Python 3.14 introduces concurrent.interpreters, a standard-library module for working with multiple Python interpreters inside one process. Each interpreter has its own runtime state, which provides isolation while avoiding some of the overhead of separate operating-system processes.
This feature is useful for advanced concurrency and parallelism. Isolated interpreters can run independently and can take advantage of multiple CPU cores when combined with threads or higher-level executor APIs.
What Is a Python Interpreter?
A Python interpreter is an execution environment with its own modules, globals, and runtime state. Normal Python programs usually use one interpreter, but CPython has supported multiple interpreters internally for many years.
Python 3.14 exposes a higher-level interface for them through the standard library.
concurrent.interpreters was added in Python 3.14. Code that imports it will not run on Python 3.13 or earlier.
Import the Module
from concurrent import interpreters
The module provides APIs for creating, listing, and managing interpreter objects.
Create an Interpreter
from concurrent import interpreters
worker = interpreters.create()
print(worker)
The new interpreter is isolated from the main interpreter. It has its own imported modules and global variables.
Isolation Between Interpreters
Interpreter isolation is one of the feature's most important characteristics. Importing a module or changing a global variable in one interpreter does not automatically change the state of another interpreter.
This is different from ordinary threads, where threads normally share the same module globals and Python objects.
| Approach | Memory model | Typical isolation |
|---|---|---|
| Threads | Shared process and Python state | Low |
| Interpreters | Same process, separate interpreter state | Medium to high |
| Processes | Separate operating-system processes | High |
Run Work with InterpreterPoolExecutor
Python 3.14 also adds InterpreterPoolExecutor to concurrent.futures. It combines worker threads with isolated interpreters and offers an API similar to other executors.
from concurrent.futures import InterpreterPoolExecutor
def square(number):
return number * number
with InterpreterPoolExecutor(max_workers=2) as executor:
results = executor.map(square, [2, 3, 4, 5])
print(list(results))
Output:
[4, 9, 16, 25]
Each worker uses a separate interpreter, so CPU-bound tasks can run with stronger isolation than ordinary shared-state threading.
Data Sharing Is Explicit
Objects are not automatically shared between interpreters. Data usually needs to be copied, serialized, or transferred through supported communication mechanisms.
This can make programs easier to reason about because accidental mutation of shared Python objects is reduced, but it also means developers must plan how tasks exchange data.
Why Use Interpreters Instead of Processes?
Multiple interpreters stay inside one process. This can reduce some process-management overhead and provides a different concurrency model for applications that need isolation.
They are not a universal replacement for multiprocessing. Process isolation is still stronger, and some libraries are designed around separate processes.
Extension Module Compatibility
Third-party native extension modules may need updates to work correctly with multiple interpreters. Standard-library extension modules are designed to support the model, but external packages can vary.
Test dependencies before moving production workloads to interpreter-based concurrency.
When to Use concurrent.interpreters
- CPU-bound work that benefits from running across multiple cores.
- Applications that want stronger isolation than ordinary threads.
- Worker-style designs where tasks exchange limited, explicit data.
- Experiments with actor-like or message-oriented concurrency models.
Common Mistakes
- Expecting normal shared globals: interpreters do not behave like ordinary threads.
- Assuming every third-party extension is compatible: verify native dependencies.
- Using the feature on Python 3.13 or earlier: the public standard-library module was added in Python 3.14.
- Ignoring communication costs: isolated workers still need a strategy for moving data between execution contexts.
InterpreterPoolExecutor vs ProcessPoolExecutor
Both executors can run CPU-oriented work with isolation, but they use different boundaries. ProcessPoolExecutor starts separate processes, while InterpreterPoolExecutor keeps workers inside the same process and gives each worker an isolated interpreter.
The best choice depends on dependency compatibility, startup cost, memory use, failure isolation, and how data moves between workers. Existing multiprocessing designs do not need to be rewritten simply because interpreters are available.
Design Tasks for Isolation
Interpreter-based workers are easiest to use when tasks accept self-contained inputs and return self-contained results. Functions that depend heavily on mutable module globals or shared singleton objects require more redesign because each interpreter has its own state.
Conclusion
concurrent.interpreters makes multiple interpreters a first-class Python 3.14 feature. It offers isolation within one process and supports new approaches to parallel execution. For practical task pools, InterpreterPoolExecutor provides a familiar entry point while preserving the benefits of interpreter isolation.