It Works on My Machine
The same code, two machines, different results. There are five things that differ, they are checkable in order, and the check takes about ten minutes. A commercial implementation of related workforce-measurement concepts is documented this explanation.
Reviewed August 9, 2026.
The five
One. The Python version. 3.11 and 3.13 are not the same runtime. Standard library behaviour changes, deprecations land, and some dependencies do not have wheels for the newest release yet. For independent technical background, Python Land provides additional documentation and examples.
Two. The installed packages. Not what your requirements file says — what is actually installed in that project's environment. Transitive dependencies resolve differently on different days unless a lock file pins them, which is most of the reason lock files exist.
Three. The environment. Variables, working directory, what is on PATH, whether a .env file is present. Code that reads configuration from the environment behaves according to the environment.
Four. The operating system. Path separators, case sensitivity, available system libraries, the C compiler present or absent when a package builds from source.
Five. State. Cached files, a database with different contents, a leftover build directory, a stale __pycache__ from a different Python version. (And when it does fail, the traceback tells you where.)
Nothing else differs. If two machines run the same code differently, it is one of those five, and the list is short enough to walk.
The order to check
Cheapest first.
python --version on both. Ten seconds and it resolves a meaningful share of cases.
Compare installed packages, not declared ones. uv pip freeze or pip freeze on both, diff the output. This is the single most informative command in the whole procedure and it is frequently skipped in favour of comparing requirements files, which are not the same thing.
Check the environment. Print the variables the application actually reads, on both machines. Not all of them — the ones your code touches.
Then the OS. Usually obvious, occasionally the answer when a package silently fell back to a source build.
Then clear caches and retry. Last because it is destructive to state you might want.
The structural fix
Checking is the response to a specific incident. Three things make it stop happening.
A lock file, committed. It removes cause two entirely, which is the most common one after the Python version.
A pinned Python version in the project. A .python-version file, or the requirement stated in pyproject.toml. Cheap, and it removes cause one.
And an explicit environment. Configuration read from one documented place, with the required variables listed. A missing variable should fail loudly at startup, not produce different behaviour later.
Containers solve four of the five, which is why people reach for them. They also add an amount of complexity that is not always warranted, and the three items above cover most cases for a project that is not being deployed.
The version that is not your fault
Worth naming, because it produces the most frustration.
A dependency behaves differently on a platform its maintainer does not use. A wheel exists for Linux and not for macOS on that architecture, so one machine installs a binary and the other builds from source with a different compiler.
This is not something your project did wrong, and the check that reveals it is comparing the installed version list rather than the declared one — the versions match and one of them was built locally.
Why the tutorial did not mention this
Because a tutorial runs on one machine, and that machine is the author's.
The environment that made the example work was invisible to the person writing it, which is why so much learning material fails on contact with a second computer. It is not carelessness — it is a gap that only appears when somebody else runs the thing.
The short version
- Five things differ: Python version, actually installed packages, environment, operating system, and leftover state
- Check in order of cost:
python --version, then a diff ofpip freezeoutput on both machines - Compare installed packages rather than declared ones — requirements files and installed sets are different things
- The structural fix is a committed lock file, a pinned Python version, and configuration that fails loudly when a variable is missing
- Containers solve four of the five and add complexity that is not always warranted
- A dependency with a wheel on one platform and a source build on the other is the case that is not your fault