When does Docker image cache invalidation occur?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
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
Related reading
- When not to use docker run --init
- When to pull from Docker repo and when from Git repo and then build?
- When to use Docker HEALTHCHECK vs livenessProbe / readinessProbe
- Where are Docker images stored on the host machine?
- When does Kafka Leader Election happen?
- When Kafka send acknowledgement if acksall and all replicas are healthy?
- When I use Deployment in Kubernetes, what''s the differences between apps/v1beta1 and extensions/v1beta1?
- when rabbitmq delete message from queue?

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.