Quota
The free tier includes 10 GiB of file storage and Pro 100 GiB. Past that, Free refuses uploads and Pro bills the difference. Either way you can still read and delete files.
| Item | Free | Pro |
|---|---|---|
| Storage | 10 GiB | 100 GiB included |
| Past the included amount | Uploads refused | $0.015 per GiB-month, until the spending limit |
| Object count | Unlimited | Unlimited |
| Key length | 1024 bytes | 1024 bytes |
| Objects per list page | 100 by default, 1,000 max | Same |
When you exceed the quota
The two plans part here.
On Free, the quota is a wall. At 10 GiB, put and presign(PUT) are refused with 507 quota_exceeded. It never turns into a charge.
On Pro, the quota is a billing line. Uploads keep working past 100 GiB, and what you hold above it is billed as overage. The refusal comes only when the organization's spending limit is reached — see below.
On both plans, only writes are ever blocked.
| Operation | Free, over quota | Pro, over quota | Pro, at the spending limit |
|---|---|---|---|
put | 507 quota_exceeded | Works, billed | 507 quota_exceeded |
presign(PUT) | 507 quota_exceeded | Works, billed | 507 quota_exceeded |
get, head, list, delete, presign(GET) | Still available | Still available | Still available |
Even when storage is full, you need to be able to read and delete files in order to free up space.
try {
await env.storage.put(key, body);
} catch (e) {
if ((e as { status?: number }).status === 507) {
return new Response("Storage is full", { status: 507 });
}
throw e;
}How Pro overage is billed
Storage is a gauge, not a counter, so what is billed is the average amount you held over the month, not the peak and not a sum: the service samples each organization's object bytes once an hour and averages the samples. The part of that average above 100 GiB is billed at $0.015 per GiB-month, rounded down to whole GiB — an organization two bytes over the line is not sent a line item for it.
The price and the included amount use the same unit, GiB (230 bytes), so "100 GiB included, 3 GiB over" reads the way it adds up.
The overage is added to the same monthly total as request and CPU overage, and that total is what the spending limit judges. The limit is on by default at $20 a month above the flat price. When the total reaches it, the organization stops spending until the first of next month: requests are answered 429 budget_exhausted, and uploads are refused with the same 507 quota_exceeded a Free project sees at its quota. Reads and deletes keep working through all of it.
Check your current usage
runlot storage status
runlot storage status --jsonrunlot usageThe File storage tab in the dashboard shows the same values, and states which of the two behaviours above applies to your plan.
Notifications
Both go to the organization's admin, and each kind is sent at most once every 24 hours per project. You can also see them on the organization screen in the dashboard.
| Notification | When |
|---|---|
storage_near_quota | Usage reached 90 % of the quota. Sent on both plans. |
storage_quota_hit | An upload was actually refused with 507. Free only — on Pro a 507 means the spending limit, and the notification for that is budget_exhausted, which names the limit. |