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.
| Task | Default | What it does |
|---|---|---|
trashedTrashed 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. |
draftsAbandoned 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. |
revisionsExcess 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. |
unusedAssetsUnreferenced 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. |
emptyFoldersEmpty 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.
| Task | Default | What it does |
|---|---|---|
orphanedRelationsRelations 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. |
searchIndexStale 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. |
changelogDraft 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. |
activityElement 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. |
deprecationsDeprecation warnings |
On 30 days |
Craft’s deprecation log, which nothing prunes. Anything still happening is logged again immediately. |
queueFailed 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. |
sessionsStale 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. |
tokensExpired 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. |
announcementsAnnouncements |
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. |
assetIndexingAsset 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. |
transformIndexOrphaned 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. |
bulkOpsBulk 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.
| Task | Default | What it does |
|---|---|---|
backupsOld 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. |
logsRotated 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. |
tempTemporary 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. |
compiledCompiled 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. |
configBackupsConfig 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
| Task | Default | What it does |
|---|---|---|
gcGarbage 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.