Docuum: LRU eviction of Docker images, because creation time is the wrong signal
Least recently used (LRU) eviction of Docker images. 🗑️
At a glance
- What is it?
- Docuum is a small Rust daemon that keeps Docker image disk usage under a threshold by deleting the least recently used images, learning usage from docker system events. It is a fit for CI workers and laptops, and it deliberately leaves BuildKit's build cache to Docker's own garbage collector.
- Who is it for?
- Adopt Docuum on a CI worker, a developer laptop or a Kubernetes node where Docker images accumulate and a large part of them are pulled repeatedly, because eviction by last use protects images that are expensive to rebuild. Do not adopt it as a BuildKit cache cleaner, since the documentation states Docuum does not vacuum the build cache and that both mechanisms are meant to run side by side, and do not reach for it on a host with no Docker event stream.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why image creation time is the wrong eviction signal
Docker ships a command that appears to do this job. The documentation of Docuum names it directly: docker image prune --all --filter until=…, which removes images based on how old they are. The complaint is specific and correct. That filter uses the image creation time rather than the last usage time, so an image that is old but built every morning by a pipeline is treated as stale, and a frequently used image can be deleted even though rebuilding it is expensive or pulling it takes minutes. That failure mode is quiet, because the disk frees up exactly as intended and the cost shows up later as a slow build. Docuum exists to flip the signal. Its stated purpose is least recently used eviction of Docker images to keep disk usage below a given threshold, and the documentation names the environments it suits: continuous integration workers, developer workstations, and any other place where images pile up on disk over time.
Recovering a last-used time from the Docker event stream
The obstacle is that Docker does not record when an image was last used, and the project documentation links the upstream issue where that limitation is discussed. Docuum works around it rather than waiting for Docker to change. It listens for notifications via docker system events, so every time an image is used the daemon learns about it, and it maintains a small piece of state in a local data directory to remember the usage timestamps. The location of that directory depends on the platform and follows the convention the project links to for local application data. The state file is what makes restarts cheap: you can restart Docuum, or reboot the whole machine, without losing the record of when each image was last touched. Eviction then happens when Docuum first starts and again whenever a new Docker event arrives, running until the total disk usage from Docker images falls below the threshold you set.
Threshold, keep, min-age and the deletion chunk size
Four flags shape the behaviour, and the usage text printed by the binary is short enough to read in full:
Usage: docuum [OPTIONS]
Options:
-v, --version
Print version
-t, --threshold <THRESHOLD>
Set the maximum amount of space to use for Docker images [default: "10 GB"]
-k, --keep <REGEX>
Prevent deletion of images for which repository:tag matches <REGEX>
-d, --deletion-chunk-size <DELETION CHUNK SIZE>
Remove the specified quantity of images at a time [default: 1]
-m, --min-age <MIN AGE>
Set the minimum age of images to consider for deletion
-h, --help
Print helpThe threshold accepts several representations, with 10 GB, 10 GiB and 10GB all valid, and on Linux a percentage form such as 50% is also supported, which is the setting you want when the machine has several disks and a fixed number is the wrong unit. The keep flag takes a regular expression matched against repository:tag, which is how you protect a base image or a release tag that your pipeline depends on. The min-age flag accepts durations such as 4d or 1 hour and acts as a second guard: an image that is not used but was created minutes ago is left alone. The chunk size controls how many images are removed per pass, which matters on a machine where a single delete of a very large image is slow.
Installing on macOS or Linux and running the first pass
Installation is one command on macOS and on Linux for both AArch64 and x86-64:
curl https://raw.githubusercontent.com/stepchowfun/docuum/main/install.sh -LSfs | shThe same command run again updates to the latest version, which matters because there is no package manager entry to run. The script honours two environment variables: VERSION, which defaults to the latest version, and PREFIX, which defaults to /usr/local/bin. To install into the working directory instead, set the prefix explicitly:
curl https://raw.githubusercontent.com/stepchowfun/docuum/main/install.sh -LSfs | PREFIX=. shIf you would rather not pipe a script into a shell, the documentation describes the manual route: download the binary from the latest release, make it executable with chmod, and place it somewhere on your PATH. Running the daemon by hand looks like this:
docuum --threshold '10 GB'After that the process listens for Docker events, and you stop it with Ctrl and C held together. Log verbosity is set through an environment variable named LOG_LEVEL, which accepts trace, debug, info, warning or error, and the default is debug.
Windows installs and the daemon configuration you will need anyway
Windows has no script, so the steps are manual: download the binary from the latest release, rename it to docuum, or docuum.exe if file extensions are visible, create a directory called Docuum inside your %PROGRAMFILES% directory, and put the renamed binary there. The last part of the Windows instructions concerns the Advanced tab of the System Properties section of the Control Panel, where the environment variables are edited so the directory ends up on PATH. Whichever platform you use, running the binary as a service is the intended deployment, because eviction has to happen continuously rather than when someone remembers to type a command. The documentation points at launchd and systemd for that, and the repository carries a service_configs directory with the files for it. The project's own container image shows the intended container shape, which is a two stage build on alpine with the Docker CLI added and the binary as the entry point:
FROM --platform=$TARGETPLATFORM alpine:3.23.4
RUN apk add --no-cache docker-cli
COPY --from=build /usr/local/bin/docuum /usr/local/bin/docuum
ENTRYPOINT ["/usr/local/bin/docuum"]The comment in that file is a warning worth reading: Docuum is not intended to be run as an init process, so you should pass --init to docker container run.
BuildKit's cache is a separate pool that Docuum leaves alone
Here is the limitation that catches people out. Before BuildKit, Docker created an intermediate image for each step in a Dockerfile, and Docuum would vacuum those along with everything else. Since BuildKit arrived, Docker no longer produces those intermediate images and instead keeps a separate build cache, and BuildKit ships its own garbage collector for it with a default threshold of 10% of the total disk capacity. Docuum does not vacuum that cache, and BuildKit's collector does not vacuum images. The documentation is explicit that the two are meant to be used together, which is a sensible division: one manages images by last use, the other manages build cache by its own rules. But it does mean that a machine with an enormous build cache will not be rescued by raising the Docuum threshold, and it means the two thresholds have to be set independently if you want the total disk picture under control.
Against TTL pruning, and what the licence and release line say
The alternative approach is the time to live scheme that other tools in the Docker ecosystem use, including Docker's own until filter. The difference in approach is where the signal comes from. A TTL tool asks how old an image is and deletes on a schedule, so someone has to pick an interval and tune it, and the age of an image says nothing about whether it will be needed today. Docuum instead asks what was used recently, evicts immediately whenever disk usage exceeds the threshold rather than waiting for a timer, and uses no CPU resources when there is no Docker activity, which is what lets it sit on a laptop without draining the battery. It also respects the parent and child relationships between images, deleting the children of a parent before the parent itself even if the children were used more recently, because Docker does not allow an image with children to be deleted. On the practical side, the documentation states that Docuum is used by Netflix on its production Kubernetes nodes and by Airbnb on a CI fleet of more than 1.5k workers, and it calls out compatibility with Toast and Docker Compose. The licence is where you need to read carefully: the package manifest declares MIT, while the repository ships its own LICENSE.md with terms that GitHub does not classify, so check that file against your organisation's requirements rather than relying on the manifest. The project is not archived and the last push was on 2026-10-18, with recent releases v0.27.1 on 2026-09-02, v0.27.0 on 2026-04-06 and v0.26.1 on 2026-03-07, and the Rust source is on edition 2024 with clippy lints denied at the project level.
Editorial conclusion
Adopt Docuum on a CI worker, a developer laptop or a Kubernetes node where Docker images accumulate and a large part of them are pulled repeatedly, because eviction by last use protects images that are expensive to rebuild. Do not adopt it as a BuildKit cache cleaner, since the documentation states Docuum does not vacuum the build cache and that both mechanisms are meant to run side by side, and do not reach for it on a host with no Docker event stream. Before you deploy it as a service, check the daemon instructions in service_configs, decide whether the custom LICENSE.md terms are acceptable to your organisation, and note that the Cargo manifest declares MIT while the repository carries its own licence file.
Frequently asked questions
What does Docuum do?
It performs least recently used eviction of Docker images to keep the total disk usage from images below a threshold. Instead of using image creation time, like docker image prune --all --filter until=…, it learns when an image was last used by listening to docker system events.
How do I install Docuum on macOS or Linux?
Run the installation script from the command line, which also updates an existing installation when run again. The script accepts a VERSION environment variable and a PREFIX environment variable that defaults to /usr/local/bin, and you can instead download the binary from the latest release and put it on your PATH.
Can Docuum clean up Docker's BuildKit cache?
No. The documentation states that Docuum does not vacuum BuildKit's build cache, that BuildKit has its own garbage collector with a default threshold of 10% of total disk capacity, and that both tools can be used together.
Which images does Docuum refuse to delete?
The --keep flag takes a regular expression matched against repository:tag, so matching images are protected from deletion. The --min-age flag adds a second guard, setting the minimum age of images to consider for deletion, with durations such as 4d or 1 hour.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/stepchowfun-docuum)Was this useful?