Python 3.13 without GIL: Real-World Threading Finally Works
Tested Python 3.13's optional GIL. Shared results showing real multithreading gains, install steps, and when it outperforms multiprocessing.
Python 3.13 introduces the most significant concurrency improvement in CPython's history: the ability to disable the Global Interpreter Lock (GIL). Thanks to PEP 703, Python can now execute native threads in parallel — not just in theory, but in practice.
This post shares hands-on results after compiling Python 3.13 with --disable-gil
, running CPU-heavy multithreading tasks, and toggling the GIL on and off at runtime. The verdict? Python threads finally scale — and in some cases, outperform multiprocessing — with no code changes.
How to Install Python 3.13 Without the GIL¶
To run GIL-free Python, you’ll need to compile it from source.
Requirements (Ubuntu)¶
Build and Install¶
Add to your shell path or run directly:
Benchmarking: Threads vs Processes vs Serial Execution¶
To truly evaluate the GIL, I wrote the following script to simulate a real CPU workload: calculating factorials using threads, processes, and single-threaded code.
Results: GIL OFF vs ON¶
GIL Disabled¶
GIL Enabled¶
Interpretation¶
Mode | GIL Enabled | GIL Disabled | Performance Impact |
---|---|---|---|
Single-threaded | 4.83s | 4.80s | ~identical |
Multi-threaded | 4.57s | 2.32s | >2× faster without GIL |
Multi-processing | 2.51s | 2.65s | Comparable |
Observations:¶
- Without the GIL, Python threads scale across cores — no workarounds, no hacks.
- GIL-free threading outperformed multiprocessing, without the complexity of IPC.
- The single-thread baseline remains unaffected — the GIL toggle doesn’t impact serial code paths.
Why This Matters¶
Historically, Python's GIL has made multithreading useless for CPU-bound code. This forced developers to:
- Use
multiprocessing
, which incurs overhead - Offload to C or Cython
- Rewrite in other languages (Go, Rust, C++)
With Python 3.13’s --disable-gil
build, those workarounds are no longer necessary. Multithreaded CPU-bound Python code is finally viable.
Considerations¶
- GIL-disabled builds are not ABI compatible — C extensions must be rebuilt.
- Some overhead exists in managing locks around containers, especially in pure Python workloads.
- This is still marked as experimental in Python 3.13. Future versions will likely optimize further.
Final Thoughts¶
Python 3.13 with --disable-gil
is not just a technical milestone — it's a practical, user-facing shift in what Python can do. For the first time, multithreaded Python isn't a theoretical dream. It's fast, predictable, and works without changing your code.
If your workloads involve concurrency, especially CPU-heavy tasks, this feature is worth adopting early.
FAQs
What is the significance of Python 3.13’s --disable-gil feature?
Python 3.13 introduces a GIL-free build option via --disable-gil
, allowing native threads to execute in true parallel. This eliminates the long-standing Global Interpreter Lock bottleneck for CPU-bound multithreaded workloads.
How does performance compare with and without the GIL?
When the GIL is disabled, multithreaded CPU-bound code scales across cores, outperforming both multiprocessing (due to lower overhead) and traditional GIL-constrained threads. Serial code performance remains unaffected.
Do I need to change my code to benefit from GIL-free Python?
No. Python 3.13’s GIL-free build works without any code changes. Existing multithreaded programs can benefit immediately if the GIL is disabled at compile time and runtime.
Are there any compatibility concerns with --disable-gil?
Yes. GIL-disabled builds are not ABI-compatible with standard CPython builds. C extensions must be recompiled, and some thread-safety assumptions in third-party packages may need to be reviewed.