A pause for the Python JIT
Benefits for LWN subscribersThe primary benefit from subscribing to LWN is helping to keep us publishing, but, beyond that, subscribers get immediate access to all site content and access to a number of extra site features. Please sign up today!
In 2024 the Python 3.13 release added an experimental just-in-time (JIT) compiler to optimize the way that CPython executes Python code. Since then, work has proceeded on the JIT, albeit perhaps less formally than some might like. In June, Python's steering council (SC) put out an announcement that no new development on the JIT land (with the exception of bug and security fixes) in Python's main branch, until it accepts a Python Enhancement Proposal (PEP) that would make the case for the JIT as a supported part of CPython. That has led to the creation of PEP 836 ("JIT Go Brrr: The Path to a Supported JIT Compiler for CPython"), which is currently under discussion. As it stands, it seems likely that work on JIT will continue, but when that will happen is less certain.
PEP it up
The Python community uses PEPs to propose new features, serve as a focus for discussion, collect community input, and to serve as a record of decisions. There are three types of PEP: standards track, process, and informational. The standards-track PEPs are for major new features or changes for Python, where the community needs to discuss and decide before (say) removing the global interpreter lock (GIL). Process PEPs are similar but are related to Python governance and development practices around the code base. If accepted by the steering council, these become binding, and (if applicable) work is to commence on implementing the proposal.
Informational PEPs are, as the name suggests, to provide guidelines or other information to the Python community; these PEPs do not represent formal consensus and are non-binding. As such, they generally would not be considered suitable as a basis of major new features landing in CPython's main branch, but work has proceeded on Python's JIT on the basis of PEP 744 ("JIT Compilation"), which is an informational PEP.
That PEP was only introduced several months after CPython core developer Brandt Bucher had already merged the pull request (PR) to add a JIT compiler in January 2024, ahead of the Python 3.13 release.
Thomas Wouters, a steering council member who was serving as the release manager for Python 3.13, stepped in a few days later and asked why the feature had been submitted before a PEP had been submitted or accepted. Ultimately, Wouters persuaded Bucher that a PEP was warranted, and he agreed to start work on one. PEP 744 was announced in April 2024. LWN covered some of that discussion at the time, and Bucher's PyCon US 2024 and PyCon US 2025 talks on the JIT compiler.
There is a "JIT Planning for 3.15 and 3.16" tracking issue on GitHub, created in September 2025, to track goals and work the JIT developers believe was needed to enable the JIT by default by the Python 3.16 release in 2027. But the work was continuing without a standards-track PEP that indicated larger community agreement and awareness.
Hit pause
In its announcement, the council took pains to note that it was not
criticizing the JIT effort or those behind the work: "This has been hard, deeply
technical work that has been done with great care, and the recent performance
improvements are real and encouraging.
" However, because the project had
been underway and undergone a few re-architectures, the council decided, "now is a good
time to re-evaluate the JIT's informal status in the project
".
The council set a window of six months for a new PEP to be submitted and resolved; it said that the JIT code is to be removed from the main branch and any development would need to continue outside that repository if a PEP is not accepted within that time frame.
We know this asks something of the people who have invested years in this work, and we don't take that lightly. We see this not as winding the project down but as giving it, and the community, the clarity and the explicit commitment that a change of this magnitude to CPython's runtime deserves.
The council asked that the PEP address several points; first, it should cover
"how the JIT will be sustained and maintained over the long term
". It
would also need to explain how the JIT would keep compatibility with other
CPython features and tooling, if the JIT would be compatible (or incompatible)
with third-party JIT implementations, as well as whether the JIT architecture is
considered stable or would change further. The council also asked for "clear,
measurable success metrics and timelines
"
Why now?
Naturally, there were questions about the announcement. Antoine Pitrou said
that the council's decision seemed reasonable but wondered if there was "any
further background
" that prompted it. Wouters replied
that there had not been "a single triggering request
" for the PEP, but
the announcement was released after the 3.15 beta
to indicate the council was "okay with the status quo for 3.15
". The JIT
is still included as an experimental feature in 3.15 and includes
major updates such as a new tracing frontend, a basic form of register
allocation, and several optimizations.
Peter Bierma asked
for clarification on the council's deadline: he thought that it was unlikely
that it would be possible to meet the deadline when some PEPs, such as PEP 703 ("Making the Global
Interpreter Lock Optional in CPython"), have taken five months to be accepted by
the council after being formally submitted. Pablo Galindo Salgado indicated
that the council would be flexible if the PEP was stuck in discussion or in its
queue for consideration. Wouters added
that the council was trying to drive a "clear decision from the
community
", because the JIT is a significant change that deserves
serious attention. "That doesn't necessarily mean the JIT immediately gets
ripped out when that six month deadline is hit – we're not unreasonable – but we
do want this to be taken seriously.
"
The decision to stop development until a PEP is accepted, Mark Shannon said,
put JIT contributors in an awkward position. He asked if work to improve the JIT
could continue for a month or two "to give time for the PEP to be discussed
properly
". Council member and JIT contributor Savannah Ostrowski replied
that she didn't think that the grace period Shannon asked for was
necessary. "We understand the work is ongoing and the current state isn't the
final state (as is true of most things in open source).
"
Shannon clarified
that he was worried about losing momentum and contributors. "There is other
work I personally can do, on memory allocation and such, but PRs will bitrot and
other contributors may lose interest.
" Jiahao Li, who had made contributions
to the JIT, asked
if there were "clear and minor optimizations
" that might be acceptable
to continue. Alyssa Coghlan suggested
that a grace period might be warranted for any in-flight pull requests,
especially those from new contributors. "Saying 'no new PRs on this topic
until a PEP is approved' is one thing, shifting the goal posts for already in
progress changes is something else
".
Council member Donghee Na was
not convinced that exceptions were a good idea. Even if the policy was
adjusted to allow PRs that were already open, "I still think our main focus
should be on writing the PEP. Involving those contributors in the PEP process
would also be a good experience for them as part of CPython's development
process.
"
On June 8, Diego Russo, a CPython core developer and JIT contributor, replied
that he had discussed next steps with Shannon and they were working on a
draft. The "JIT Go Brrr" draft PEP was announced
on July 3 by Ken Jin. The PEP name may be a nod to the "doesjitgobrrr" web site that tracks
the performance of the JIT versus the standard CPython interpreter. "Go Brrr" is
a reference to a
meme about the US Federal reserve printing money with a caption including
the phrase "money printer go brrr
".
New PEP
The PEP, authored by Bucher, Jin, and Ostrowski, lays out the current status for the JIT, as well providing a two-and-a-half year timeline with the milestones and goals for the JIT to become a non-experimental feature. The PEP leaves the decision of whether to enable the JIT by default to the Python release manager, rather than setting a condition for that to occur. Currently the JIT is included in the Python binaries for Windows and macOS, but it is disabled by default; some Linux distributions (the PEP cites Fedora and Gentoo) also include the JIT but leave it disabled by default. Interested users can turn on the JIT by setting PYTHON_JIT=1 as an environment variable.
The first year would be focused on developer-experience improvements, making
the JIT compatible with free-threaded (no-GIL) Python, avoiding regressions,
as well as adding further testing for native Python profilers and
debuggers. The second year target, which is scheduled for the first beta of
Python 3.17, is "at least 20% performance geometric mean
improvement
" measured by the Python Performance Benchmark
Suite (pyperformance) when using the JIT and free-threaded Python versus
free-threaded Python alone.
The last milestone, to be completed by the first 3.17 release candidate, is compatibility review: running the test suites of the top PyPI packages (exactly how many is not specified) to assess JIT compatibility with existing code.
The PEP also calls for adding support for multiple versions of the LLVM compiler; currently, building Python with the JIT enabled requires a specific version of LLVM. Building the JIT for Python 3.14 requires LLVM 19 and Python 3.15 requires LLVM 21; both versions of LLVM have reached end of life. LLVM is required because it is used to create templates called "stencils" (example) for the JIT.
There is a separate standards-track proposal, PEP 774 ("Removing the LLVM requirement for JIT builds"), that would remove the LLVM requirement entirely, but it has not yet been accepted. The current situation is a problem for Linux distributors that support versions of Python in long-term-support releases, as discussed in this thread on the Python forum.
The PEP also proposes some
changes to the JIT's frontend infrastructure. Specifically, it calls for
replacing the current trace-recording frontend of the JIT compiler with a
method-based frontend to make the JIT easier to maintain and make it "more
traditional and teachable
", which is not the case now. "The current
tracing frontend can produce head-scratching results even for very simple
benchmarking programs.
" The trace-recording frontend is explained in detail
in a blog
post by Jin from May 2026.
Discussion
Cesare Di Mauro noted that the PEP mentioned that the JIT might use more memory, but it made no clear statement about the goals for memory consumption. Jin said that was a good point and planned to take it up with the co-authors of the PEP to include an upper limit on additional memory use.
Wouters, who clarified he was speaking as himself and not as a council
member, thought
that the PEP really felt like it was two PEPs: one that was showing the criteria
for acceptance, and one that explained how the proposers expected to meet the
criteria. "Fundamentally, the discussion about the minimum expectations for a
supported JIT is distinct from how to get there, especially as we have different
proposals for how to get there.
" He also questioned the firm timeline that
was included in the PEP. "It's just not how development works in an
open-source project, especially one that cares about backward
compatibility.
"
He wanted to see an explicit discussion in the PEP about the JIT's startup
time, warmup time, and memory overhead. These, he said, did not need to be
"particularly strict numbers
", but if those metrics were not tracked, it
would not be possible to understand the cost paid when the JIT is enabled.
The other requirement he voiced was about maintainability of the JIT and its support
among the core CPython team members. "We should focus on making whatever
design we end up with understandable, and understood by the
Core team. We need to make sure enough people work on it and spend time with
it
". Shannon agreed
that "this seems like two PEPs
", and implementation details in the current
PEP seemed out of place.
Bucher replied
the PEP was "providing what the SC asked for
" and that the
authors had put a lot of effort into creating a cohesive PEP. "A separate PEP
seems like it makes the process more complicated and opaque, not less. Here, we
have a way to present a complete story
". He also thought that the current
JIT "can be understood and is accessible to other members [of the community]
outside the core team
". Ostrowski added
that it would make her uncomfortable to have the PEP include goals for the JIT
without "everything we've thought through alongside it
". Goals without
plans, she said, aren't really goals at all.
Wouters responded
that he understood where Bucher was coming from now. He added that his
understanding of the council's request, though, was meant to be for the current
JIT and not a future one. "If the plans in this PEP for the future JIT were
rejected, that still leaves the fate of the current JIT unclear.
" Jin replied
that the PEP was not proposing a new or future JIT, though it might seem that
way for those unfamiliar with the recent JIT progress. "The design we
described might seem like a radical change, but most of it is already in the
current CPython main branch! Again, the only change is growing support for
methods.
"
CinderX is an
extension for improving the performance of the Python runtime that includes a
JIT. Kevin Newton, one of the contributors to CinderX, also
thought the proposal should be two PEPs. More importantly, he believed that
the PEP "very much understates the sizeable difference between a tracing JIT
and a method-at-a-time JIT
" and was glossing over some important details. He
said that CinderX had already run into some of the problems that the JIT
developers would face in replacing the current frontend. He also worried about
the focus on simplicity:
JITs and dynamic language runtimes are some of the more complex pieces of software out there. I promise I'm sympathetic to having too little energy and contributors, and it makes sense that you would want the things you mention. But I worry that eschewing complexity in favor of making a JIT compiler "fit" in someone's head ultimately results in a JIT compiler not worth having.
Jin said
that he appreciated Newton's expertise with CinderX and other JITs, but he
disagreed that it would require a lot of changes to support methods for the
current state of the JIT in CPython. The developers had not yet implemented
"the usual complex things
" yet, which meant that it would not be highly
complex to switch between the two at this time. He also disagreed that there was
a mandate to produce two PEPs from the steering council, and wanted to avoid
putting the burden of doing so on the JIT developers.
The "this should be two PEPs" theme continued with a lengthy comment from CPython core developer Jeremy Hylton. He called for separate PEPs describing the design of the JIT, how various parts of the interpreter runtime interact, as well as one that would describe metrics, timelines, and maintenance plans.
Eric Snow, also a CPython core developer, pushed
back against the "ongoing pressure
" and expressed support for the
JIT. He thought documenting the design and addressing concerns was worth doing
but disagreed with blocking further development in the main
repository. There was a risk, he cautioned, that making extended demands that
seemed like busy work would drive away contributors and turn Python into a
project "in which mostly only enterprise teams participate
".
Russo said
he had worked on the JIT almost since its inception and felt the work should
continue; he did, however, support splitting the document into two PEPs. He
thought that trying to cover everything in one PEP broadened the discussion and
made it harder to reach consensus. "The Steering Council's requests can be
addressed through multiple focused PEPs rather than trying to fit everything
into one document. Once we have an agreed baseline, follow-up PEPs can evolve
individual parts of the JIT independently.
"
Status
The discussion seems to have lost momentum, without any official statement from the council about whether it also feels there should be multiple PEPs or if it is satisfied with the current draft. There has been no commitment from any of the PEP's authors to split up the current document or produce new PEPs.
On August 17, Wouters posted
a summary of the council's meeting from August 6. The summary noted that the council
"had office hours
" with the authors "discussing the state of the PEP
and whether it answered the questions the SC asked in its request for a
PEP
", but did not elaborate on the results of that discussion. PEP 836
was listed as an agenda item for the council's next meeting, but minutes from
that meeting have not yet been posted.
For now, the development of the JIT seems to be largely on hold. No one seems to be voicing direct opposition to the JIT work, just a fair number of people who are asking for more information and debating the details.