Limits
Per-workspace quotas by plan, and what happens when you reach one.
View as MarkdownLimits bound how much of the product a workspace uses. They are separate from pricing, which bounds what it costs.
The table
| Resource | Trial | Paid |
|---|---|---|
| Workers per workspace | 1 | 10 |
| Backups per workspace | 5 | 100 |
| API keys per workspace | 2 | 20 |
| Members per workspace | 1 | 25 |
| Destinations per workspace | 1 | 25 |
| Connections per workspace | 1 | 25 |
| Total stored | 20 GiB | unlimited |
| One artifact | 5 GiB | unlimited |
| Retention window | 7 days | unlimited |
| Workspaces per user | 5 | 5 |
Read the live values rather than trusting this page:
curl -fsS "https://api.saved.sh/v1/workspaces/$WID/quotas" -H "Authorization: Bearer $TOKEN"In that response, a limit of 0 means unlimited, not zero.
Limits are not prices
Nothing in this table is a revenue line. Each cap exists for a reason that is not billing:
| Cap | Why |
|---|---|
| Members | Blast radius. Permissions are workspace-wide, so every member sees every backup |
| Workers, API keys | Credential sprawl is a security problem before it is a cost one |
| Destinations, connections | Each is a long-lived credential we hold on your behalf |
| Storage, on trial | An unpaid workspace should not be able to store unbounded data |
A workspace of twenty pays the same as a workspace of one for the same usage.
Two kinds of limit, two kinds of failure
Counting limits are checked before anything is created, so a refused call creates nothing:
{ "error": { "code": "quota_exceeded", "message": "this workspace already has 5 backups" } }Size limits cannot be checked in advance, because nothing about a request knows how large a dump will be. They bind during a run and fail the run, not the API call.
A trial workspace backing up a database larger than 5 GiB compressed will configure the backup successfully and then watch it fail at 02:00. Watch usage against the limit rather than waiting to find out.
The retention cap is the one to plan around
Trial caps the retention window at 7 days, and retention is write-once.
A backup created on trial keeps its 7-day policy even after you upgrade. Upgrading lifts the cap for new backups; it cannot loosen an existing one, because retention cannot be edited at all. If you intend a 90-day retention, set it on a paid plan, or plan to recreate the backup.
This is the single most common thing to get wrong while evaluating. If you are trialling with backups you intend to keep, either upgrade before creating them, or accept that you will recreate them later.
What is not limited
| Not limited | |
|---|---|
| Runs per day | Trigger as often as your source allows |
| Concurrent runs | Bounded by your worker and your source, not by us |
| Schedule frequency | No minimum interval is enforced |
| Downloads and reads | Never gated, in any state |
| API calls | No rate limit today |
The absence of a run-rate limit is not an invitation. A run costs computation and produces an artifact that costs archive, so an over-frequent schedule is bounded by your bill rather than by a quota.
Reaching a limit
curl -fsS "https://api.saved.sh/v1/workspaces/$WID/quotas" -H "Authorization: Bearer $TOKEN" \
| jq -r '.quotas[] | select(.limit != 0 and .used != null and .used >= .limit)
| "at limit: \(.resource) \(.used)/\(.limit)"'Worth running before applying a manifest that creates several backups, which otherwise fails partway through with some created and some not.
To raise one: upgrade from trial, which lifts every counting limit and removes the storage and retention caps. Beyond the paid defaults, ask.
Billing state also gates writes
Separately from quotas, an unpaid workspace stops doing new work.
| State | New runs | Config changes | Reads and downloads |
|---|---|---|---|
trial, active, warned | Yes | Yes | Yes |
stopped | No | Yes | Yes |
blocked | No | No | Yes |
Reads and downloads are never gated in any state.