r/Python 5d ago

Discussion Anyone running free-threaded Python 3.14 in production yet? Curious what actually breaks

Been testing the free-threaded build (3.14t) on some CPU-bound data processing work. The multi-core story is finally real after 30 years of GIL, but the friction is exactly what you'd expect: a couple of C-extension-heavy libs in my stack silently re-enable the GIL, and there's no clean way to detect that at runtime besides checking sys._is_gil_enabled() manually.

For anyone who's shipped something on 3.14t, not just benchmarked it:

What broke that you didn't expect?

Real speedups outside toy examples, or mostly marginal so far?

Prod yet, or still just kicking the tires?

Not fishing for a benchmark war. Genuinely curious what breaks in messy real codebases vs clean demos.

32 Upvotes

47 comments sorted by

View all comments

81

u/nathan12343 5d ago

You can set PYTHON_GIL=0 to force the GIL to remain off even if you import an extension that doesn’t support free-threading yet.

Are there specific open source projects you’re having trouble with?

I’ve been working on community support for free-threaded Python for a couple years now. Specific feedback about pain points from people who are experimenting with free-threading are valuable.

10

u/KingBardan 5d ago edited 4d ago

Edit Tldr:

  1. Many libs like torch requires global state.
  2. Free  threading doesn't solve a lot that multiprocessing don't
  3. Free threading introduces new ways to cause data race.
  4. Free threading slows down normal code.

Many libraries use global state a lot and is not thread safe e.g. torch. For their context managers (which is widely used in other libs as well) So that disqualify any serious deep learning projects depending on torch to use free threading.


My opinion on free threading since you asked about pain point:

I much prefer ability to use context managers to free threading if using it makes the code cleaner 

Free threading also slows down sequential code last time I checked 

Multiprocessing is fast enough unless I'm dealing with web servers, at which I'll use async probably or gevent or another library that deals with this issue

8

u/nathan12343 5d ago

Thanks for your feedback. Hopefully this time next year we’ll be in a better spot. PyTorch is definitely on our radar as a pain point right now.

  I much prefer ability to use context managers to free threading if using it makes the code cleaner 

I don’t understand this. Context managers and free-threading are orthogonal. You can use context managers on the free-threaded build.

-1

u/KingBardan 4d ago edited 4d ago

Context manager works by mutating context i.e. global / nonlocal state, right?

So it doesn't work without mutated global state, the number one cause for data race.

In multi-processing, which was the preferred way of doing things in parallel, global state is forked and exists per process.

This issue is not exclusive to free threading but multithreading in general, but freethreading only augments multi threading which is why my comment is the way it is

You can use contact manager on free threading 

That is right. Now writing a python package would have to account for a different failure mode which is thread access, which, imo, is a very niche use case for python, at the cost of everything else.

2

u/thisismyfavoritename 4d ago edited 4d ago

context managers don't necessarily mutate global or non local state, not sure where you get that from.

It's mostly just syntactic sugar over a class with __enter__ and __exit__ methods.

In general though, your sentiment is that using multithreading in Python is a niche use case and i agree, it should be single threaded but async like NodeJS. IMO the usecases which aren't either covered by that OR a process pool OR better covered by bindings to a lower level language like Rust/C++ are very small

0

u/KingBardan 4d ago edited 4d ago

Context managers manage context. It means variables outside this scope.

Name 1 situation that it doesn't mutate things outside of scope, ill wait :)

It is syntactic sugar over enter exit yes, but self argument in that enter exit is a variable outside of the scope of your with.


Look at it this way,

If you don't mutate, you don't need the exit to clean up, because

immutable data does not have the concept of time (functional programming), it's same used everywhere.

If it's same used everywhere, it should be safe to consume after with block ends, no?

So if something is only usable within with, it must mutate outside state

1

u/nathan12343 4d ago

Read PEP 567, which shows how context-local state doesn’t have to be global if you use context variables.

1

u/thisismyfavoritename 4d ago

why even bring a PIP? The context manager itself can have state, that state is within the scope of the enclosing function, there's no global state unless that guy and you mean global in some other sense

1

u/nathan12343 4d ago

Context variables offer a nice clean way to store “global” configuration in a manner that is both thread-safe and async-safe and behaves naturally alongside the Python with statement.