For decades, CPython's Global Interpreter Lock (GIL) meant only one thread could execute Python code at a time. Threads helped with waiting on I/O, but CPU-heavy work needed multiprocessing or native extensions to use multiple cores.

Python 3.14 is the first release where the free-threaded build, Python without the GIL, is officially supported. It is still a separate build rather than the default, but it is now a real option.

What changes

In the free-threaded build, multiple threads can run Python code truly in parallel on different CPU cores.

python
from concurrent.futures import ThreadPoolExecutor

def cpu_work(n):
    return sum(i * i for i in range(n))

with ThreadPoolExecutor(max_workers=4) as pool:
    results = list(pool.map(cpu_work, [5_000_000] * 4))

On the standard build this runs roughly one task at a time. On the free-threaded build, the four tasks can run on four cores.

When it helps

  • CPU-bound work in threads: parsing, data transformation, simulations, image processing in pure Python.
  • Workloads that used multiprocessing only to get parallelism, and paid for it with process start-up and data copying.
  • Servers mixing I/O and CPU work in threads.

Reported speed-ups for multi-threaded CPU-bound code are substantial on multi-core machines, though far from linear.

When it does not

  • Single-threaded code runs somewhat slower on the free-threaded build, because of the extra work needed for thread safety.
  • I/O-bound code was already fine with threads or asyncio.
  • NumPy-style workloads that already release the GIL inside native code may see little change.

Compatibility: check your extensions

C extensions must be built for the free-threaded ABI. Many popular packages provide compatible wheels, but coverage is uneven. If an extension is not marked as free-threading safe, Python may re-enable the GIL at import time and print a warning.

Try it with uv

bash
uv venv --python 3.14t
uv run python -c "import sys; print('GIL enabled:', sys._is_gil_enabled())"

The t suffix selects the free-threaded build.

Thread safety is now your problem

The GIL hid many race conditions. Without it, shared mutable state needs real protection:

python
import threading
lock = threading.Lock()
counter = 0

def increment():
    global counter
    with lock:
        counter += 1

Prefer designs that avoid shared state: pass data to workers and collect results, or use queues.

How to evaluate it

  1. Benchmark your real workload on both builds.
  2. Run your test suite on the free-threaded build, ideally under stress with many threads.
  3. Check that every native dependency supports it.

Key takeaways

  • Python 3.14 officially supports a free-threaded build without the GIL.
  • It speeds up CPU-bound multi-threaded code but slows single-threaded code slightly.
  • Native extensions must support it, or the GIL may be re-enabled.
  • Benchmark and test carefully, and protect shared state with locks.