Limits and file sizes
ForkPDF caps the request you send, the file it generates, and the testResults returned
with it. These are the limits that apply to normal API and dashboard use.
At a glance
| Limit | Value | On exceed |
|---|---|---|
| API request body | 20 MB | 413 PAYLOAD_TOO_LARGE |
| Dashboard template save | 12 MB combined assets 15 MB request |
413 TEMPLATE_ASSETS_TOO_LARGE |
| PDF output | 25 MB | 413 OUTPUT_TOO_LARGE |
| Spatial ZIP output | 39 MB | 413 OUTPUT_TOO_LARGE |
| Combined output | 40 MB file + testResults |
413 COMBINED_OUTPUT_TOO_LARGE |
testResults |
8 KB JSON | 413 TEST_RESULTS_TOO_LARGE |
How sizes are measured
All limits use UTF-8 bytes. sizeBytes reports the PDF or ZIP file size only.
Request limits
The API accepts up to 20 MB of JSON.
- What counts:
htmlContent,css,js,data,testCase, the expanded contents of atemplateId, and inline data URI images embedded inhtmlContentorcss. - What does not count: the bytes of images, fonts, and pages fetched by Chromium from a
remote
url; only the URL string counts.
Dashboard template saves are limited to 12 MB of combined
html + css + js + testCase inside a 15 MB request. Use templateId instead of
inline htmlContent when the same layout is reused; the expanded template still counts toward
the 20 MB API request.
Output limits
A normal generation returns a PDF. With spatial: true, it returns a ZIP containing
document.pdf and data.pb. The limits are separate:
| Output | Limit | What it includes |
|---|---|---|
| 25 MB | The rendered PDF only. | |
| Spatial ZIP | 39 MB | document.pdf + data.pb + ZIP overhead. |
| Combined response | 40 MB | PDF or ZIP plus testResults. |
streamOnly responses use the same limits. Webhook generations return a 15-minute download
URL instead of the file binary.
Spatial ZIPs include data.pb
ForkPDF serializes the rendered DOM for the PDF. Element attributes are carried into data.pb,
and inline data URI images are also part of the HTML you send. A base64 image is therefore stored twice:
once in the request HTML and once in data.pb. A URL image is a short attribute in both places;
the PDF still contains the image pixels.
Tested with the same 539 KB JPEG:
| Image source | Request payload | data.pb | ZIP | |
|---|---|---|---|---|
| Image URL | 414 B | 512 B | 541 KB | 536 KB |
| Inline data URI | 719 KB | 719 KB | 541 KB | 1.07 MB |
With URL images, the request and data.pb stay small, and the ZIP stays close to the PDF size.
With inline data URIs, the base64 string is carried in both the request and data.pb, so the ZIP
can be about 2× the PDF.
Use image URLs for spatial output. If you use inline data URIs, keep the PDF around 18 MB or less to stay under the 39 MB ZIP limit, and keep the inline HTML under the 20 MB request limit. URL-based images can use the full 25 MB PDF budget; the ZIP should remain near the PDF size.
testResults limit
testResults is capped at 8 KB of JSON. It is separate from the PDF size but
counts toward the 40 MB combined limit.
API response and webhook payload
The JSON generation response includes sizeBytes, testResults, and a presigned
downloadUrl. The webhook sends the same metadata and URL, not the PDF binary. The payload stays
small because testResults is capped at 8 KB.
Error reference
| Status | Code | Meaning | Fix |
|---|---|---|---|
| 413 | PAYLOAD_TOO_LARGE |
API request over 20 MB, or dashboard body over 15 MB. | Reduce inline HTML or data; use templateId; compress assets. |
| 413 | TEMPLATE_ASSETS_TOO_LARGE |
Dashboard template assets over 12 MB. | Move images out of the template, or split the template. |
| 413 | OUTPUT_TOO_LARGE |
PDF over 25 MB, or spatial ZIP over 39 MB. | Reduce image size or font count; use spatial: false for large PDFs. |
| 413 | COMBINED_OUTPUT_TOO_LARGE |
Generated file plus testResults over 40 MB. |
Reduce the file or return a smaller testResults summary. |
| 413 | TEST_RESULTS_TOO_LARGE |
testResults over 8 KB. |
Return a summary instead of the full layout map. |
Reducing size
- Use
templateIdinstead of resending the same HTML. - Use image URLs or smaller images instead of base64 data URIs.
- Subset fonts and remove unused font weights.
- Return a summary from
testCase; put the full layout map indata.pb. - For spatial output, prefer image URLs. Inline data URIs are carried in both the request and
data.pb; keep those PDFs around 18 MB or less.