Description
docker system df -v reports incorrect SHARED SIZE and UNIQUE SIZE when using the containerd image store.
For images built FROM another image (e.g. node:22), large portions of shared image content (base image layers) are incorrectly attributed to UNIQUE SIZE, even though they are clearly shared across images.
This leads to significantly inflated UNIQUE SIZE values that do not reflect the actual layer delta introduced by the derived image.
Reproduce
docker pull node:22
# minimal Dockerfile
cat <<EOF > Dockerfile
FROM node:22
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY index.js index.js
CMD ["node", "index.js"]
EOF
docker build -t express_app:v0.0.1 .
docker system df -v
One can see something similar,
REPOSITORY TAG SIZE SHARED SIZE UNIQUE SIZE
express_app v0.0.1 1.64GB 1.216GB 421MB
node 22 1.64GB 1.216GB 424MB
However, express_app only introduces ~10–15MB of new layers (verified via docker history), but UNIQUE SIZE is reported as ~421MB.
Expected behavior
docker system df -v should correctly attribute shared and unique image size based on actual layer and content reuse.
For images built FROM another image:
- Layers and content blobs referenced by multiple images should be counted as
SHARED SIZE
- Only layers and content introduced by the derived image should be counted as
UNIQUE SIZE
For the example above:
node:22 → base image
express_app → node:22 + small application layer (~10–15MB)
The expected output should reflect:
express_app UNIQUE SIZE ≈ size of newly added layers (~10–15MB)
node:22 UNIQUE SIZE ≈ minimal residual (if any)
docker version
Client:
Version: 29.1.3
API version: 1.52
Go version: go1.24.4
Git commit: 29.1.3-0ubuntu3~24.04.1
Built: Fri Mar 6 11:35:12 2026
OS/Arch: linux/amd64
Context: default
Server:
Engine:
Version: 29.1.3
API version: 1.52 (minimum version 1.44)
Go version: go1.24.4
Git commit: 29.1.3-0ubuntu3~24.04.1
Built: Fri Mar 6 11:35:12 2026
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 2.2.1
GitCommit:
runc:
Version: 1.3.4-0ubuntu1~24.04.1
GitCommit:
docker-init:
Version: 0.19.0
GitCommit:
docker info
Client:
Version: 29.1.3
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.30.1
Path: /home/mli/.docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: 2.40.3+ds1-0ubuntu1~24.04.1
Path: /usr/libexec/docker/cli-plugins/docker-compose
trust: Manage trust on Docker images (Docker Inc.)
Version: 29.1.3
Path: /usr/libexec/docker/cli-plugins/docker-trust
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 7
Server Version: 29.1.3
Storage Driver: overlayfs
driver-type: io.containerd.snapshotter.v1
Logging Driver: json-file
Cgroup Driver: systemd
Cgroup Version: 2
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
CDI spec directories:
/etc/cdi
/var/run/cdi
Swarm: inactive
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version:
runc version:
init version:
Security Options:
seccomp
Profile: builtin
cgroupns
Kernel Version: 6.6.87.2-microsoft-standard-WSL2
Operating System: Ubuntu 24.04.4 LTS
OSType: linux
Architecture: x86_64
CPUs: 32
Total Memory: 31.23GiB
Name: DESKTOP-8RCR6T0
ID: 7bf42676-71e1-41b8-a261-8508f0e5706c
Docker Root Dir: /var/lib/docker
Debug Mode: false
Experimental: false
Insecure Registries:
::1/128
127.0.0.0/8
Live Restore Enabled: false
Firewall Backend: iptables
Additional Info
After my current fix, the expected output is
$ docker system df -v
Images space usage:
REPOSITORY TAG IMAGE ID CREATED SIZE SHARED SIZE UNIQUE SIZE CONTAINERS
express_app v0.0.1 69be9ef22b10 2 hours ago 1.64GB 1.624GB 13.15MB 0
node 22 9059d9d7db98 6 days ago 1.64GB 1.624GB 16.18MB 0
I have a working fix for this and can submit a PR if that would be helpful.
Description
docker system df -vreports incorrectSHARED SIZEandUNIQUE SIZEwhen using the containerd image store.For images built
FROManother image (e.g.node:22), large portions of shared image content (base image layers) are incorrectly attributed toUNIQUE SIZE, even though they are clearly shared across images.This leads to significantly inflated
UNIQUE SIZEvalues that do not reflect the actual layer delta introduced by the derived image.Reproduce
One can see something similar,
However,
express_apponly introduces ~10–15MB of new layers (verified viadocker history), butUNIQUE SIZEis reported as ~421MB.Expected behavior
docker system df -vshould correctly attribute shared and unique image size based on actual layer and content reuse.For images built
FROManother image:SHARED SIZEUNIQUE SIZEFor the example above:
The expected output should reflect:
docker version
Client: Version: 29.1.3 API version: 1.52 Go version: go1.24.4 Git commit: 29.1.3-0ubuntu3~24.04.1 Built: Fri Mar 6 11:35:12 2026 OS/Arch: linux/amd64 Context: default Server: Engine: Version: 29.1.3 API version: 1.52 (minimum version 1.44) Go version: go1.24.4 Git commit: 29.1.3-0ubuntu3~24.04.1 Built: Fri Mar 6 11:35:12 2026 OS/Arch: linux/amd64 Experimental: false containerd: Version: 2.2.1 GitCommit: runc: Version: 1.3.4-0ubuntu1~24.04.1 GitCommit: docker-init: Version: 0.19.0 GitCommit:docker info
Additional Info
After my current fix, the expected output is
I have a working fix for this and can submit a PR if that would be helpful.