Skip to content
← Back to explainers

Python explainer

Check Whether Your Python Has a JIT, Then Measure

About 4 min to read. Allow extra time to work through examples.

Ask your interpreter whether it has a JIT and whether the JIT is on. Then switch it on for a test run and judge it on your own workload.

This article uses Python. You can make it your practice mode to browse related content across the site.

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 -I or -E. Both options make Python ignore PYTHON* environment variables, PYTHON_JIT included, 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

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.

step 37 of 38

Memory, Copies and Slow Code

Up next When to Write a C or Rust Extension