Limits and free plan
The console runs on Cloudflare's Workers Free plan, with no card on the account and no paid-plan feature. Each change to it counts what it costs a day against that plan's limits.
This page covers four things:
- what the plan allows, and what the console spends of it
- what happens near a limit, and at 100%
- the limits a person or an app can hit, and the answer they get
- how long each kind of data is kept
Plan
Workers Free, no card
Low queues held from
80% of a limit
Project quota by default
5,000 a day
Daily counts start again
00:00 UTC
Cloudflare's free plan, as the console uses it
The limits are per day unless the row says otherwise. The Usage page counts the four in bold each UTC day, as the Worker sees them.
| Limit | Free plan | What the console spends |
|---|---|---|
Workers requests |
100,000 a day |
The console's own API and the apps' /v1 calls. The pages are static assets: a request for a file is answered without running the Worker, so it costs no Worker request. |
Subrequests |
50 per invocation |
Each queue alarm calls a few targets. Before each call it looks the host up over DNS over HTTPS (A and AAAA, reused within the alarm's batch), so an alarm sends fewer tasks when the lookups would pass 50. The every-minute cron keeps its own budget. Its worst minute holds up to 5 summary mails, about 8 B2 requests for a backup's last step, 10 for a console-wide alert to up to 10 admins and 11 for an expiry warning. With 3 to spare, that leaves 13 for quiet-hours digests. D1 and Durable Object calls do not count against the 50. |
Durable Object requests Not confirmed |
about 100,000 a day |
One object per queue and one per job: task adds, alarms and dispatches. The Queues page asks at most 25 objects per page. One person's reads may make at most 1,000 object requests an hour (24,000 a day at worst, 24%); one API key at most 600 an hour (14,400 a day, 14%). |
Durable Object duration and storage Not confirmed |
about 13,000 GB-s of duration a day; 5 GB stored |
Each queue's waiting tasks and recent finished ones, and its metrics, live in the queue object's own SQLite. A job's object keeps its definition, its runs and, for a check, its results. |
Durable Object rows |
5 M rows read and 100,000 written a day, for the whole account |
The per-person read budget caps one person at 50,000 estimated rows an hour (1.2 M a day at worst, 24%). A filtered or sorted task list reads at most about 1,010 rows; a plain page at most about 410. A busy hour of normal use (30 queue pages, 15 Queues pages and 5 day-long Metrics views) charges about 17,600 rows. |
D1 rows read |
5 M a day |
The pages' lists, the dashboard and the cron's queries. A dashboard load for FlowDeck reads about 25 rows. The cron's heartbeat reads one row a minute (1,440 a day). The queue metrics read nothing from D1. |
D1 rows written |
100,000 a day |
Each task created and each job run writes one row: the project's daily count, for its quota. A run-log row is written for each failed attempt, and for the share of successful ones a queue keeps. The cron's heartbeat writes about 288 rows a day. Every index is one more written row, so only the lists and the cron's every-minute queries have one. One person's changes are capped at 120 an hour: about 17,000 rows a day at worst (17%). |
D1 storage |
5 GB |
People, projects, keys, the audit log, queue and job definitions, and the run logs, which are pruned. |
Cron triggers |
5 per account |
One trigger, every minute. It wakes queues and jobs whose alarm should have fired, prunes old rows and runs the console's own upkeep (Data and architecture lists its parts). |
CPU time |
10 ms per request |
The daily backup dumps a few pages of rows in each cron minute, so no single run does the whole job. |
Workers Logs |
200,000 events a day |
Half the requests are sampled, so a flood cannot use up the day's logs. |
Not confirmed The Durable Object numbers
The project's docs mark the Durable Object figures for requests, duration and storage as not confirmed: they were not checked against Cloudflare's current limits when the console was set up. The code's own note says the same of the four numbers the Usage page counts against. The console treats them as the budget either way.
How the console keeps its spend low
- One cron trigger of the five the account allows. Each part of it runs on its own.
- The pages are static assets, served without running the Worker.
- Queue metrics stay in each queue's object, not in D1. Per-minute rows in D1 would cost 1,440 writes a day for one busy queue.
- The dashboard reads D1 only. It asks no queue or job object, however many there are.
- The Queues page comes 25 queues at a time, because each queue's counts cost one object request.
- Saving a project's alert settings writes D1 only. Each object reads them when it may alert.
- A task keeps at most its last 10 attempts, so a task retried all day holds 10 rows, not hundreds.
- The cron writes its heartbeat only when the row is 5 minutes old, or its failed parts changed: about 288 rows a day instead of 1,440.
Near a limit, and at 100%
Every minute, the cron's usage watch compares the day's counts with the four limits. Each Usage line reads OK, Near the limit or Over the limit.
-
Under 80%The line reads OK. Nothing is held.Queues and jobs run as usual.
-
From 80%: near the limitThe usage watch holds every low-priority queue until the next UTC day. The admins get a usage alert by mail, never a project's channels. It is throttled to one every 10 minutes per metric; the next one says how many were held back.Low-priority queues held until 00:00 UTC. Normal queues go on.
-
At 100%: over the limitEvery queue is held, whatever its priority. The console-wide hold is set: one row in D1, read with the quota check, so it costs no query of its own. The watch tells at most 40 queues a minute.New tasks are refused with 429
quota, on the pages and through/v1. A scheduled job run is skipped and logged asquota; a forced one gets 429quota. -
What still works during the holdSign-in, the pages and the admin routes go on. Every signed-in member sees the usage lines and the hold, so they can tell why their queues were held.A retry the hold leaves no room for is not sent. It stays queued, due at 00:00 UTC.
-
00:00 UTCThe daily counts start again, and the hold ends.Held queues go on; waiting retries are sent.
The project's daily quota
Every project has a daily cap, so one project's API key cannot use up the free plan. Each creation or run costs D1 writes, Durable Object requests and Worker requests.
- 5,000 a UTC day by default, while an admin has set none.
- Set by admins only, on the Usage page: 1 to 1,000,000,
0for no cap, or back to the default. - Counted in D1, per project and per UTC day. The Usage page shows each project's count against its cap, for example "5,000 (the default)".
| What happens | Counts |
|---|---|
A task created, on the pages or through /v1 | 1 |
A file of tasks | 1 per task, all counted at once: when the day has no room for every task, none is made |
A job run, scheduled or forced | 1 |
A task added by a job whose target is a queue | Once, as the run |
Every attempt after a task's first: a retry, an attempt cut off and sent again, Retry failed, Run now on a failed task, a batch run | 1 each, counted by the queue's object a batch at a time |
A copy of a failed task into its dead-letter queue | 1, as a creation |
Run now on a task never tried | Nothing more: its first attempt was counted when it was made |
A create refused for a name the queue remembers | Its unit is given back |
Over the cap, a create gets 429 quota and nothing is added; a forced run gets 429 quota; a scheduled run is skipped and logged as "Skipped (daily quota)". A retry with no unit left waits for the next UTC day, and a dead-letter copy is not made (the original stays in Failed).
FlowDeck's share. FlowDeck's project has no cap of its own, so the default applies. Its ten scheduled jobs run 1,417 times a day (1,418 on Sundays), which leaves about 3,580 for its tasks and their retries. Over the cap, a task gets 429 quota and FlowDeck runs the work itself.
Limits a person or an app can hit
Every refusal is JSON with ok: false and one plain sentence. A field problem is 400 invalid, with a message for each field at its path, shown beside its input. Sign-in limits are on Security and access.
Tasks and calls
| Limit | Number | Answer | Where |
|---|---|---|---|
Request body | 64 KB; 256 KB for a task create or a file of tasks | 413 | Every JSON route, pages and /v1 |
Task body | 100 KB | 400 invalid | Creating a task |
Headers | 50, each at most 8 KB | 400 invalid | Tasks and jobs |
URL | 2,048 characters | 400 invalid | Tasks, jobs and checks |
Task name | 1 to 500 letters, digits, _ and -; left out, the queue makes one | 400 invalid | Creating a task |
A name used again | Refused while the queue remembers it: waiting, running or failed (7 days), and for 24 hours after it succeeded or was deleted | 409 | Per queue |
Schedule ahead | At most 30 days; left out or in the past, it runs now | 400 invalid | A task's scheduleTime |
Attempt deadline | 15 seconds to 15 minutes; 3 minutes when left out | 400 invalid | Tasks and jobs |
An answer from a target | At most 1 MB read; the first 1 KB kept | — | Every attempt |
Attempts kept | The last 10 per task; a job run has at most 6 (the first and 5 retries) | Older ones removed | Run logs |
Daily quota | 5,000 task creations and job runs a day, by default | 429 quota | Each project |
Projects, queues and jobs
| Limit | Number | Answer | Where |
|---|---|---|---|
Queues | 100 per project | 409 | Create a queue, import |
Jobs and checks | 200 per project | 409 | Create a job, import |
Secrets | 200 per project | 409 | Secrets page |
Service accounts | 100 per project | 409 | Secrets page |
API keys | 20 per project that are not revoked; a revoked key stays for the record and does not count | 409 | Keys page |
Job retries | 0 to 5 after the first attempt; backoff 1 second to 24 hours; at most 16 doublings | 400 invalid | Create or edit a job |
Runs at once | Up to 5 with the allow overlap; one waiting run with queue | The next one is skipped and logged | Each job |
Alert addresses | 10 per project | 400 invalid | Alerts page |
A queue's settings
| Setting | Range | Default |
|---|---|---|
Name | 1 to 63 lower-case letters, digits and -, starting with a letter; unique in the project; cannot change | Required |
Max dispatches per second | More than 0, at most 500 | 500 |
Max concurrent dispatches | 1 to 5,000 | 1,000 |
Max attempts | -1 (unlimited) or 1 to 1,000, the first attempt included | 100 |
Max retry duration | At most 30 days; 0s is unlimited | 0s |
Min and max backoff | 0.1 seconds to 24 hours; min at most max | 0.1s and 1h |
Max doublings | 0 to 16 | 16 |
Logging | Failed attempts only, or a sample of successful ones too (1 to 100%) | Failed only |
Priority | Low or normal. Low queues are held first near a free limit. | Normal |
Status codes not retried | 0 to 50 different codes, 300 to 599 | 400, 401, 403, 404, 410, 422 |
Dead-letter queue | Another queue of the project, with no loop back | None |
Every project has a queue named default, which cannot be deleted. Any setting out of range is 400 invalid.
Files
| Limit | Number | Answer | Where |
|---|---|---|---|
A file of tasks | 1 to 50 tasks, 256 KB at most, no name twice; checked whole before anything is made | 400 invalid; 413 over 256 KB | Create a task, From a file (Tasks from a file) |
Its change budget | One change per 10 of its tasks (5 for 50), so one person makes at most 1,200 tasks an hour on the pages | 429 | Create a task, From a file |
Its quota | All its tasks counted at once | 429 quota | Create a task, From a file |
An import file | 256 KB at most | 413 | Export and import |
What one import changes | At most 40 queues and jobs made or changed (each is one Durable Object request), skipped ones included | 409 | Export and import |
What a settings file holds | At most 100 queues, 200 jobs, 100 service accounts and 200 secrets (by name), no name twice | 400 invalid | Export and import |
Exports and imports | 20 an hour per person, dry runs included | 429 rate_limited | Export and import |
Budgets and rate limits
| Limit | Number | Answer | Where |
|---|---|---|---|
Reads of queue and job objects | 50,000 estimated rows an hour per person, across every project, queue and route | 429 | Console pages that read an object: a queue, the Queues page, task lists, Metrics, a task |
Object requests by those reads | 1,000 an hour per person | 429 | The same pages |
Changes | 120 an hour per person. Free: sign out, sign out everywhere, remove a passkey, revoke a key. | 429 | Every signed-in change, admin routes included |
Filtered or sorted task lists | 10 an hour per person; 60 an hour per queue; they look at the queue's newest 500 tasks | 429 | A queue's Tasks tab |
Plain task lists | 120 an hour per person per queue; 240 an hour per queue | 429 | A queue's Tasks tab, its paging and Refresh |
Ticked tasks | 1 to 50 per batch delete or run, in one object request | 400 invalid | A queue's toolbar |
/v1 requests | 600 a minute per API key | 429 | /v1 |
/v1 object requests | 600 an hour per key: task reads, deletes, and creates answered 409 | 429 | /v1 task routes |
Unknown or revoked keys | More than 120 a minute from one address | 429 | /v1 |
Open routes | 120 a minute per address, together | 429 | /health, /.well-known/*, the sign-in options and the start of Google sign-in |
Test alerts | 10 an hour per project | 429 rate_limited | Alerts page |
Back up now | 3 an hour, every attempt counted | 429 rate_limited | Usage page, Backups (admins) |
Maintenance switch | One change every 10 seconds per switch | 429 rate_limited | The pages and /v1 |
The per-person budgets are counted where every isolate sees them, without a D1 write per request. Each isolate counts in memory and adds its count to one D1 row now and then: on the first charged read and every 2,500 rows after, on the first change and every 20 after. That costs at most 21 D1 writes an hour per person per isolate for reads, and 7 for changes.
What is kept, and for how long
| What | Kept | Where |
|---|---|---|
A task's headers and body | Sealed while it waits or runs; dropped once it is done | The queue's object |
Finished tasks (succeeded or deleted) | 24 hours; the name stays taken that long | The queue's object |
Failed tasks | 7 days in the Failed tab, then pruned | The queue's object |
Task attempts | Failed ones always, successful ones as the queue's logging says; at most the last 10 per task; pruned after 7 days | D1 run logs |
Job runs and their attempts | 7 days; every successful job run is kept | D1 run logs |
Queue metrics by the minute | 2 days; a row only for a minute in which something happened | The queue's object |
Queue metrics by the hour | 30 days | The queue's object |
A job's outcomes by the hour | 24 hours, for the dashboard | The job's object |
Uptime check results | The last 100, and hourly counts for 7 days | The check's object |
The audit log | 400 days; the cron deletes up to 500 older lines a minute | D1 |
Rate-limit counts | Until their window has passed (an hour, the longest); up to 500 rows pruned a minute | D1 |
Backups | Object Lock keeps each file 29 days; the bucket's lifecycle rule removes it at 30 | B2 |
D1 Time Travel | 7 days on the free plan; each deploy notes a restore point before it migrates | Cloudflare |
The Worker's logs | A few days, half the requests sampled | Workers Logs |
Cloud Console, as it is on main. 22 Oct 2026.