Images & Layer Sharing
18 min
A Docker image isn't one monolithic file — it's a stack of layers,
each identified by a content hash. Layers are stored once and shared
across every image that happens to use them: two images both built
FROM python:3.12 share that exact base layer on disk. Pulling a new
image only needs to download layers that AREN'T already present
locally — which is why a second, related image often pulls in seconds
instead of minutes.
def download_size(image_layers, already_pulled):
return sum(size for layer_id, size in image_layers if layer_id not in already_pulled)
This is exactly why official language images (python, node, etc.) are worth standardizing on across a team's projects -- every image built FROM the same base tag shares that base layer locally, so pulling your tenth project's image barely costs anything beyond its own small application layer.
Write `download_size(image_layers, already_pulled)`: `image_layers` is a list of `(layer_id, size_bytes)` pairs making up an image. Return the total bytes that would ACTUALLY need downloading — the sum of every layer's size, skipping any `layer_id` already present in `already_pulled`.
Why does pulling a second Docker image on the same machine often download far less data than the image's total size would suggest?
You can compute the actual incremental download size of an image given already-cached layers, and understand why Docker's layer-sharing model makes related images cheap to pull.