Python 3.15 Arrives: Lazy Imports, a Faster JIT, and UTF-8 by Default

The Python Software Foundation has released Python 3.15, and this year’s annual CPython update is one of the most consequential in years. Arriving on October 9 after a slightly bumpy runway — the release manager even pushed out an unscheduled third release candidate to squash last-minute lazy-import bugs — Python 3.15 is less about a single headline feature and more about a performance story that is finally starting to compound.

Lazy Imports: The Feature Everyone Will Notice First

The change with the broadest day-to-day impact is PEP 810, explicit lazy imports. Python has always loaded imported modules eagerly, even when a program never touches them at runtime. For large applications with heavy dependency trees, that import tax has long dominated startup latency — a pain point familiar to anyone who has run a CLI tool that takes a second just to print a help message.

Python 3.15 introduces a new lazy soft keyword. Write lazy import heavy_module and Python defers loading the module until the first time your code actually uses it. Developers get the organizational benefit of declaring all imports at the top of a file while only paying the loading cost for the modules they truly exercise. If a lazily imported module fails to load, the exception is raised at the point of first use rather than at import time — a behavioral nuance that teams will want to account for in error handling.

The JIT Compiler Grows Up

The experimental just-in-time compiler introduced in recent CPython releases has received its most substantial upgrade yet. According to the release notes, the JIT now delivers a 7–8% geometric mean performance improvement over the standard interpreter on x86-64 Linux, and an 11–12% speedup on AArch64 macOS compared to the tail-calling interpreter. The numbers vary by platform and workload, and the JIT remains officially experimental — but the trajectory is unmistakable. CPython’s multi-year performance push, from the specializing interpreter to the copy-and-patch JIT, is delivering measurable returns.

UTF-8 Everywhere

Python 3.15 also flips one of its longest-standing configuration defaults: UTF-8 is now the default encoding across platforms, per PEP 686. For years, cross-platform text handling trips over locale-dependent encodings, with Windows behaving differently from Linux and macOS. Defaulting to UTF-8 eliminates a whole class of cross-platform compatibility bugs and brings Python in line with the broader industry direction.

Free-Threading Takes Another Step

Work on removing the Global Interpreter Lock continues to mature. Python 3.15 adds a stable ABI for free-threaded builds, called abi3t, along with companion C API changes. The macOS installers now include free-threading support by default, making it dramatically easier for developers to experiment with GIL-free parallelism. Extension authors should note, however, that targeting the new ABI generally requires non-trivial source changes — the docs are candid that compatibility is not automatic.

Smaller Gems Worth Knowing

The release is packed with quality-of-life improvements:

  • frozendict becomes a built-in type (PEP 814), giving developers an immutable, hashable mapping.
  • A built-in sentinel type (PEP 661) finally standardizes a pattern libraries have reimplemented for decades.
  • Unpacking in comprehensions (PEP 798) simplifies common iteration idioms.
  • Package startup configuration files (PEP 829) let packages define declarative startup behavior.
  • A new statistical profiler, Tachyon, can sample a live process without code modification or restarts and emit interactive flame graphs — a significant observability upgrade.
  • Frame pointers are now enabled by default, improving integration with system-level profilers.
  • Error messages and typing features continue their steady polish, with TypedDict gaining typed extra items and the argparse module enabling suggestion hints by default.

Should You Upgrade?

The honest answer: CPython performance work is compounding, but no single feature is a must-upgrade on its own. The JIT is not finished, free-threading is not yet mainstream, and the biggest wins come from measuring your own workloads. Teams with import-heavy CLI tools and services will likely see immediate startup improvements from lazy imports, while data-heavy shops should benchmark the JIT and free-threaded builds against their real dependencies.

As always with a fresh major release, the practical blocker is ecosystem compatibility. Give key libraries a few weeks to publish wheels, test your critical paths, and treat 3.15 as the release where Python’s modernization efforts visibly converge.

One thing is clear: the world’s most popular programming language is getting faster, leaner at startup, and more serious about parallelism — one deliberate annual release at a time.


What are your thoughts on Python 3.15? Will lazy imports change how you structure your code? Let us know in the comments.

Why It Matters

Python 3.15 matters less for any single feature than for how several long-running efforts now reinforce one another: lazy imports attack startup latency, the JIT targets runtime speed, and UTF-8 defaults remove a class of cross-platform encoding bugs. The JIT and free-threading work remain experimental, so the gains will vary by platform and workload. The practical constraint is ecosystem readiness, since libraries need time to publish compatible wheels before teams can treat 3.15 as a drop-in upgrade.

Sources