A colleague says the new Python JIT will make your service faster. First
find out whether your Python has one. A just-in-time compiler, or JIT,
turns Python code that runs often into machine code while the program
runs. Whether an interpreter includes one depends on who built it, not
only on its version. Python 3.14 added sys._jit so you can ask:
import sys
version = sys.version.split()[0]
jit = getattr(sys, "_jit", None)
if jit is None:
print(version, "has no sys._jit")
else:
print(version, "available:", jit.is_available(), "enabled:", jit.is_enabled())
Three Pythons on one laptop gave these answers:
| Interpreter | Output |
|---|---|
| 3.12.13, installed by uv | has no sys._jit |
| 3.14.8, installed by uv | available: True enabled: False |
the same 3.14.8, with PYTHON_JIT=1 set |
available: True enabled: True |
| 3.15.0, installed by Homebrew | available: False enabled: False |
is_available() tells you whether this executable includes the JIT.
is_enabled() tells you whether the JIT is on in this process. Python 3.12
has no JIT. Python 3.13 can have one, if whoever built it asked for it, but
it has no sys._jit to ask. The leading _ marks _jit as an
implementation detail that can change, which is why the snippet uses
getattr with a default. There is also is_active(), which is meant for
debugging the JIT itself, so leave it out of your own code.
Turn it on and compare
If is_available() returns True, the PYTHON_JIT environment variable
turns the JIT on or off when Python starts. Run your own benchmark both
ways:
PYTHON_JIT=0 python3.14 benchmark.py
PYTHON_JIT=1 python3.14 benchmark.py
benchmark.py stands for your own workload, timed as the earlier timing
articles in this track describe. Have it print the snippet above too, so
each result records the JIT state it ran with. The variable cannot add a
JIT to a Python built without one. On the Homebrew 3.15.0 above,
PYTHON_JIT=1 changed nothing.
Common mistakes
- Running with
-Ior-E. Both options make Python ignorePYTHON*environment variables,PYTHON_JITincluded, so both runs use the default. - Timing only a short command. The JIT compiles code after it has run many times, so a script that ends within a second may stop before the JIT helps. Time startup and long-running work separately.
- Comparing on different machines or inputs. Use the same executable, dependencies, inputs and machine for both settings. Alternate the runs and repeat them.
Check your understanding With the JIT on, a loop benchmark takes 10% less time. Should you cut your service's capacity by 10%? Show answer Hide answer
No. Measure the service itself. Suppose Python code takes 15 milliseconds of a 100-millisecond request, and the rest is waiting for a database. Cutting those 15 milliseconds by 10% saves 1.5 milliseconds, so the request takes 1.5% less time, not 10%. Check throughput, latency and memory under real load before you change capacity.
What the release notes report
Python 3.13 added the JIT as an experimental option for people who build Python themselves. In 3.14, the official macOS and Windows installers include it, switched off by default, and the free-threaded build does not support it. The Python 3.14 release notes report results from a 10% slowdown to a 20% speedup, depending on the workload. They call the JIT experimental and do not recommend it for production.
Python 3.15.0 came out on 9 October 2026. Its release notes report a 7 to 8% geometric-mean speedup from the JIT on the pyperformance benchmarks, measured on x86-64 Linux. The JIT is still experimental. That figure averages many benchmarks, and your program can gain more or less. Read the notes for the exact release you will install, and measure your own workload.