If you’re a Python developer who writes more than the occasional small script, you already know the truth: threads in Python are one of the longest-running frustrations in the language.
But now, Python has finally decided it’s time to grow up.
The most recent Python release introduces one of the boldest and most far-reaching changes the language has ever seen:
official support for Free Threading.
What does that actually mean?
Python and Threads: Thirty Years of Solitude
Python is no longer a young language. Created nearly 35 years ago by Guido Van-Rossum, and with Python 3 released back in 2008, it has proven itself across countless domains and applications.
Yet in one important area, the language has long carried an implementation that is hard to justify in a mature ecosystem: thread support. CPython, the most common implementation, never truly got along with threads.

Proper thread support is difficult. It demands careful handling of race conditions, deadlocks, shared state, and memory management. When all of this is embedded in a dynamic interpreter with pervasive object sharing and a garbage collector, the challenge becomes far greater than in a tightly bounded application.
Looks Like a Thread. Feels Like a Thread. But Isn’t a Thread.
From an early stage, Python’s solution was awkward but effective: allow concurrency, forbid true parallelism. Multiple threads can exist and run concurrently, but not in parallel. Even on multi-core systems, only one thread executes Python bytecode at any given moment.
This is enforced by the GIL (the Global Interpreter Lock) which ensures that only a single thread runs Python code at a time.
So why have threads at all? For I/O-bound workloads, they still help: while one thread waits for I/O, another can run. Some computation-heavy libraries achieve true parallelism through specialized native code. But in general, anyone wanting Python to scale across CPU cores has had to rely on multiple processes.
Free-Threading Python: This Is How It Starts
In recent years, a serious effort has been underway to free Python from the GIL. The previous release introduced this capability experimentally. Python 3.14 takes the most decisive step yet: for the first time, Python officially supports running without the GIL.

This is not the default. Running without the GIL requires explicit configuration. Not out of conservatism, but because of the magnitude of the change and the costs it carries:
-
Runtime for non-parallel code may increase by 10–15%
-
Memory usage may rise by around 20%
-
Existing systems and libraries that assume the GIL may break
For these reasons, the Python steering committee has not set a target date for making GIL-less execution the default. Over the coming years, the mechanism will be tested in real systems, its impact better understood, and performance overhead reduced. Developers will have time to adapt existing code to a truly parallel model.
When will that happen?
We’ll have to wait for the decision of the (former) benevolent dictator and his council.
Until then, it will be fascinating to watch this evolve in practice.
