# How to Use `--exclude-newer` for Reproducible Python Environments


The `--exclude-newer` option instructs [uv](https://pydevtools.com/handbook/reference/uv.md) to ignore any package versions published after a specified date. This creates a time-locked resolution process that ensures consistency regardless of when the installation is run.

## Basic usage

Pass an [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339) date or timestamp to `--exclude-newer`:

```bash
uv add -r requirements.txt --exclude-newer 2023-12-12
```

The flag also accepts a full timestamp for more precision:

```bash
uv lock --exclude-newer "2023-12-12T00:00:00Z"
```

## Reproducing historical environments

This is particularly useful when reproducing environments for older projects. For example, if a repository was last updated in June 2023, use the flag to only resolve dependencies that were available at that time:

```bash
git clone https://github.com/example/ml-model
cd ml-model
uv add -r requirements.txt --exclude-newer 2023-06-15
```

## Setting `exclude-newer` in `pyproject.toml`

For a persistent setting that applies to all uv operations in a project, add `exclude-newer` to `pyproject.toml`:

```toml
[tool.uv]
exclude-newer = "2023-06-15T00:00:00Z"
```

This ensures that anyone running `uv lock` or `uv sync` on the project uses the same time-locked resolution without needing to remember the command-line flag.

> [!TIP]
> For most projects, a [lockfile](https://pydevtools.com/handbook/how-to/how-to-use-a-uv-lockfile-for-reproducible-python-environments.md) is a better solution for reproducible environments. `--exclude-newer` is most valuable when migrating legacy projects to uv or debugging dependency issues that appeared after a specific date.

## pip's equivalent flag

[pip](https://pydevtools.com/handbook/reference/pip.md) 26.0 (January 2026) added `--uploaded-prior-to`, which applies the same datetime cutoff for a single command:

```bash
pip install --uploaded-prior-to 2023-06-15 -r requirements.txt
```

The two flags differ in scope. `--exclude-newer` written into `pyproject.toml` persists for every `uv lock` and `uv sync` in the project, so collaborators automatically get the same time-locked resolution. `--uploaded-prior-to` is per-command and per-invocation, so every pip call that needs the cutoff has to pass the flag. pip also does not yet write the cutoff into the generated `pylock.toml`.

## Learn More

- [uv: A Complete Guide](https://pydevtools.com/handbook/explanation/uv-complete-guide.md) covers what uv does, how fast it is, the core workflows, and recent releases.
- [uv documentation on `--exclude-newer`](https://docs.astral.sh/uv/concepts/resolution/#time-restricted-reproducible-resolutions)
- [How to use a uv lockfile for reproducible Python environments](https://pydevtools.com/handbook/how-to/how-to-use-a-uv-lockfile-for-reproducible-python-environments.md)
