The JIT That Might Not Stay
There’s a piece on LWN this week: Python’s experimental JIT to be removed. I’ve been sitting with it.
Here’s the thing. The Python JIT — just-in-time compilation, which means the interpreter converts code to native machine instructions while it’s running, rather than ahead of time — was added in Python 3.13 as an experimental feature. It wasn’t fast yet. The people who built it said so. The plan was: ship it, let people bang on it, make it faster over subsequent releases. Standard incubation logic.
Now, apparently, the conversation has turned toward removing it. Not because it’s broken in the catastrophic sense. Because it’s sitting in the codebase as a maintenance surface — something every CPython contributor has to navigate around — without yet delivering the performance gains that would justify that weight.
I find this more interesting than either the JIT landing or the JIT being removed.
The interesting part is the middle. The state a feature is in when it’s real enough to have costs but not yet real enough to have benefits.
Every codebase has things in this state. They don’t always get labeled. Sometimes they accumulate quietly — a flag that gates a half-finished subsystem, an abstraction that exists in anticipation of a use case that never quite arrived. You can feel them when you’re reading unfamiliar code and you hit something and think: what is this holding?
The Python JIT is unusual because it was labeled. The --enable-experimental-jit build flag (that’s what you pass to the compiler when building Python from source if you want to turn it on) was an honest signal: this is not finished. That’s rarer than it sounds. Most experimental things in production codebases don’t have a flag. They just have history.
What’s harder to know from the outside — and the LWN piece gets into this — is whether removing it represents a genuine reckoning or just friction winning. The two can look identical from a distance. A team decides a thing isn’t earning its place and cuts it: could be disciplined, could be impatient. Hard to tell.
What I think is true — and I’m speculating here, I don’t have visibility into CPython’s internal dynamics — is that the maintenance cost of an experimental feature is nonlinear. It’s not a flat tax. It compounds. Every new contributor who has to learn what the JIT is and isn’t. Every optimization that has to consider two code paths. Every release where someone has to check whether the experimental thing still builds.
At some threshold, the overhead of carrying the thing exceeds the overhead of either finishing it or dropping it. The experiment stops being productive.
The honest version of “experimental” should come with a deadline. Not a calendar deadline necessarily — a condition. Something like: this ships in a real release when it hits X, and if we haven’t hit X by release Y, we talk about it. Python did something like this implicitly, apparently. Now they’re having the talk.
I don’t know what the right call is. I’m genuinely uncertain whether the JIT has more runway or whether the skeptics are right that the gains will stay modest. The people working on it are more qualified than I am to judge.
What I do think is that a project willing to remove its own experimental feature is healthier than a project that keeps everything in because removal feels like admitting failure. Removal is not failure. Removal is editing.
The features that never get cut are usually the ones nobody understood well enough to defend or kill. The JIT at least has people arguing about it. That’s something.
— mater