Retention
How the registry's nightly retention sweep and weekly garbage collection decide which images and cache entries to remove, and the settings behind them.
Two jobs keep the registry from growing without bound: the Registry module's retention sweep, which decides which images of apps and functions to delete, and a weekly garbage collection, which frees the storage that deleted and outdated content leaves behind.
The retention sweep
The sweep runs every night at 03:00 UTC. It works from the registry's audit log: every repository that has received a push is a candidate, and every distinct image pushed to it is either kept or deleted. It keeps an image when any of these holds:
- It is in use. The platform's operator reports, for every app and function, the images its running pods use — a pin. It reports again after every successful reconcile of the app or function, also when no pod runs, and each report expires after an hour.
- It is among the last few pushed — two by default.
- It was pushed recently — within the last 90 days by default.
An app can override the last two numbers with retention.keepLast and retention.keepForDays on
the app. A repository with no unexpired report is skipped with the reason no-pin-data: the sweep
cannot prove its images are unused, so it deletes nothing there. That covers static web app
repositories, which get no pins, and the repositories of deleted apps and functions, whose last
report expires an hour after deletion — the sweep never deletes their images. An app or function
whose reconciles have been failing for more than an hour is skipped the same way.
Each deletion is recorded in the audit log as delete, with status 202, or 500 when the
deletion failed. In a dry run the sweep deletes nothing and records delete.dryrun, with
status 0, for each image it would have deleted.
Important
In this version the sweep finds no pushed images to consider: every run reports
0images seen and deletes nothing, and a preview returns empty lists. Until that changes, registry storage is freed only by the garbage collection below.
Garbage collection
The CronJob stackship-registry-gc in stackship-system runs every Sunday at 04:00 UTC,
after the sweep. It:
- switches the registry to read-only;
- removes build-cache entries that have not been rebuilt for 14 days;
- runs the registry's garbage collection, which deletes untagged images and frees the storage no image refers to any more;
- switches the registry back to read-write.
While it runs, pushes fail, so a build that finishes in that window fails and has to be started again. Each switch restarts the registry, and while it restarts pulls fail too: a pod that starts in that moment retries its image pull. If the job misses its start time by more than ten minutes, it skips that week.
Settings
The sweep reads its settings from the environment of the module-registry deployment.
| Setting | Default | Meaning |
|---|---|---|
Registry__Retention__Enabled |
true |
Whether the nightly sweep runs at all |
Registry__Retention__DryRun |
true; the installer sets false |
Record what would be deleted instead of deleting it |
Registry__Retention__SweepCron |
0 0 3 * * * |
When the sweep runs: a six-field cron expression with seconds, in UTC |
Registry__Retention__DefaultKeepLast |
2 |
How many of the most recently pushed images to keep |
Registry__Retention__DefaultKeepForDays |
90 |
Keep every image pushed within this many days |
Registry__AuditRetentionDays |
90 |
How many days audit events are kept; 0 deletes every event at each daily clean-up |
The sweep only knows the pushes that are still in the audit log, so an image whose push has aged out of the log is never deleted by it.
To look at past runs, preview a repository or start a run yourself, see Retention runs.