Version 1.5.0
July 18, 2026
Added
- Added a Relation batch size setting so you can lower how many assets each relation scan queue execution loads on sites with heavy or deeply nested relations. Overridable via
relationBatchSizeinconfig/asset-cleaner.phpor theASSET_CLEANER_RELATION_BATCH_SIZEenvironment variable. - Added a Relation time budget setting that stops and re-queues a relation scan execution once a wall-clock budget is reached, keeping each execution under the queue's time-to-reserve (TTR). Overridable via
relationTimeBudgetSecondsinconfig/asset-cleaner.phpor theASSET_CLEANER_RELATION_TIME_BUDGETenvironment variable.
Changed
- Relation usage verdicts and entry lookups are now cached for the duration of a queue execution instead of a single chunk, so repeated relation sources and shared owners in nested-element chains (Matrix, CKEditor) are only resolved once. This significantly reduces database queries on relation-heavy sites.
- Relation sources are now resolved in bulk: entry sources are classified, loaded, and policy-checked with a handful of set-based queries per batch instead of several queries per source, reducing scan queries by orders of magnitude on relation-heavy sites. Disable with
bulkRelationResolution => falseinconfig/asset-cleaner.phporASSET_CLEANER_BULK_RELATION_RESOLUTION=falseto fall back to per-source resolution. Verify parity on an install withphp craft asset-cleaner/diagnostics/relation-parity.
Fixed
- Time-bounded the relation scan stage so a single queue execution stops and re-queues before hitting the worker timeout, fixing
ScanRelationsJobfailures with "exceeded the timeout of 300 seconds" on large or heavily related asset libraries. - Multi-site content is now fully scanned. Content scanning (entries and global sets) previously only inspected the primary site's field content, so an asset referenced only in another site's CKEditor/Redactor content could be wrongly reported as unused. All content queries now cover every site.
- Provisional drafts now count as usage for every user. When "include drafts" is enabled, scans previously only counted provisional drafts belonging to the user who started the scan, so assets referenced in other editors' work-in-progress could be wrongly reported as unused. The per-user filter has been removed from scans and the usage inspector.
Version 1.4.1
June 8, 2026
Changed
- Renamed the Composer package to
yannkost/craft-asset-cleaner. No functional changes.
Version 1.4.0
April 16, 2026
Added
- Added a new Select All checkbox to the Asset Cleaner utility so you can quickly select or deselect all volumes before scanning.
Version 1.3.2
April 5, 2026
Changed
- Improved the asset usage modal so draft and revision usage can be identified directly from the displayed entry links
- Renamed user photo usage labels in the usage modal to "User profile picture" for clearer presentation
Fixed
- Split large relation scans into resumable queue batches so high-volume scans are less likely to exceed worker timeouts
- Hardened relation scan progress tracking so stale queued relation batches are less likely to overwrite later-stage scan state
- Fixed the scan progress display so the asset counter advances during long-running scans instead of remaining at
0 - Counted asset references from the
users.photoIdcolumn as usage during scans and usage checks
Version 1.3.1
April 4, 2026
Changed
- Split
AssetUsageServiceinto focused collaborators for entry usage resolution, relation usage resolution, and content usage scanning while preserving the existing public plugin service API - Standardized plugin logging so operational warnings remain useful without flooding the dedicated log with temporary relation-resolution investigation traces
- Reduced scan lookup memory usage during content scans
Fixed
- Fixed relation fallback usage checks so draft-only and revision-only relation sources no longer count as usage when those inclusion options are disabled
- Fixed relation fallback handling to ignore trashed relation sources instead of treating them as generic usage
- Fixed relation source resolution across sites and owner states for relation-backed asset usage checks
- Fixed invalid field handle warnings during content usage checks by only reading HTML-capable fields from the concrete element field layout context
- Hardened content field layout discovery so problematic layouts fail safely with warnings instead of breaking scans
Version 1.3.0
April 3, 2026
Added
- Added configurable scan workspace path support via the
ASSET_CLEANER_SCAN_PATHenvironment variable orscanWorkspacePathinconfig/asset-cleaner.php - Added a database-backed scan storage mode for containerized, cloud-style, and multi-worker environments where shared filesystem access is not guaranteed
- Added plugin settings for selecting the scan storage mode and configuring the file-based scan workspace path
- Added default settings for whether draft-only and revision-only asset references should count as used
- Added per-scan utility toggles for including drafts and revisions without changing the global defaults
- Added a per-scan relational fallback option that treats any row in Craft’s relations table as usage, helping preserve assets referenced by plugin-defined or otherwise unknown element types
- Added a configurable asset usage dialog on the asset edit page so draft, revision, and relational fallback behavior can be checked before reviewing usage results
- Added updated translations for the new scan and usage options
Changed
- Refactored scan persistence into storage backends so the scan coordinator can run against either file-based or database-based storage
- Batched content entry processing during scans to avoid materializing all candidate entries in memory at once
- Hardened scan workspace file writes with stricter validation, readability checks, and better failure handling
- Retained only the latest scan for restore/export workflows while allowing stale queued jobs to exit quietly if their scan has been replaced
- Made draft and revision handling explicit in scan behavior so installations can choose between canonical/live-oriented cleanup and editorial-history-aware cleanup
- Defaulted scans to the safer relational fallback mode while still allowing stricter relation resolution when needed
- Updated the utility and usage UI to expose the new scan-safety controls more clearly
Fixed
- Added path-aware diagnostics when scan metadata files are missing or unreadable, including resolved storage context details to help debug container and shared-storage setups
- Improved support for container-based installs by allowing scan state to be stored in the database instead of relying on shared local storage
Version 1.2.1
March 31, 2026
Fixed
- Replaced the cache-backed asset scan flow with a file-backed staged scan pipeline stored under
@storage/asset-cleaner/scans/<scanId> - Fixed large scans failing when the cached content index expired before the queue finished processing
- Removed the need to pass the full asset ID list through each queued batch job
Changed
- Split background scans into dedicated setup, relations, content, and finalize queue stages
- Snapshotted assets into chunk files and resolved usage from relations and content in one pass per scan
- Updated scan progress reporting to reflect the current scan stage
- Restored legacy CSV path formatting for unused asset exports
Version 1.0.1
February 7, 2026
Added
- Plugin icon with broom and dust particles for control panel and plugin store
- Custom Logger helper class for dedicated error logging to
storage/logs/asset-cleaner_YYYY-MM-DD.log - Comprehensive error handling with try/catch blocks in all controller actions
- Translation support for 20 languages: Arabic, Bulgarian, Czech, German, English, Spanish, French, Hungarian, Italian, Japanese, Korean, Dutch, Polish, Portuguese, Romanian, Russian, Slovak, Turkish, Ukrainian, and Chinese
Changed
- Updated utility icon to use custom SVG icon
Version 1.0.0
February 7, 2026
Added
- Initial release
- Scan assets across multiple volumes to identify unused assets
- Per-volume results display with separate tables
- Bulk actions: Download CSV, Download ZIP, Move to Trash, Delete Permanently
- ZIP download with folder structure preservation option
- Memory-efficient ZIP creation for large files using chunked processing
- Smart filename generation with snake_case sanitization and timestamps
- Progress bar for scanning operations
- "View Usage" button on asset edit pages showing where assets are used
- Soft delete (trash) and permanent delete options with confirmation dialogs
- Asset usage detection in entry relations and content fields
- Support for Craft CMS 5.0+