Limits & Concurrency
Your plan controls how many PDFs you can render at once, how large requests and outputs can be, how long a render may run, and whether JavaScript and internet access are enabled. Understanding these limits explains most render rejections and failures.
Plan names, prices, and limits can change. The values below reflect the current plan catalog — the authoritative limits for your workspace are always shown in the dashboard and on the pricing page.
Plan limits at a glance
| Limit | Free | Starter | Growth | Scale |
|---|---|---|---|---|
| Concurrency | 1 | 1 | 3 | 8 |
| Queue depth | 5 | 25 | 100 | 300 |
| Monthly generations | 200 | Unlimited | Unlimited | Unlimited |
| Max request payload | 1 MB | 5 MB | 15 MB | 30 MB |
| Max render time | 20 s | 60 s | 90 s | 120 s |
| Max PDF size | 10 MB | 25 MB | 75 MB | 150 MB |
| Storage | 100 MB | 5 GB | 15 GB | 50 GB |
| Bandwidth / month | 1 GB | 100 GB | 500 GB | 2 TB |
| Bandwidth / day | 0.25 GB | 10 GB | 50 GB | 200 GB |
| JavaScript execution | No | Yes | Yes | Yes |
| Internet access | No | Yes | Yes | Yes |
Concurrency and the queue
Concurrency is the number of renders your workspace can process at the same time. If every slot is busy, additional requests wait in a queue until a slot frees up, then run in turn.
- A request that finds a free slot starts immediately.
- A request that arrives while all slots are busy waits in the queue.
- If the queue is already full, the request is rejected rather than queued — retry with backoff.
Because a single connection blocks until its PDF is ready, concurrency — not a monthly page count — is the metric that determines throughput for bursty workloads. Higher plans raise both the number of parallel slots and how deep the queue can grow. Paid workspaces are also scheduled ahead of free ones when the platform is busy.
Request and output size
Two size limits apply to every render:
- Request payload — the combined size of everything you upload for a render: HTML, header and footer HTML, the template context, and all attached assets. Requests over the limit are rejected before rendering.
- PDF size — the maximum size of the generated file. A render that would exceed it fails.
If you hit the payload limit, the usual cause is large embedded images or fonts — reference them as assets so they are uploaded efficiently instead of inlined as base64.
Render time
Each render has a maximum wall-clock time. Long renders are usually caused by waiting on slow external resources or a wait condition such as networkidle0 that never settles. Keep templates self-contained, prefer local assets, and only wait for what you actually need.
Monthly generations and bandwidth
The Free plan is capped at a fixed number of generated PDFs per month; paid plans have no fixed generation cap. In addition, every plan has a fair-use bandwidth allowance measured both per month and per day, covering uploaded request data, fetched remote assets, and generated output. Exceeding the daily or monthly bandwidth allowance temporarily blocks new renders until the window resets.
JavaScript and internet access
On the Free plan, renders run in a locked-down mode: JavaScript is not executed and the renderer has no internet access, so external URLs and scripts are ignored. This mode is designed for static, self-contained HTML and CSS.
Paid plans enable JavaScript execution and internet access, so client-side rendering (charts, dynamic layout) and remote assets work. Even with internet access enabled, prefer the asset pipeline for anything you control — it is faster and does not depend on a third-party host being reachable at render time.
Storage
Stored PDFs and dashboard-managed assets count against your workspace's storage quota. When you approach the quota, remove PDFs or assets you no longer need to free space. Storage is a running total, not a monthly reset.
Data retention
Operational records are kept for a fixed window and deleted automatically afterwards. Content you manage yourself (templates, assets) stays until you delete it.
| Data | Retention |
|---|---|
| Render history (status, metrics, reference, metadata) | 13 months (400 days) |
| Per-render logs | 30 days |
| Webhook delivery attempts | 90 days |
| Dashboard notifications | 90 days |
| Stored PDFs | Until you delete them, your workspace retention window removes them, or their render record expires (13 months at the latest) |
| Templates and assets | Until you delete them (or your account is closed) |
Generation payloads (HTML, context, request assets) and non-stored PDFs are never retained — they are deleted right after the render finishes. See the Terms of Service for the authoritative policy.
How limits surface as errors
When a request exceeds a limit, the API responds with a specific status so you can react programmatically:
| Situation | Response | What to do |
|---|---|---|
| Queue full / no capacity | 429 Too Many Requests |
Retry with exponential backoff. |
| Payload too large | 413 Payload Too Large |
Reduce inlined data; use assets. |
| Monthly generations, bandwidth, or storage exceeded | 403 Forbidden |
Upgrade the plan or wait for the window to reset. |
| Render exceeded max time | Render failure | Simplify the template or relax wait conditions. |
See Errors for the full list of status codes and exceptions and how to handle them safely.