Sweeper reference

Twenty-three tasks in four groups. Each keeps its own window, each is switched on or off individually, and every one of them scans before it sweeps.

How a sweep works

Press Scan and every selected task reports what it would remove. Press Sweep and they remove it. Both go through the same method with a flag — a task cannot report a preview its execution does not match without the discrepancy being visible in the report.

The order is the order below, and it matters: content first, because deleting an element is what orphans the rows the database tasks then collect; files next; Craft’s own collector last, so one pass picks up everything the rest left behind.

A task that throws does not take the sweep down with it. The failure is recorded against that task and the others carry on — a broken log directory is no reason to abandon the database work.

Configuration

Every task’s settings live in Nuke → Settings → Sweepers. The setting stores overrides only; anything you never touch keeps the default that shipped with the task. That is what lets a task added in a later release arrive switched on with sensible settings rather than sitting silently disabled because it was not in a list written before it existed.

Content

The tasks that create work for everything below.

TaskDefaultWhat it does
trashed
Trashed elements
On
30 days
Permanently deletes elements that have been in the trash longer than the window — your window, not Craft’s single global softDeleteDuration. More usefully, it reports what is in there, broken down by element type, before it goes. Nested elements are counted but left for Craft’s own collector, which knows which ones a revision still depends on.
drafts
Abandoned drafts
On
30 days
Unsaved drafts — the rows Craft creates the moment somebody clicks “New entry” and then closes the tab — and stale provisional (autosave) drafts, which Craft recreates on the next edit. Named drafts somebody deliberately saved are never touched.
revisions
Excess revisions
On
keeps maxRevisions
Craft applies its maxRevisions limit when an element is saved. Lower that setting on an established site and nothing happens to the history already there — for an archive of 40,000 entries, never. This applies it retroactively. Optionally requires a revision to be both surplus and older than a second window.
unusedAssets
Unreferenced assets
On, report only
180 days, 500/run
Assets with no row in relations and no reference tag anywhere in element content. It cannot see an asset referenced only by a URL in raw HTML or hard-coded in a template, so it reports by default and the strongest thing it will ever do is move one to the trash — where a second, separately configured window has to elapse before it is really gone.
emptyFolders
Empty asset folders
Off Folders with no files and no subfolders. Off deliberately: an empty folder is often somewhere an editor was told to upload to, and deleting it is a worse outcome than an untidy tree. Turn it on after a migration. Volume roots are never candidates.

Database

Rows nothing points at any more.

TaskDefaultWhat it does
orphanedRelations
Relations to deleted elements
On
trashed excluded
Craft has no foreign key on relations.targetId, so anything hard-deleted outside its own delete path leaves rows pointing at nothing. Those always go. Relations to elements still in the trash are opt-in — while an element is recoverable, its relations are part of what would be recovered.
searchIndex
Stale search index rows
On searchindex has no foreign key either — it cannot, because it is rewritten constantly. Rows left by a failed delete, a restored database or a hand-run DELETE have nothing to clean them up, and on a big site the index is one of the largest tables there is.
changelog
Draft change tracking
On
180 days
changedattributes and changedfields, which record which parts of an element a draft has touched so merging only overwrites what changed. Written on every autosave. Keep the window comfortably longer than your longest-lived draft.
activity
Element activity
On
30 days
The rows behind the control panel’s “currently editing” indicators. Anything older than a few days answers a question nobody is asking.
deprecations
Deprecation warnings
On
30 days
Craft’s deprecation log, which nothing prunes. Anything still happening is logged again immediately.
queue
Failed queue jobs
On
30 days
Craft removes a job when it succeeds; a failed one stays forever carrying its serialised payload. Waiting and in-progress jobs are never touched, whatever their age.
sessions
Stale login sessions
On
90 days
“Remember me” tokens, on your own window rather than rememberedUserSessionDuration. Deleting a row logs that browser out; it does not delete the user.
tokens
Expired tokens
On Preview, share and password-reset tokens. Swept by expiry, not by age — a token issued a year ago with a ten-year lifetime is still valid.
announcements
Announcements
On
90 days
The “what’s new” notices Craft and plugins post after an update. Stored per user, so fifty editors means fifty copies of each.
assetIndexing
Asset indexing leftovers
On
7 days
One row per file walked, existing only for the duration of an indexing run. A cancelled or crashed session leaves the lot behind.
transformIndex
Orphaned transform records
On Transform index rows whose asset is gone. Rows for live assets are deliberately left alone — removing one would just make Craft regenerate the image while the old file stayed on the volume.
bulkOps
Bulk operation records
On
7 days
The bookkeeping Craft uses to fire deferred handlers once at the end of a bulk operation. Meaningless after the request that wrote it.

Files

Under storage/, where the disk actually fills up.

TaskDefaultWhat it does
backups
Old database backups
On
30 days, keep 5
The directory nothing cleans up. Every db/backup, every pre-update backup Craft takes and every backup Nuke took all land here, each the size of the database. Two conditions and a file must satisfy both: older than the window and outside the newest few — so “delete backups older than 30 days” on a site that has not been backed up in a year does not delete the only backup there is.
logs
Rotated logs
On
30 days
Files in storage/logs, including the ones Craft’s own rotation does not govern — plugin targets, files from an older Craft. The window is never less than a day whatever the setting says: truncating the file the process is currently appending to is a good way to lose the record of what the sweep just did.
temp
Temporary files
On
1 day
Four directories, all of which leak: runtime/temp, abandoned uploads, and the local copies Craft pulls down from remote volumes to work on. All regenerated on demand.
compiled
Compiled templates
On
30 days
Twig writes a PHP file per template per version and removes none of them, so a site deployed weekly for two years has a hundred copies of every template. Keep the window comfortably longer than your deploy interval.
configBackups
Config and Composer backups
On
30 days
config-backups, config-deltas and composer-backups. Each is a snapshot taken before one change — a recovery aid, not an archive.

Craft

TaskDefaultWhat it does
gc
Garbage collection
On
trash not emptied
Runs Craft’s own collector, always last. Craft normally fires it at random on a small percentage of requests, which on a low-traffic site may be days away. There is an option to empty the trash completely, ignoring softDeleteDuration — leave it off unless you mean it.

Adding your own

A sweeper is one class with one method that handles the scan and the sweep together. See extending.