Quick question for your team: when did you last plan the cleanup work?
Not the feature work. The other stuff. Pruning old deployment revisions. Clearing out container images nobody will ever pull again. Checking whether that certificate expires next month. Rotating the credential someone created for a one-off migration in March.
If the honest answer is “we do it when it becomes a problem”, then you are not scheduling maintenance - maintenance is scheduling you. And it always picks the worst possible slot: Saturday morning, mid-release, or the exact hour before a demo.
The debt that accumulates while you ship
Platform debt is sneaky because none of it looks urgent, and all of it grows on its own:
- Deployment revisions accumulate with every deploy. Hundreds of dead versions clutter the console, slow down tooling, and occasionally hit a quota you did not know existed.
- Container images and artifacts pile up in the registry, quietly costing storage every month for versions nobody will ever run again.
- Certificates and credentials march toward expiry with zero fanfare. The most reliable outage in our industry is a certificate that expired at 3 a.m. while everyone slept.
- Idle resources - the dev cluster nobody shut down, the test database that outlived its project - burn money for nothing.
- Backups run on a schedule but nobody checks they completed. An unverified backup is a rumor, not a recovery plan.
Individually, each is a fifteen-minute chore. Collectively, they are the reason your Saturday got ruined.
Why it never gets scheduled
The mechanics are always the same, and they are worth naming because they explain why “we should be more disciplined” never works:
- No owner. Maintenance belongs to the platform, which belongs to everyone, which means nobody.
- No ticket. It never wins prioritization against a feature, because its value is “nothing bad happened” - the hardest outcome to sell.
- Invisible until it explodes. There is no user complaining about unpruned revisions. Right up until the deploy fails.
- It lives in the wrong place. When cleanup scripts live inside product repos, every team re-invents them slightly differently and nobody maintains any of them.
You cannot fix that with discipline. You fix it by taking the work off humans entirely.
The pattern: small, independent, scheduled, least-privileged
The shape that works - and this is the whole point of the article - is deliberately unglamorous. Every chore becomes its own tiny automated unit:
- A script that does exactly one thing.
- A scheduled trigger that runs it on a cadence (daily, weekly, whatever fits).
- Its own least-privilege identity - a revision pruner may delete revisions and nothing else. If a job goes wrong, the damage is bounded by design.
- Living in one platform-maintenance repo, separate from any product. New chores can be added without touching a single product repo, and every team benefits automatically.
That last point is the structural insight. Cleanup code inside product repos becomes five drifting copies (the same DRY problem I wrote about for auth and CI). One cross-project home means one implementation, one review, one place to look when you ask “what runs automatically around here?”
Three jobs worth having tomorrow
If you want to start, these three pay for themselves fastest:
1. The revision pruner. Keep the last N deployment revisions per service, delete the rest. Runs weekly, needs one permission, saves you from quota surprises and console clutter.
# Keep the 10 newest revisions per service, drop the rest
list_revisions "$SERVICE" | sort_by_created_desc | tail -n +11 | while read -r rev; do
delete_revision "$rev" # identity may delete revisions — nothing else
done
2. The artifact pruner. Same idea for images and build artifacts: keep tagged releases and recent builds, expire the rest. Pure cost saving, zero risk when the retention rule is conservative.
3. The expiry watchdog. The highest-value job on this list, because it prevents the outage rather than cleaning up after it. Enumerate certificates, keys, and credentials, compute days-until-expiry, and alert well before - 30 days is the widely used threshold, and it exists so you have room to troubleshoot a renewal that goes sideways.
# Alert at 30 days — buffer for a renewal that does not go smoothly
for secret in $(list_secrets); do
days=$(days_until_expiry "$secret")
[ "$days" -le 30 ] && notify "⚠️ $secret expires in $days days"
done
Notice what that job does not do: it does not rotate anything automatically. It buys you time and a human decision. Automating the alert is safe; automating the rotation of a production credential deserves far more care.
Make the invisible visible
One trap worth avoiding: silent automation erodes trust. If nobody ever sees these jobs run, someone will eventually assume they are broken - or worse, that they are dangerous - and switch them off.
So make them speak. A short weekly summary (“pruned 42 revisions, 19 images, 0 secrets nearing expiry”) turns invisible work into visible value, and doubles as your early warning when a job silently stops running. Log what was dropped, not just that something ran - silent truncation reads as success when it was not.
The dentist and the root canal
Nobody enjoys a dental checkup. It is twenty boring minutes, twice a year, for a problem you do not currently have - which is exactly why it is so easy to skip. And you can skip it for years with no visible consequence at all.
Then one night, without warning, you are in an emergency chair at 11 p.m. facing a root canal - hours of work, real pain, and a bill many times what all those checkups would have cost. The decay did not happen that night. It happened quietly, across all the months when nothing seemed wrong.
Platform maintenance is dental hygiene for your infrastructure. Scheduled, it is boring and cheap: a job runs, prunes a few revisions, mentions a certificate expiring in three weeks, and nobody’s weekend is involved. Unscheduled, it becomes an incident with an audience.
Book the checkups. Automate them so you cannot cancel. Your Saturdays are worth more than the fifteen minutes you saved.