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.