Python 3.15’s JIT Compiler: How Much Faster Is It Really?
What actually changed in Python 3.15’s experimental JIT, the real speedup numbers, and whether it’s worth enabling yet
The Python 3.15 overview mentions the JIT speedup in passing. This is the longer version: what actually changed under the hood, and whether “experimental” still means “not for you.”
A quick recap: what the JIT does
Python’s JIT, introduced experimentally in 3.13, compiles frequently-executed bytecode into machine code at runtime instead of interpreting it every time — the same general idea as JIT compilers in JavaScript engines or the JVM, adapted to CPython’s specific execution model. It’s opt-in, built via a separate compile flag, and off by default.
What’s new in 3.15’s JIT specifically
3.15 adds a new tracing frontend and basic register allocation to the JIT pipeline. In plain terms: the tracing frontend does a better job identifying which code paths are actually hot (worth compiling) versus which ones run once and aren’t worth the compilation overhead, and register allocation — deciding which values live in CPU registers versus memory — is one of the most impactful optimizations any compiler can make, because register access is dramatically faster than memory access. Earlier JIT versions did less of this work, leaving performance on the table even for code that did get compiled.
The actual numbers
Core developers report roughly 8-9% geometric-mean speedup on x86-64 Linux and 12-13% on AArch64 macOS compared to the standard interpreter, measured across the pyperformance benchmark suite. Geometric mean matters here — it’s not “your specific script gets 9% faster,” it’s the aggregate across a benchmark suite with wildly different workload shapes. Tight numerical loops and hot function calls benefit more; I/O-bound code (the majority of real-world web apps and scripts) sees close to nothing, because the bottleneck was never CPU-bound interpretation in the first place.
Should you enable it
For most applications, no — not yet, and not because it’s unstable so much as because it doesn’t help. If your workload is I/O-bound (most web backends, most scripts that spend their time waiting on a network or database), the JIT has nothing to compile that matters. It’s worth testing specifically if you have CPU-bound Python code — numerical processing, tight loops, algorithmic work that isn’t already handled by NumPy or a compiled extension — where interpreter overhead is a measurable part of your runtime.
How to test it
Building CPython with --enable-experimental-jit (or using a pre-built distribution that ships it enabled) lets you compare against a standard build directly on your own workload — the pyperformance numbers above are a general signal, not a guarantee for your specific code. If you do test it, benchmark your actual bottleneck, not a synthetic loop; the JIT’s gains are real but workload-dependent enough that generic numbers won’t tell you what you’ll actually see.
Real Python’s JIT compiler preview goes deeper into the implementation details if you want the full technical picture beyond this summary.
Frequently Asked Questions
How much faster is Python 3.15’s JIT?
Core developers report roughly 8-9% geometric-mean speedup on x86-64 Linux and 12-13% on AArch64 macOS versus the standard interpreter, measured across the pyperformance benchmark suite — not a per-workload guarantee.
What’s new in Python 3.15’s JIT specifically?
A new tracing frontend that better identifies which code paths are actually worth compiling, plus basic register allocation — deciding which values live in CPU registers versus memory, one of the most impactful optimizations a compiler can make.
Should you enable Python 3.15’s JIT?
For most applications, not yet — if your workload is I/O-bound, which most web backends are, the JIT has nothing to compile that matters. It’s worth testing specifically for CPU-bound work like numerical processing or tight loops.
Is Python’s JIT enabled by default?
No, it’s opt-in and experimental, built via a separate compile flag (—enable-experimental-jit). It’s been experimental since its introduction in Python 3.13.