THIS EXPLANATION
THE ROOM
CDA·125 Computing, Data & AI 6 MIN · 8 STATIONS

Layers are diffs

A Socratic walk-through of layers are diffs — reasoned out one step at a time, not lectured.

abcdefgh
a

The question we started with

THE QUESTION #

Why does adding a large file and then deleting it leave the result bigger than before?

Here is a build that looks obviously correct. Download a three-hundred-megabyte archive, extract what you need from it, delete the archive, ship the image. The final filesystem does not contain the archive; you can go and look.

And yet the image is three hundred megabytes larger than the one without those steps. Not slightly larger — larger by exactly the thing you deleted. The deletion clearly worked, since the file is gone. So where is the weight coming from, and what does that tell us about what an image actually is?

b

Reasoning it through

REASONING #

Begin with a suspicion: perhaps an image is not a filesystem at all. If it were a snapshot of final contents, the deleted file would simply be absent and the size would drop.

So what else could it be? Think about what a build system needs. Rebuilding an image that shares a base with fifty others should not copy that base fifty times, and pulling an updated image should not re-download the parts that did not change. Both of those want the same thing: an image stored as a sequence of changes, each one addressed by the hash of its own content, so identical pieces are stored and transferred once.

That is what an image is. Each build instruction that touches the filesystem produces a layer, and a layer is a tar archive of the differences that instruction made — files added, files modified, files removed. The image is the ordered list of those archives plus a manifest naming them. Nothing anywhere holds the merged result.

Now the question answers itself, but follow it precisely. Your extract-and-delete build produced one layer containing the three-hundred-megabyte archive, and then a second layer recording its removal. Both layers ship. The runtime stacks them and the merged view has no archive in it — but the bytes travelled, and they are stored, because a later layer cannot reach back and edit an earlier one. Earlier layers are immutable by construction; that immutability is exactly what makes them shareable and cacheable.

Which raises a mechanical question: how does a later layer record a deletion at all, if a tar archive can only contain files? The union filesystem — overlayfs on modern Linux — uses a marker. In the overlay format a deleted file is represented by a character device with major and minor number zero, sitting at the deleted file's path, and its presence tells the union layer to hide everything below it. The file is not removed; it is masked. That distinction is the whole idea in one sentence.

Now push on the security consequence, because it is the one that bites hardest. Suppose a build copies in a private key, uses it, and deletes it in a later instruction. The running container shows no key. But anyone who pulls the image can unpack the layer archives individually and read it straight out of the intermediate layer. The deletion protected the merged view and nothing else. This is not a hypothetical; it is one of the most common ways credentials leak from published images.

So what actually removes something? Only never adding it within any layer that ships. Two routes follow from that. First, do the add and the delete inside a single instruction, so the layer produced is the net difference and the archive never appears in any completed layer. Second — and better for anything large — do the work in a separate build stage and copy only the result into the final image, so the heavyweight steps never join the shipped chain at all.

One refinement worth keeping honest. Layers are deduplicated by content hash, so a layer identical to one already present is stored and pulled once. That helps enormously with shared bases and repeated pulls, and it does nothing here: your archive layer is unique to your image, and it has to be stored and pulled the first time regardless.

c

The analogy

THE ANALOGY #
THE FIGURE

Think of a ledger kept in permanent ink, where every entry is a correction to what came before. Write down a large sum, then discover it was wrong. You cannot erase it — you write a second entry cancelling it out. Read the ledger through and the balance is right. But the book has two entries in it now, not zero, and it is physically heavier than a book with neither.

Anyone who wants the balance reads the whole ledger and computes it. Anyone who wants the original mistaken figure just turns to that page.

WHERE IT BREAKS DOWN

an accountant reading the ledger reconstructs the balance by working forward through every entry, whereas a union filesystem does the merge once and then serves the merged view directly, so the running container never pays a per-read cost for the depth of its history — the cost is entirely in storage and transfer, not in speed.

d

Clarifying the model

THE MODEL #

Three clarifications.

First, the misconception: people often reason that image size follows from what the final filesystem contains. It follows from the sum of the layers, which is a different and never-smaller quantity. Once you hold that, a whole family of surprises stops being surprising — why an apt-get update in one instruction and a cleanup in the next saves nothing, why a chmod on a large directory can add nearly as much as the directory itself, since changing a file's metadata rewrites the whole file into the new layer.

Second, layer count and layer size are separate concerns. Merging instructions to reduce the number of layers is mostly cosmetic; merging them so a temporary file never survives an instruction boundary is the part that matters. Optimise for what each layer contains, not for how many there are.

Third, this is not a Docker quirk. The layered, content-addressed format is standardised by the Open Container Initiative image specification, so every registry and runtime behaves this way. Understanding it once transfers everywhere.

e

A picture of it

THE PICTURE #
Layers are diffs
Layers are diffs The bars are what the image weighs -- the sum of every layer produced so far. The line is what the merged filesystem actually contains at that point. They track each other exactly until the final instruction, where the deletion pulls the line down and leaves the bar where it was. The gap between them at the right-hand edge is the archive: gone from the view, still in the image. The figures are illustrative, but the shape is the point, and the shape is that the bar can never come down. {"generator":"mermaid-svg-renderer@3.2.1","source":"../Socrates/.diagram-cache/_src/layers-are-diffs.md","sourceIndex":1,"sourceLine":4,"sourceHash":"d8b6e85ba8a1735cc991c0097840069e63b1c454e964bcdd0afc74a103da2098","diagramType":"xychart","layoutVariant":"source","repairedDuplicateIds":[],"motion":"entrance-with-reduced-motion-fallback","presentation":"editorial","attempt":1,"viewBox":{"x":0,"y":0,"width":790,"height":636},"qa":{"passed":true,"findings":[]}} base download extract delete 700 650 600 550 500 450 400 350 300 250 200 150 100 50 0 Megabytes in the image

How to readThe bars are what the image weighs — the sum of every layer produced so far. The line is what the merged filesystem actually contains at that point. They track each other exactly until the final instruction, where the deletion pulls the line down and leaves the bar where it was. The gap between them at the right-hand edge is the archive: gone from the view, still in the image. The figures are illustrative, but the shape is the point, and the shape is that the bar can never come down.

f

What became clearer

WHAT CLEARED #
WHAT CLEARED

An image is not a filesystem but an ordered stack of immutable difference archives, and a deletion is just another difference that masks what is below it. So subtraction is impossible after the fact: the only way to keep something out of an image is to arrange that no shipped layer ever contained it, which is why the fix is always about where the work happens rather than about cleaning up afterwards.

g

Where to go next

ONWARD #
  • Multi-stage builds, and why copying an artifact forward beats deleting the toolchain.
  • How overlayfs resolves reads across the stack, and what copy-on-write costs at runtime.
  • Scanning published images for credentials left in intermediate layers.
h

Key terms

TERMS #
TermWhat it means
Layera tar archive of the filesystem changes made by one build instruction, identified by the hash of its contents.
Union filesystema driver such as overlayfs that presents a stack of layers as one merged directory tree.
Whiteoutthe marker written into an upper layer to hide a file present in a lower one; in overlayfs, a character device with major and minor number zero.
Content addressingnaming stored data by the hash of the data itself, which lets identical layers be stored and transferred once.
Image manifestthe document listing an image's layers in order along with its configuration.

Every term the collection defines is gathered in the glossary.

Nearby on the shelf

4