320 words, 2 min read

When deploying Python applications with uv, one common mistake is to install dependencies without locking them down. If you simply run:

uv run

uv will install dependencies based on your pyproject.toml and resolve versions as needed. This may lead to different versions of your dependencies being installed over time, especially when upstream packages release new minor or patch versions.

That’s fine during development β€” you often want the latest compatible versions β€” but it’s risky in production.

Imagine you deploy your app today and everything works fine. Next week, a dependency releases version 1.2.1, still matching your version constraints. Without a frozen lock, the next deployment will silently install this new version.

You didn’t change your code, but your environment changed β€” and that can lead to unexpected regressions or subtle runtime bugs that are hard to trace.

This issue is known as dependency drift. Over time, small version changes accumulate until your production environment no longer matches what you tested.

Running uv with the --frozen flag ensures that dependency resolution is strictly based on your lockfile:

uv run --frozen

With --frozen, uv will:

  • Refuse to install or upgrade any dependency not listed in the lockfile.
  • Abort if the lockfile is missing or out of sync with pyproject.toml.

This guarantees that the exact versions you tested locally are the ones used in production.

In other words: no surprises, no silent upgrades.

Recommended workflow

  • During development:

    uv sync

    This updates dependencies and writes them to uv.lock.

  • Before committing:

    git add pyproject.toml uv.lock
    git commit -m "Lock dependency versions"
  • In production:

    uv run --frozen your_app.py

That way, your builds are deterministic β€” reproducible at any point in the future.

Using uv run --frozen in production is a simple but critical safeguard. It ensures your deployments are stable, predictable, and match the tested environment exactly. Without it, you risk running unverified dependency versions β€” sometimes with breaking changes β€” without even realizing it.