
Python 3.15 hit beta 1 on May 7. Feature freeze is now active — the feature set is locked, and what shipped in beta is what ships in October. Three performance-focused additions lead this release: explicit lazy imports via PEP 810, a noticeably improved JIT compiler, and Tachyon, a built-in statistical sampling profiler. If you maintain a Python package, the calculus is straightforward: bugs found during beta are fixable. Bugs found after the October GA are your problem.
Lazy Imports Finally Land (PEP 810)
Slow startup has been Python’s most consistent embarrassment in the CLI and test-runner space. Every import statement fires at startup whether or not the code path that needs it ever runs. PEP 810 fixes this with a new lazy keyword that defers module loading until first use.
# Standard import — numpy loads immediately at startup
import numpy as np
# Python 3.15 — numpy loads only when np.array() is first called
lazy import numpy as np
The numbers back it up. Benchmarks show CLI startup dropping from 104ms to 36ms — nearly a 3x improvement. Meta reported a 70% reduction in initialization time across its internal Python libraries. Nothing becomes lazy unless you explicitly say so; the design is opt-in by nature. That’s the right call. Magic imports that silently defer loading create debugging nightmares. Explicit lazy imports give you the speedup without the confusion.
There’s also a backward-compatible opt-in path via the __lazy_modules__ list attribute, which lets you enable lazy loading for specific modules without rewriting every import statement.
The JIT Keeps Improving
Python’s JIT compiler was introduced experimentally in 3.13. In 3.15, it’s measurably better. The official What’s New cites 8–9% geometric mean improvement over standard CPython on x86-64 Linux. On Apple silicon (AArch64 macOS), the JIT pulls 12–13% ahead of the tail-calling interpreter.
What changed: the 3.15 JIT now handles simple object creation, partially covers overloaded operations and generators, and gains basic register allocation. That last addition means the JIT avoids redundant stack reads and writes by keeping values in CPU registers — a textbook compiler optimization that was missing until now.
The JIT isn’t on by default — you need a build with --enable-experimental-jit. But the trajectory matters: 3.11 gave us a 25% faster CPython; 3.13 introduced the JIT; 3.15 pushes it further. The compounding effect across releases is the real story, not any single benchmark number.
Tachyon: A Sampling Profiler Now in Stdlib
If you’ve used py-spy or pyinstrument for production profiling, you know the gap in Python’s standard tooling. cProfile is a deterministic profiler — it instruments every function call, adding overhead. For long-running production processes, you want a sampling profiler: something that periodically captures a stack trace and builds a statistical picture of where time is spent.
Python 3.15 ships Tachyon as profiling.sampling, per PEP 799. It samples at up to 1,000,000 Hz with near-zero overhead and requires zero code changes. It can also attach to an already-running process without a restart.
# Profile a script and generate an interactive flame graph
python -m profiling.sampling --flamegraph myscript.py
# Attach to an already-running process
python -m profiling.sampling --pid 12345
Output modes include wall-clock time (default), CPU time only, GIL-holding time, and exception-handling time. Output formats: pstats-compatible tables or interactive HTML flame graphs rendered via D3.js. One housekeeping note: cProfile moves to profiling.tracing (the alias stays), and the profile module is deprecated in 3.15 and removed in 3.17. If you’re still on import profile, now is the time to migrate.
Stable ABI for Free-Threaded Builds and Other Additions
PEP 803 delivers a stable ABI for free-threaded CPython builds (abi3t). C extension authors can now compile once and target multiple minor versions of free-threaded CPython, rather than rebuilding per release. The bottleneck for free-threading adoption has never been CPython — it’s been ecosystem support from C extensions. This directly addresses that, and the NumPy/SciPy/Pandas ecosystem will benefit most.
A few other additions: frozendict lands as a built-in immutable, hashable dictionary. PEP 798 allows unpacking in comprehensions ([*L for L in lists] is now valid syntax). And Python finally defaults to UTF-8 encoding everywhere, ending the persistent Windows cp1252 encoding footgun.
What to Do Now
The feature set is locked. If you maintain a Python package, test against beta 1 now and report issues to the CPython bug tracker. RC1 lands August 4 — after that, breaking changes become very unlikely. The beta phase exists precisely so the ecosystem has time to adapt before the October 1 GA. That window is open now. Use it.













