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 a templateId, and inline data URI images embedded in htmlContent or css.
  • 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
PDF 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.

PDF/UA-2 (experimental): tagged PDF/UA-2 generation uses the same 25 MB PDF and 39 MB spatial ZIP limits. Conversion can add a small amount of size and processing time. There is no separate page limit, but very large documents may hit the generation timeout. See PDF/UA-2 generation for details.

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 PDF ZIP
Image URL414 B512 B541 KB536 KB
Inline data URI719 KB719 KB541 KB1.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 templateId instead 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 in data.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.