Unexpectedly high storage usage
How SupaHost measures file storage, why usage can be higher than you expect (branches, originals, leftovers, other projects), and SQL to find which buckets and files use the space.
File storage on SupaHost is measured on disk: it's the total size of each project's storage folder on your instance, added up across all projects. The quota is shared by every project on the instance, so the place to start is finding which project and bucket uses the space.
What you see
A usage alert email for file storage, or the file storage tile in Usage & billing is higher than your app's files should need.
Why it happens
Common reasons, from most to least frequent:
- Another project on the instance. The quota (100 GB on Builder, 250 GB on Pro, 500 GB on Business) covers every project, including test projects you forgot.
- Branches with data. A branch created with "Copy data, users and files" gets a full copy of the parent's files, and those count again.
- Original uploads plus resized copies. There are no image transformations on SupaHost, so apps often store an original and several sizes of every image.
- Old versions you replaced by uploading under new names and never deleted.
- Files whose database records are gone. Your app deleted a row in its own table but not the file it pointed to.
How to fix it
Measure each bucket in the project's SQL editor.
metadata->>'size'is the file size in bytes:select bucket_id, count(*) as files, pg_size_pretty(sum((metadata->>'size')::bigint)) as total from storage.objects group by bucket_id order by sum((metadata->>'size')::bigint) desc nulls last;Run it in each project; the instance total is the sum.
Find the largest files:
select bucket_id, name, pg_size_pretty((metadata->>'size')::bigint) as size, created_at from storage.objects order by (metadata->>'size')::bigint desc nulls last limit 50;Find files nothing points to. For a recipe app that stores
photo_pathonrecipes:select o.name, pg_size_pretty((o.metadata->>'size')::bigint) as size from storage.objects o left join public.recipes r on r.photo_path = o.name where o.bucket_id = 'recipe-photos' and r.id is null and o.created_at < now() - interval '1 day';Delete through the Storage API, not SQL. Storage blocks direct deletes from
storage.objects, because the file on disk would be left behind. From a server:const { error } = await supabaseAdmin.storage.from('recipe-photos').remove(pathsToDelete)Clean up branches and test projects you no longer need: remove their files through the API first, then delete the branch or project.
Store less. Resize images before upload, and keep only the sizes you actually display.
On SupaHost
- The total under Usage & billing is the size on disk of each project's storage folder. The SQL above adds up the sizes recorded in
storage.objects, so the two can differ a little. Database size is measured and billed separately. - Usage alerts fire once per level per month, at the threshold you choose (80%, 90% or 100%) and at 100%. Usage alerts are one of the email notifications in your account Settings, and can be turned off there.
- File storage above the quota is billed as overage at $0.021 per GB. If you'll stay above it, add 50 GB for $1.05 a month under Usage & billing → Add-ons.
- Storage files aren't part of the daily database backups. Before a big clean-up, download a copy from the Backups tab with "Package files".