I recently had a client whose ImageSharp image cache was over four times the size of their actual media, and it had quietly pushed their Umbraco Cloud site past its storage limit. If you run an Umbraco site with a reasonable amount of media, the same thing is probably happening to you right now. The ImageSharp image cache never cleans itself up. On Umbraco Cloud that cache counts towards your media storage limit, and on self hosted sites it slowly eats disk. I built Umbraco.Community.ImageSharp.TrimCache to solve exactly that, and it is free on NuGet and the Umbraco Marketplace.
What is ImageSharp TrimCache?
It is a small Umbraco package that trims the ImageSharp.Web image cache by age, on a schedule, in the background. It supports both the local physical cache and the Azure Blob cache, and it runs on Umbraco 13, 17 and 18.
There is nothing to wire up. Install the package and a hosted service starts trimming old cached image variants automatically.
Why you need it
Every time a request resizes or crops an image, ImageSharp.Web caches the generated variant so it does not have to do the work again. That is great for performance, but the cache is never cleared automatically. Over time it accumulates thousands of variants for sizes and crops that may never be requested again.
On a self hosted site this is wasted disk space. On Umbraco Cloud, where the cache lives in blob storage, it counts towards your plan's media storage limit and can push you over it. Either way, you end up manually clearing folders or containers, which is exactly the kind of maintenance job that should be automatic.
A real example from a client site
I had a client on the Umbraco Cloud Starter plan, which includes 5 GB of media storage. Their actual media was only around 1 GB, but the ImageSharp cache had grown to roughly 4.5 GB of resized variants. Together that pushed them over the 5 GB limit, even though most of those cached files were old and rarely requested again.
The fix was straightforward: keep the cache trimmed so older cached files are cleared out regularly, before they pile up and grow the cache past the plan limit. That kept the site comfortably under 5 GB without deleting a single piece of real media. The package works the same whether the cache sits on local disk or in Azure Blob storage, which is what Umbraco Cloud uses, so one package covers both self hosted sites and Umbraco Cloud.
How it works
The package registers a background hosted service. On a schedule it scans the ImageSharp cache and deletes any variant older than a configurable age, then the empty folders left behind are pruned too.
Deleting a cached variant is safe. It is disposable derived output, not source media. If a deleted variant is requested again, ImageSharp simply regenerates it from the original image on the next request. A cache miss, not data loss. Because of that, an age based trim does not need to work out which variants are still in use, which keeps it simple and predictable.
Getting started
Add the package to an existing Umbraco site:
dotnet add package Umbraco.Community.ImageSharp.TrimCacheBy default it trims the local ImageSharp cache folder, removing variants older than 30 days once a day. That is all most sites need.
Configuring the trim
Everything is optional and configured under an ImageCacheTrim section in appsettings.json:
"ImageCacheTrim": {
"Enabled": true,
"Mode": "Auto",
"MaxAgeDays": 30,
"IntervalMinutes": 1440
}Mode is Auto by default, which uses Azure when blob storage is configured and the local cache otherwise. You can force Local or Azure if you prefer. MaxAgeDays controls how aggressive the trim is, and IntervalMinutes controls how often it runs.
Azure Blob and Umbraco Cloud
For blob backed sites, point the trimmer at the container your ImageSharp cache writes to, using an account connection string or a connection string that carries a SAS. The SAS form is how Umbraco Cloud exposes its storage.
The one setting to get right here is Prefix. On Umbraco Cloud the image cache often lives in the same container as your media, so you set Prefix to the cache subfolder (for example cache/) to make sure the trimmer only ever touches cached variants and never your media. The full setup, including how to convert a SAS URL into the connection string, is in the project README.
Why it is safe?
The trimmer only scans the cache location you configure. Source media is a separate concern, and with a prefix set on Azure the trim is scoped to the cache folder inside the container. Deletes are age based, idempotent and fail tolerant, so a locked or missing file is simply retried on the next run rather than crashing anything. In a load balanced setup it does the right thing automatically, running on every server for a per server local cache and on a single server for a shared blob cache.
Where to get it?
Umbraco.Community.ImageSharp.TrimCache is open source and MIT licensed.
NuGet:
dotnet add package Umbraco.Community.ImageSharp.TrimCacheGitHub: https://github.com/justin-nevitech/Umbraco.Community.ImageSharp.TrimCache
If it saves you a disk cleanup or keeps you under your Umbraco Cloud storage limit, it has done its job. Issues and contributions are welcome.