PEP: 779
Title: Criteria for supported status for free-threaded Python
Author: Thomas Wouters <thomas@python.org>,
        Matt Page <mpage at python.org>,
        Sam Gross <colesbury at gmail.com>
Discussions-To: https://discuss.python.org/t/84319
Status: Final
Type: Standards Track
Created: 13-Mar-2025
Python-Version: 3.14
Post-History: `13-Mar-2025 <https://discuss.python.org/t/84319>`__
Resolution: `16-Jun-2025 <https://discuss.python.org/t/84319/123>`__

.. note::
   The Steering Council accepts PEP 779 with a non-exhaustive list of
   requirements to be addressed during phase II. See the `acceptance
   <https://discuss.python.org/t/84319/123>`__ for details.

Abstract
========

The acceptance of :pep:`703` (Making the Global Interpreter Lock Optional in
CPython), as `announced by the Steering Council
<https://discuss.python.org/t/pep-703-making-the-global-interpreter-lock-optional-in-cpython-acceptance/37075>`__,
describes three phases of development for the work to remove the Global
Interpreter Lock. Phase I started early in the development of Python 3.13,
and includes making the free-threaded (GIL-less) Python build available but
explicitly *experimental*. Phase II would make the free-threaded build
officially supported but still optional, and phase III would make the
free-threaded build the default. Because of the number of unknowns at the
time, the criteria for moving to the next phase were left deliberately vague
at the time. This PEP establishes clear expectations and requirements for
moving to Phase II, making the free-threaded Python build officially
supported.

.. note::

   Eagle-eyed readers may have noticed an overlap in authors of this PEP and
   the Steering Council at the time of PEP 703 acceptance. The SC makeup has
   since changed, but just to make it explicit: this PEP as proposed, while
   based on criteria set forth by the SC, does not come from the Steering
   Council itself.

Motivation
==========

Whether to move forward with :pep:`703` (as well as ultimately making it the
default) is a question of whether the costs outweigh the benefits. Making
free-threaded Python an officially supported build is important to signal
that we're now at a stage where the design is finalised, the APIs are usable
and stable, and we're satisfied the performance and complexity cost is not
prohibitive.

Moving to the "officially supported" stage is an important step towards
making free-threaded Python the default build, and eventually the only one.
Before we can decide we're ready to make it the default, we need a much
better picture of the costs and the benefits, and we can only get there if
more of the Python ecosystem starts supporting free-threaded Python. We
currently have enough packages and tools supporting :pep:`703` that it's
clear we're on the right path, but not enough to make the final decision. In
addition to giving the Python community time to make the changes necessary
to support free-threaded Python, we expect to use phase II to show clear
benefits in real-world applications, as well as clearly define the cost in
terms of performance, support burden, and ecosystem complexity.

Rationale
=========

In order for PEP 703 to be acceptable it should be desirable, stable,
maintainable, performant (in CPU and memory), and ideally it should have
Stable ABI so the same wheels can be used for free-threaded and with-GIL
builds.

- Desirability: from various experiments it's very clear free-threaded
  Python has tremendous potential benefit. It's not a simple drop-in
  solution -- some code will have to be redesigned to make the most of the
  new capability, as well as avoid performance pitfalls -- but it can
  achieve higher performance, significantly lower latency and new
  thread-based functionality when embraced.

- Stability: the majority of the new API design is in 3.13, and is being
  successfully used to support free-threaded Python in a number of
  third-party packages (see for example
  https://py-free-threading.github.io/tracking/). There's been some more
  development in 3.14 to add more convenience functions, and to replace
  APIs that previously relied on the GIL for thread-safety, but we have not
  had to break the 3.13 APIs for free-threaded Python.

- Maintainability: the majority of :pep:`703`'s design is relatively
  simple, with most complexity hidden away behind CPython's existing C
  APIs. The implementation details of, for example, lockless list and dict
  APIs, `which rely on QSBR <https://github.com/python/cpython/issues/115103>`_,
  and `deadlock-avoiding critical sections <https://github.com/python/cpython/issues/115103>`_,
  may be complex and difficult to get right, but gives us easy to use APIs
  without too many pitfalls. Making more of CPython free-threading-safe is
  a relatively simple process, although we do probably need more
  documentation on the basic guarantees the new APIs provide
  (https://github.com/python/cpython/issues/128642).

- Performance: the performance penalty on linear performance, comparing a
  free-threaded build against a with-GIL build, as measured by the
  pyperformance benchmarks (for example as run by `Microsoft's Faster
  CPython team <https://github.com/faster-cpython/benchmarking-public/>`_,
  or `Meta's Python Runtime team <https://github.com/facebookexperimental/free-threading-benchmarking>`_),
  is currently around 10% (except on macOS, where it's more like 3%). We
  have a few more PRs in flight that should get us comfortably below 10% on
  Linux and Windows.

- Memory use. Exact numbers vary because of the different gc module
  implementation, but free-threaded Python currently sees about 15-20%
  higher memory use (geometric mean, as measured by pyperformance). We
  haven't spent a lot of time trying to lower this yet, so we may be able to
  push this down further. Realistically, though, higher memory use is the
  cost of having efficient, safe free-threading, and we are unlikely to get
  this very close to the with-GIL build's memory use without significant
  performance cost.

- Stable ABI. Stable ABI support is mentioned by the Steering Council as a
  potential requirement for phase II. While having Stable ABI support would
  make third-party package distribution a lot easier, there's a bit of a
  chicken and egg problem: we don't know if the Stable ABI is good enough
  if we don't have packages that support free-threaded Python using it, and
  we can't remove things from the Stable ABI if we discover problems with
  them. Given that phase II is meant to give the community time to adopt
  free-threaded Python and provide feedback on APIs and ABIs, we're not
  sure how strong a requirement the Stable ABI should be for phase II.

Specification
=============

Specific criteria for making free-threaded Python officially supported
(phase II), as we propose them:

- Acceptable performance. The Steering Council mentioned they expected
  free-threaded Python to be around 10-15% slower, although this was not a
  hard target. We are currently around 10% and don't expect it to get
  slower, but for phase II (not the default flip), we propose 15% as a hard performance target.

- Acceptable memory use. This was not mentioned by the Steering Council and
  hasn't seen much discussion. We propose a target of 20% (geometric mean,
  as measured by pyperformance) for phase II. For phase III, we'll need
  input from the community as to where the trade-off between memory and CPU
  performance should end up.

- Proven, stable APIs. This is a difficult thing to measure, but we have
  seen significant adoption of free-threaded Python with the existing APIs,
  and have not had to radically change any existing APIs to accommodate
  them. We will probably end up adding some more convenience APIs for
  specific use-cases in the future, but we believe we have proven the
  viability and stability of the APIs we have. We have not needed
  breaking changes in new APIs, and we expect all future changes
  to follow :pep:`387`'s change policy.

- Internal documentation. We have multiple Core Developers working on
  free-threaded Python, including several who recently started working on
  fixing thread-safety issues in specific modules, but we probably need to
  shore up the introductory documentation for the internals of
  free-threaded Python. This should not be a problem to achieve for 3.14.

With these criteria satisfied, we believe Python 3.14 is the right time frame
for phase II of :pep:`703`.

(Note that these are requirements for entering phase II *only*. The decision
to make free-threaded Python the default (phase III) is very different, and
we expect it will revolve around community support, willingness, and showing
clear benefit. That's left for a future PEP.)

Open Issues
===========

- Should the Stable ABI be a strong requirement for "supported" status of the free-threaded build?


Footnotes
=========

Copyright
=========

This document is placed in the public domain or under the
CC0-1.0-Universal license, whichever is more permissive.
