Support large documents
If your application handles large uploads, scanned document bundles, architectural drawings, or PDFs with many pages, annotations, or form fields, plan for large-document support from the start.
Document Engine doesn’t have a separate large document mode. Support depends on a combination of factors:
- The document itself, including file size, page count, annotation count, form fields, and page dimensions
- The storage backend you choose
- Upload and processing timeouts across your stack
- Available CPU, memory, local disk, and network throughput in your deployment
Use object storage for large documents
Use object storage for production deployments that handle large documents:
Avoid the built-in database-backed storage for large documents in production.
Why:
- The built-in storage backend stores assets in PostgreSQL, and PostgreSQL has a hard
1 GBlimit for a field value. Because Document Engine stores built-in assets in abyteacolumn, that limit applies to stored assets. Refer to the PostgreSQL limits documentation(opens in a new tab) for details. - The built-in storage backend isn’t a good fit for large-object production workloads.
- Object storage performs better and scales more predictably for large PDFs and attachments.
If you expect uploads larger than 1 GB, object storage isn’t just recommended — it’s required.
Increase the right limits
Large-document support usually requires you to adjust several settings together.
The most relevant settings are:
ASSET_STORAGE_BACKEND— Chooses3orazurefor large documents in production.MAX_UPLOAD_SIZE_BYTES— Sets the largest upload Document Engine accepts.SERVER_REQUEST_TIMEOUT— Sets the HTTP API request timeout for upload and post-upload processing.PSPDFKIT_WORKER_TIMEOUT— Sets how long PDF-related processing can run before timing out.FILE_UPLOAD_TIMEOUT_MS— Sets the timeout for uploads to S3 or Azure Blob Storage.ASSET_STORAGE_CACHE_SIZE— Sets the size of the local asset cache.
Depending on your integration, the following settings can also matter:
READ_ANNOTATION_BATCH_TIMEOUT— Useful for annotation-heavy documents if annotation-related requests time out.ASSET_STORAGE_CACHE_TIMEOUT— Useful if fetching large assets from storage times out.REMOTE_URL_FETCH_TIMEOUT— Useful if you add documents from remote URLs instead of direct uploads.
Refer to the configuration options guide for the full list.
Configure the whole request path
Large uploads can still fail even if Document Engine is configured correctly, because another layer might time out first.
Make sure the complete request path is aligned:
Client timeout -> reverse proxy or ingress timeout and body-size limit -> Document Engine upload limit and request timeout -> object storage upload timeoutIn practice:
- Set your reverse proxy or ingress to accept the same upload size as Document Engine.
- Set proxy timeouts to at least the same value as the Document Engine request timeout.
- Set object storage timeouts high enough for your largest uploads.
If any layer has a smaller limit, that layer becomes the effective maximum.
Size your environment for your workload
Large documents affect more than upload bandwidth.
Plan for enough:
- Local disk for temporary upload files and the asset cache
- RAM and CPU for the operations your application runs after upload
- Network throughput between Document Engine and your object storage
For example, a deployment that only uploads and stores large PDFs has different requirements from one that also renders pages, extracts text, or exports annotated copies.
Validate with your own documents
Test with representative files from your own application to tune support for large documents.
We recommend this workflow:
- Choose object storage and set an upload limit larger than your largest supported document.
- Increase request and storage timeouts based on an initial estimate.
- Upload representative large documents and run the operations your application uses most often.
- Monitor Document Engine logs and proxy logs for timeouts and warnings.
- Adjust settings until warnings and timeout errors disappear for your supported workload.
Typical validation steps include:
- Uploading the document
- Opening it in the viewer
- Loading annotations or form fields
- Adding a comment
- Exporting or saving changes
Example starting point
The exact values depend on your environment, so use this only as a checklist:
ASSET_STORAGE_BACKEND=s3MAX_UPLOAD_SIZE_BYTES=<larger than your largest supported upload>SERVER_REQUEST_TIMEOUT=<long enough for upload and processing>PSPDFKIT_WORKER_TIMEOUT=<long enough for post-upload PDF processing>FILE_UPLOAD_TIMEOUT_MS=<long enough for your object storage>ASSET_STORAGE_CACHE_SIZE=<large enough for your working set and local disk budget>Depending on your workload, also configure these settings:
READ_ANNOTATION_BATCH_TIMEOUT=<if annotation-heavy requests time out>ASSET_STORAGE_CACHE_TIMEOUT=<if fetching large assets times out>REMOTE_URL_FETCH_TIMEOUT=<if you import large documents from URLs>For ASSET_STORAGE_CACHE_SIZE, a useful starting point is:
average document size x number of documents you expect to be active concurrently x safety factorStart with a safety factor of 1.5, and increase it if your workload causes frequent cache churn.
For example:
- If your average large document is
500 MBand you expect one instance to keep about20active documents cached, start around500 MB x 20 x 1.5 = 15 GB. - If your average large document is
2 GBand you expect10active documents per instance, start around2 GB x 10 x 1.5 = 30 GB.
Keep in mind that ASSET_STORAGE_CACHE_SIZE covers only the local asset cache. You should also leave additional disk space for:
- Temporary upload files
- Other application data
- The operating system and container runtime
In practice, the machine or container host needs more free disk space than the cache size alone.
Enable HTTP/2 shared rendering
If your viewing workload includes large documents, enable HTTP/2 shared rendering. This is the most impactful configuration change for viewing performance on large files.
Viewing a large document is tile-heavy. The client requests many tiles while the user pans and zooms. Without shared rendering, each tile repeats per-request setup such as authentication, file materialization from asset storage, and PDF worker checkout. On large files, this setup adds noticeable overhead. Shared rendering performs this work once per connection and reuses it across subsequent tile requests.
To enable it:
HTTP2_SHARED_RENDERING_PROCESS_ENABLE=true# Hold workers across short idle gaps such as zoom or scroll pauses:HTTP2_SHARED_RENDERING_PROCESS_CHECKIN_TIMEOUT=1000# Allow longer worker checkout for large documents:HTTP2_SHARED_RENDERING_PROCESS_CHECKOUT_TIMEOUT=900000Pair it with an HTTP/2-capable proxy in front of Document Engine — for example, Caddy with h2c upstream — so tile requests from a single client are multiplexed onto one upstream connection.
If you’re running a clustered deployment, shared rendering becomes cluster-aware with no additional configuration: tile requests for a document run on the same owner node as the rest of that document’s requests. Refer to the HTTP/2 shared rendering guide for details.
Related guides
- Asset storage configuration
- Configuration options
- Cache configuration
- HTTP/2 shared rendering
- Document Engine logs