When does Docker image cache invalidation occur?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Docker build cache is reused step by step, not for the image as a whole. A layer is reused only if Docker decides the instruction and its relevant inputs match a previously built result. Once one step misses the cache, every following step in that stage must be rebuilt from that new point onward.
The Core Rule
A Docker build processes the Dockerfile instruction by instruction. For each step, Docker checks whether it already has a cached result for that instruction with the same effective inputs.
Those inputs depend on the instruction type:
- '
FROMdepends on the resolved base image' - '
COPYandADDdepend on the copied files and metadata in the build context' - '
RUNdepends on the command and the filesystem state produced by prior layers' - '
ARGandENVcan affect later instructions if those values are used'
The practical rule is simple: a cache miss at one step invalidates cache reuse for subsequent steps in that stage.
Example: Why a Small Change Can Rebuild Half the Image
Consider this Dockerfile:
If only application source files change while requirements.txt stays the same, Docker can usually reuse:
- '
FROM' - '
WORKDIR' - '
COPY requirements.txt .' - '
RUN pip install -r requirements.txt'
Then it rebuilds from COPY . . onward.
If requirements.txt changes, the RUN pip install layer changes too, and everything after that must rebuild.
This is why Dockerfiles are often organized so slow dependency-install steps occur before fast-changing application code.
What Actually Invalidates COPY and ADD
For COPY and ADD, the cache key depends on the relevant files from the build context. If one of those files changes, the instruction's cache is invalidated.
That means:
- editing a copied file invalidates the layer
- adding a new file matched by the copy source can invalidate the layer
- deleting a previously copied file can invalidate the layer
It is also why .dockerignore matters. If unnecessary files such as node_modules, local build artifacts, or .git data are part of the build context and included in a COPY, they can trigger cache misses even though the container does not need them.
RUN Does Not Know the Internet Changed
A subtle point: RUN apt-get update && apt-get install -y curl does not automatically rebuild just because the upstream package repository changed. Docker does not query the internet to decide whether a cached RUN is stale.
If the instruction text and prior filesystem state match, Docker may reuse the cached layer.
That is why teams sometimes use explicit cache-busting strategies, such as changing a build argument:
Then build with:
That forces the relevant step to miss cache.
FROM, ARG, and Multi-Stage Builds
If the FROM image reference resolves differently, cache reuse for that stage changes too. For example, updating python:3.11-slim to python:3.12-slim invalidates the stage from the base image onward.
Multi-stage builds isolate cache behavior by stage. A cache miss in the builder stage does not necessarily invalidate an unrelated stage unless artifacts are copied from it and those artifacts change.
That is one reason multi-stage Dockerfiles are useful: they let you keep build tooling and final runtime packaging separate while preserving more precise caching.
A Better Dockerfile Layout
A cache-friendly layout for many application builds is:
- copy only dependency manifests first
- install dependencies
- copy the rest of the source code
- build the application
For Node.js, for example:
This keeps dependency installation cached unless the lock file changes.
Common Pitfalls
A common mistake is thinking Docker reuses cache based on the final image name. Cache is matched instruction by instruction.
Another mistake is assuming RUN steps automatically invalidate when external package repositories change. They do not unless relevant build inputs change or you force a rebuild.
People also often place COPY . . too early in the Dockerfile, which causes small source changes to invalidate expensive dependency-install steps.
Finally, forgetting .dockerignore can make cache behavior noisy because irrelevant local files become part of the build context.
Summary
- Docker cache invalidation happens per instruction, not for the image as a whole
- A layer is reused only if the instruction and its effective inputs match a cached result
- Once one step misses cache, later steps in that stage rebuild from there
- '
COPYandADDare invalidated by changes to the relevant build-context files' - '
RUNdoes not automatically know external resources changed unless build inputs change or you force cache busting' - Good Dockerfile ordering and a proper
.dockerignoremake cache behavior predictable and fast

