Skip to content
tutorials

Python’s 3X Startup Trick Has a Catch

A faster launch sounds like a free win—until a plugin quietly stops registering. The real story is why Python’s new approach makes laziness explicit.

Dani Roth
Python’s 3X Startup Trick Has a Catch

Why Python pays an import tax before your code runs

Python pays an import tax before your code runs. Interpreter startup initiates an eager-import chain: locate modules, compile or load bytecode, then execute module-level code. This process recurses through the entire dependency graph, loading every module and its dependencies.

This eager loading exacts a toll. Startup-heavy applications, command-line tools, and short-lived serverless functions feel the cost most acutely. They may exit before using much of what they imported, paying for work that never contributes to execution. A Python core developer benchmarked a small app: 104 ms startup with normal imports.

Lazy loading offers an escape. Instead of immediate execution, it provides a placeholder. The real import — finding the file, compiling bytecode, and running module-level code — only triggers when your code first references the imported module. This defers work until necessary.

The same developer’s benchmark shows impact: hiding heavy imports inside functions reduced startup to 46 ms. Making all imports lazy slashed it further to 36 ms, nearly 3x faster than eager loading. This isn't a universal total runtime improvement, but a targeted startup optimization.

Explicit lazy imports, using a new lazy keyword, prevent breaking existing code that relies on module-level side effects, such as plugin registration. This ensures targeted optimization without unintended consequences.

The small syntax change behind the speedup

PEP 810 introduces explicit lazy imports, a targeted syntax solution. Place lazy import <module> at the top of a file, just like regular imports, but defer module execution until the code first accesses an imported name. This keeps dependencies visible and avoids scattering import statements throughout the codebase, a common workaround for slow startup.

The familiar workaround—moving imports inside functions—hides dependencies and clutters code. Native lazy import fixes this. It offers the same startup benefits without sacrificing readability or forcing developers to refactor import locations.

Python resolves the deferred import on first use. When code accesses an imported name or module attribute, the interpreter then loads, compiles, and executes the module. This means the application still pays the import cost, but only when and if that specific dependency is actually required during runtime.

This targeted approach offers significant gains. A core Python developer benchmarked an app: 104 ms with normal imports, 46 ms when hiding heavy imports in functions, and 36 ms with everything lazy. That’s a nearly 3x speedup from eager to fully lazy. Using the lazy keyword is preferred over global settings like PYTHONLAZYIMPORTS because it prevents breaking code that registers plugins or executes other critical side-effects during import. Mark only your heavy imports for the safest, biggest impact.

A 104 ms launch drops to 36 ms—but that’s one app

A Python core developer demonstrated the impact of lazy imports on a small application. Baseline startup, using normal eager imports, took 104 ms. Manually moving heavy imports into functions reduced this to 46 ms. With explicit lazy imports, startup time dropped further to 36 ms. This represents a 2.9x speedup over the eager baseline.

These figures illustrate the potential, but are not universal guarantees. Performance gains vary by application. Test your own project to confirm benefits. Refer to PEP 810 – Explicit lazy imports for full specification details.

Lazy imports deliver the most significant payoff for startup-dominated workloads. These include:

  • Command-line interfaces (CLIs)
  • Short-lived local scripts
  • Serverless function invocations

In these scenarios, the initial import tax often comprises a large percentage of total execution time. Deferring module execution directly reduces this overhead. Measure your application's startup time to identify if lazy imports can offer a similar performance boost.

Enjoying this? Get one like it in your inbox each morning.

one email a day · unsubscribe in two clicks · no third-party tracking

Why making every import lazy can backfire

Global lazy imports can backfire. Some modules register plugins, hooks, or other behavior immediately on import; deferring these means setup never happens when expected. Code depending on these side-effects will break.

Explicit lazy import syntax, as in PEP 810, avoids this hazard. It targets specific, heavy, or optional dependencies for deferral. This differs from a global environment variable or command-line switch that broadly changes all imports to lazy.

Meta’s Cinder fork of Python initially explored global laziness. Experience with Cinder informed work on PEP 690, which proposed implicit global lazy imports but faced rejection due to these very side-effect concerns.

PEP 810's explicit approach addresses those concerns, providing a safer, more controlled mechanism. Always check your Python version and the feature's specific status before adopting lazy import. It offers significant startup gains but demands careful, targeted application.

Frequently Asked Questions

What are lazy imports in Python?

Lazy imports defer loading and executing an imported module until code first uses it.

How much faster can lazy imports make Python startup?

In one reported small-app benchmark, startup fell from 104 ms to 36 ms—about 2.9 times faster. Results vary by application.

How do you write a lazy import?

Use the explicit form lazy import module to defer that import until it is needed.

Can lazy imports break Python applications?

Yes. Deferring modules that register plugins or perform other import-time side effects can change behavior; explicit, targeted use reduces that risk.

Found this useful? Share it.

For builders

Want Stork to write one of these about your product?

Send us a URL. We use the product, form a view, and publish what we actually think — in 8 languages, labeled Sponsored, with no copy approval on your side. That last part is what makes it worth quoting.

See how it works$500 · AI tools & software only

For builders

This page is doing a job for someone else’s tool.

AI agents read it. Buyers land on it. It answers in eight languages and over MCP. Your tool can have one like it — live in 24 hours.