Motivation
CPython 3.13 introduced an experimental free-threaded build (PEP 703) that removes the Global Interpreter Lock (GIL). CPython 3.14t is the first release where this build is stable enough for production use, and the ecosystem of packages with free-threading wheels is growing rapidly.
vLLM has demonstrated (vllm-project/vllm#28762) that a large-scale CUDA-accelerated serving framework can run under a free-threaded interpreter. SGLang shares a similar dependency footprint and architecture. Enabling free-threaded support would unlock true CPU-level parallelism in the Python layer — benefiting the tokenizer manager, scheduler, HTTP server, disaggregation controller, and other asyncio + thread-pool components that today serialize behind the GIL.
This RFC tracks the dependency readiness, identifies the internal code changes needed, and proposes a phased plan to make uv pip install sglang work out of the box in a clean Python 3.14t environment on Linux x86-64 (CPU and CUDA).
Background
| Term |
Meaning |
| 3.14t |
The free-threaded (no-GIL) CPython 3.14 build, identified by the t suffix in the ABI tag (cp314t). |
| cp314 |
The regular (with-GIL) CPython 3.14 build. |
| Stable ABI |
A subset of the CPython C API that is ABI-compatible across Python versions (PEP 384). Extensions built against the stable ABI only need one wheel per platform, not one per Python minor version. |
Py_GIL_DISABLED |
The compile-time macro set in free-threaded builds. C extensions must check this to use thread-safe reference counting and data structures. |
Why 3.14t and not 3.13t?
- CPython 3.14t itself is significantly more stable than 3.13t.
- Key packages (cffi, aiohttp, etc.) support 3.14t but will not back-port to 3.13t.
- PyTorch 2.10.0 (January 2026) will ship full cp314t wheels; PyTorch 2.9.0 already has "preview" wheels.
Prerequisites
Free-threaded Python support depends on SGLang first supporting regular Python 3.14 (with-GIL). This RFC assumes that prerequisite is met or being tracked separately.
Dependency Audit
The following tables categorize every SGLang dependency with compiled (C/C++/Rust/CUDA) code by its current free-threading readiness. Pure-Python packages are omitted — they work automatically.
Core Dependencies (from pyproject.toml dependencies)
| Package |
Current Version |
cp314t Wheels on PyPI |
Builds from Source |
Tracking Issue |
Notes |
torch |
2.9.1 |
Preview (2.9.0); full in 2.10.0 |
Yes |
— |
Core dependency. 2.10.0 (Jan 2026) is the target. |
torchaudio |
2.9.1 |
Follows torch |
Yes |
— |
|
torchvision |
latest |
Follows torch |
Yes |
— |
|
torchao |
0.9.0 |
Follows torch |
TBD |
— |
|
sglang-kernel |
0.4.1 |
❌ No |
❌ Needs work |
— |
SGLang-owned. Uses stable ABI (cp310). Needs Py_GIL_DISABLED audit. See below. |
flash-attn-4 |
≥4.0.0b4 |
❌ No |
TBD |
— |
CUDA extension. |
flashinfer_python |
0.6.7.post2 |
❌ No |
Resolved |
flashinfer-ai/flashinfer#1687 |
Uses stable ABI; fix was to not use limited API with free-threaded Python. |
flashinfer_cubin |
0.6.7.post2 |
❌ No |
TBD |
— |
Binary CUDA kernels, may need rebuild only. |
cuda-python |
12.9 |
TBD |
TBD |
— |
NVIDIA-maintained. |
xgrammar |
0.1.32 |
✅ Yes (≥0.1.31) |
✅ Yes |
xgrammar#500 |
Full support. |
llguidance |
≥0.7.11 |
✅ Yes (≥1.6.0) |
✅ Yes |
llguidance#256 |
Full support. |
msgspec |
latest |
✅ Yes (≥0.20.0) |
✅ Yes |
— |
Full support. |
outlines |
0.1.11 |
TBD (outlines-core) |
✅ Yes |
outlines-core#248 |
Depends on outlines-core. |
sentencepiece |
latest |
TBD |
TBD |
— |
C++ extension. |
tiktoken |
latest |
TBD |
TBD |
— |
Rust extension. |
orjson |
latest |
✅ Yes |
✅ Yes |
— |
Rust extension, typically early adopter. |
pyzmq |
≥25.1.2 |
✅ Yes |
✅ Yes |
— |
|
numpy |
latest |
✅ Yes |
✅ Yes |
— |
|
scipy |
latest |
✅ Yes |
✅ Yes |
— |
|
aiohttp |
latest |
✅ Yes |
✅ Yes |
— |
Supports 3.14t. |
pybase64 |
latest |
TBD |
TBD |
— |
C extension. |
setproctitle |
latest |
TBD |
TBD |
— |
C extension. |
nvidia-ml-py |
latest |
Pure Python |
N/A |
— |
|
pillow |
latest |
✅ Yes |
✅ Yes |
— |
|
pydantic |
latest |
✅ Yes |
✅ Yes |
— |
Rust-compiled core. |
uvloop |
latest |
TBD |
TBD |
— |
C extension (libuv). Critical for asyncio perf. |
soundfile |
0.13.1 |
TBD |
TBD |
— |
CFFI-based. |
compressed-tensors |
latest |
TBD |
TBD |
— |
|
quack-kernels |
≥0.3.0 |
❌ No |
TBD |
— |
CUDA extension. |
kernels |
latest |
TBD |
TBD |
— |
|
smg-grpc-servicer |
≥0.5.0 |
TBD |
TBD |
— |
gRPC bindings. |
Optional Dependencies (diffusion, ray, tracing)
| Package |
cp314t Status |
Notes |
ray |
❌ No 3.14 support at all |
Made optional in vLLM. SGLang already has it as optional ([ray]). Not blocking. |
opencv-python-headless |
❌ No |
Diffusion extra only. Tracking: opencv/opencv#27933, build fix PR: opencv-python#1051. |
xformers |
✅ Yes (≥0.0.35) |
Resolved by removing CPython C API dependency. |
SGLang-Owned Compiled Components
| Component |
Language |
Build System |
Free-Threading Status |
sgl-kernel |
C++17 / CUDA |
scikit-build-core + CMake |
❌ Uses stable ABI (cp310). Needs Py_GIL_DISABLED audit and potentially per-version builds. |
cpp_radix_tree (radix cache) |
C++ |
pybind11 (torch extension) |
❌ Needs thread-safety audit. |
ngram_corpus_ffi |
C++ |
pybind11 (torch extension) |
❌ Needs thread-safety audit. |
hf3fs_utils |
C++ |
pybind11 (torch extension) |
⚠️ Uses py::gil_scoped_release. Needs Py_GIL_DISABLED review. |
sgl-model-gateway (router) |
Rust (PyO3) |
maturin |
✅ PyO3 has free-threading support. |
multimodal_gen CUDA kernels |
C++ / CUDA |
setuptools |
❌ Needs audit. |
Internal Code Audit
GIL-Dependent Patterns
The following patterns in SGLang's Python code rely on the GIL for correctness and must be reviewed:
-
Explicit GIL assumptions. staging_handler.py documents: "CPython GIL guarantees ordering" for flag visibility between threads. Under free-threading, this needs an explicit memory barrier or threading.Event.
-
py::gil_scoped_release in C++ extensions. hf3fs_utils.cpp uses py::gil_scoped_release to release the GIL during memcpy. Under free-threading, pybind11's gil_scoped_release is a no-op, but the surrounding data structures must be thread-safe without the GIL.
-
Shared mutable state across threads. The following areas use thread pools or daemon threads that share mutable Python objects:
TokenizerManager: ThreadPoolExecutor for tokenization with shared request queues
CacheController: background threads for cache management
KVEvents: daemon threads for ZMQ event distribution
weight_utils.py: multi-threaded safetensors loading with shared iterators
-
Module-level mutable globals. Several modules use module-level dicts/lists as registries (model registry, format registry, etc.). Under free-threading, concurrent imports or first-access initialization can race.
-
asyncio + ThreadPoolExecutor interaction. run_coroutine_threadsafe and call_soon_threadsafe are used throughout the disaggregation layer. These are asyncio-safe but the callbacks they schedule may access shared state without locks.
Thread-Safety Classification
| Risk Level |
Pattern |
Example Locations |
Mitigation |
| High |
GIL-ordering assumptions |
staging_handler.py:192 |
Replace with threading.Event or atomics |
| High |
Shared mutable containers across threads |
weight_utils.py (iterator sharing) |
Add threading.Lock or use queue.Queue |
| Medium |
Module-level mutable registries |
Model/format registries |
Use threading.Lock for lazy init |
| Medium |
concurrent.futures with shared closures |
async_dynamic_batch_tokenizer.py |
Audit closure captures |
| Low |
py::gil_scoped_release in C++ |
hf3fs_utils.cpp |
Verify data is not shared with Python threads |
| Low |
Pure asyncio code (single-threaded event loop) |
HTTP server, tokenizer manager main loop |
Safe by design (single-threaded) |
Proposed Plan
Phase 0: Python 3.14 (with-GIL) Support
Goal: pip install sglang works on regular Python 3.14.
Phase 1: Dependency Readiness Tracking
Goal: All dependencies are installable in a 3.14t environment.
Phase 2: sgl-kernel Free-Threading Support
Goal: sglang-kernel builds and passes tests under 3.14t.
Phase 3: Internal C++ Extension Audit
Goal: All SGLang-owned C++ extensions are thread-safe without the GIL.
Phase 4: Python-Level Thread-Safety Fixes
Goal: SGLang's Python code does not rely on GIL for correctness.
Phase 5: CI and Release
Goal: Free-threaded builds are tested and released.
Phase 6: Performance Validation and Optimization
Goal: Quantify the benefit of free-threading for SGLang workloads.
References
Related resources
No response
Motivation
CPython 3.13 introduced an experimental free-threaded build (PEP 703) that removes the Global Interpreter Lock (GIL). CPython 3.14t is the first release where this build is stable enough for production use, and the ecosystem of packages with free-threading wheels is growing rapidly.
vLLM has demonstrated (vllm-project/vllm#28762) that a large-scale CUDA-accelerated serving framework can run under a free-threaded interpreter. SGLang shares a similar dependency footprint and architecture. Enabling free-threaded support would unlock true CPU-level parallelism in the Python layer — benefiting the tokenizer manager, scheduler, HTTP server, disaggregation controller, and other asyncio + thread-pool components that today serialize behind the GIL.
This RFC tracks the dependency readiness, identifies the internal code changes needed, and proposes a phased plan to make
uv pip install sglangwork out of the box in a clean Python 3.14t environment on Linux x86-64 (CPU and CUDA).Background
tsuffix in the ABI tag (cp314t).Py_GIL_DISABLEDWhy 3.14t and not 3.13t?
Prerequisites
Free-threaded Python support depends on SGLang first supporting regular Python 3.14 (with-GIL). This RFC assumes that prerequisite is met or being tracked separately.
Dependency Audit
The following tables categorize every SGLang dependency with compiled (C/C++/Rust/CUDA) code by its current free-threading readiness. Pure-Python packages are omitted — they work automatically.
Core Dependencies (from
pyproject.tomldependencies)torchtorchaudiotorchvisiontorchaosglang-kernelPy_GIL_DISABLEDaudit. See below.flash-attn-4flashinfer_pythonflashinfer_cubincuda-pythonxgrammarllguidancemsgspecoutlinessentencepiecetiktokenorjsonpyzmqnumpyscipyaiohttppybase64setproctitlenvidia-ml-pypillowpydanticuvloopsoundfilecompressed-tensorsquack-kernelskernelssmg-grpc-servicerOptional Dependencies (diffusion, ray, tracing)
ray[ray]). Not blocking.opencv-python-headlessxformersSGLang-Owned Compiled Components
sgl-kernelcp310). NeedsPy_GIL_DISABLEDaudit and potentially per-version builds.cpp_radix_tree(radix cache)ngram_corpus_ffihf3fs_utilspy::gil_scoped_release. NeedsPy_GIL_DISABLEDreview.sgl-model-gateway(router)multimodal_genCUDA kernelsInternal Code Audit
GIL-Dependent Patterns
The following patterns in SGLang's Python code rely on the GIL for correctness and must be reviewed:
Explicit GIL assumptions.
staging_handler.pydocuments: "CPython GIL guarantees ordering" for flag visibility between threads. Under free-threading, this needs an explicit memory barrier orthreading.Event.py::gil_scoped_releasein C++ extensions.hf3fs_utils.cppusespy::gil_scoped_releaseto release the GIL during memcpy. Under free-threading, pybind11'sgil_scoped_releaseis a no-op, but the surrounding data structures must be thread-safe without the GIL.Shared mutable state across threads. The following areas use thread pools or daemon threads that share mutable Python objects:
TokenizerManager:ThreadPoolExecutorfor tokenization with shared request queuesCacheController: background threads for cache managementKVEvents: daemon threads for ZMQ event distributionweight_utils.py: multi-threaded safetensors loading with shared iteratorsModule-level mutable globals. Several modules use module-level dicts/lists as registries (model registry, format registry, etc.). Under free-threading, concurrent imports or first-access initialization can race.
asyncio + ThreadPoolExecutor interaction.
run_coroutine_threadsafeandcall_soon_threadsafeare used throughout the disaggregation layer. These are asyncio-safe but the callbacks they schedule may access shared state without locks.Thread-Safety Classification
staging_handler.py:192threading.Eventoratomicsweight_utils.py(iterator sharing)threading.Lockor usequeue.Queuethreading.Lockfor lazy initconcurrent.futureswith shared closuresasync_dynamic_batch_tokenizer.pypy::gil_scoped_releasein C++hf3fs_utils.cppProposed Plan
Phase 0: Python 3.14 (with-GIL) Support
Goal:
pip install sglangworks on regular Python 3.14.Phase 1: Dependency Readiness Tracking
Goal: All dependencies are installable in a 3.14t environment.
Phase 2: sgl-kernel Free-Threading Support
Goal:
sglang-kernelbuilds and passes tests under 3.14t.Phase 3: Internal C++ Extension Audit
Goal: All SGLang-owned C++ extensions are thread-safe without the GIL.
Phase 4: Python-Level Thread-Safety Fixes
Goal: SGLang's Python code does not rely on GIL for correctness.
Phase 5: CI and Release
Goal: Free-threaded builds are tested and released.
Phase 6: Performance Validation and Optimization
Goal: Quantify the benefit of free-threading for SGLang workloads.
References
Related resources
No response