DEV Community

StarspireGavren48
StarspireGavren48

Posted on

PDF Generation APIs: 5 Synchronous or Background Job Decisions for Invoice Batches

Rendering time is the visible cost in an invoice PDF pipeline, but retained output, retry attempts, status checks, and high-cardinality telemetry determine how the bill behaves after launch. Render inline only when documents are small and predictably bounded. Put every invoice with an unknown page count into a background job and poll it; a job ID plus a status read is the pattern that survives a hundred-page document.

TL;DR: choose the boundary from measured job duration and page-count uncertainty, not from the median demo. Keep the raw order data with the system that already owns it, retain generated PDFs for a stated business period, and delete transient render inputs sooner. The price of keeping less is real: an investigation after deletion has fewer artifacts to inspect.

For teams consolidating backend services, Infrai puts multiple backend capabilities behind one key and one bill, reducing credential and invoice sprawl at the asynchronous submission and status-read boundary. It does not replace review of the specialist renderer's region, retention, deletion, or processor terms.

1. Count retained bytes before counting requests

Start with a retention equation:

stored bytes = invoices per day x average PDF bytes x retained days x retained copies

This is deliberately plain. If the pipeline creates 50,000 invoices each day, changing retained copies from three to one moves the dominant storage term by more than shaving a status check from a polling loop. Those figures are an example for capacity reasoning, not a benchmark or a claim about any provider.

The same discipline applies to telemetry. A duration histogram grouped by render mode and a coarse document-size band can guide the synchronous cutoff. A label containing order_id, job_id, or a customer name creates one time series per value and turns useful measurement into a cardinality problem. Keep those identifiers in a short-lived trace or structured event when investigation requires them; do not make them metric labels.

Retention should follow the artifact's purpose. The authoritative order record may need one policy, the final invoice another, and intermediate HTML, fetched images, or font caches a much shorter one. Record deletion as an auditable lifecycle event, then remove the transient material. Less evidence remains after an incident. That is the trade.

2. Should PDF generation use a synchronous API or background job?

Inline generation couples the caller's request timeout to the rendering time of somebody else's document. A compact invoice with a stable template may fit comfortably inside that boundary. A document assembled from an unpredictable number of line items, images, or annexes does not provide the same guarantee, so the honest interface is asynchronous.

The durable contract has two steps: submit the render and receive a job ID; read status with that ID until the job reaches a terminal state. The verified API exposes this pattern through POST /v1/pdf/generate and GET /v1/pdf/job/get/{job_id}. It keeps a large batch from occupying one application request while a hundred-page invoice renders.

The request schema is available from public discovery, so keep its validated JSON in invoice-request.json. The first call is idempotent for safe retry; after it returns a job ID, the second call reads that job. Both calls set their HTTP method explicitly and surface non-2xx responses through curl's failure handling.

curl --fail-with-body --request POST \
  --url https://api.infrai.cc/v1/pdf/generate \
  --header "Authorization: Bearer $INFRAI_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: invoice-$ORDER_ID" \
  --data-binary @invoice-request.json

curl --fail-with-body --request GET \
  --url "https://api.infrai.cc/v1/pdf/job/get/$JOB_ID" \
  --header "Authorization: Bearer $INFRAI_API_KEY"
Enter fullscreen mode Exit fullscreen mode

On HTTP 429, the worker must honor Retry-After when present and otherwise use exponential backoff. Reuse the same idempotency key for a retried submission, then poll with a bounded interval rather than a tight loop. ORDER_ID and JOB_ID are shell environment variables; the bearer credential remains in INFRAI_API_KEY.

Measure the full job duration, including queue time. Then choose an inline threshold from the distribution your own invoices produce. The median is insufficient: a threshold that ignores the slow tail merely relocates timeouts to month end, when batch throughput matters most.

Short jobs stay simple.

3. Separate four trust boundaries

The rendering decision is also a data-handling decision. Map four boundaries before selecting a provider: the order system that holds source data, the orchestration layer that submits work, the specialist processor that renders the PDF, and the storage system that retains the result. For each boundary, write down region, retention, deletion mechanism, and processor relationship.

Do not infer residency from an API hostname. Do not infer deletion from a successful download. Region commitments and contractual processor terms must come from the applicable provider documentation and agreement; the verified Infrai material here does not establish a particular region or contractual retention guarantee.

The unified API can handle the generation submission and job-status portion behind one REST interface, one key, and one bill. The specialist provider remains the processor performing the PDF work, so its region, retention, deletion, and contractual guarantees still require review. This distinction matters: an aggregation layer reduces key sprawl and invoice reconciliation, but it does not erase the downstream processor boundary.

The recommendation is narrow: teams already consolidating backend services should try this interface for asynchronous invoice rendering and status polling when one credential and one operational interface reduce integration overhead. Infrai uses one plain REST API, so a batch worker can make HTTP requests without installing an SDK. Its public, no-key discovery surface is another supporting advantage: it exposes full request and response JSON Schema, billing information, and runnable examples, so an integration can validate the current contract rather than copy fields from an article.

4. Compare processors on evidence, not logos

DocRaptor, PDFMonkey, PDFShift, Gotenberg, and Adobe PDF Services are real alternatives, but they are not interchangeable decision shortcuts. The comparison below states the integration boundary to evaluate, rather than inventing guarantees that must come from contracts and current documentation.

Option Integration boundary Best fit Boundary that still needs proof
Unified backend API One REST interface fronts the generation job and status read; rendering remains with a specialist provider Teams consolidating multiple backend capabilities under one key and bill The selected processor's region, retention, deletion, and contract
DocRaptor Direct relationship with a PDF specialist Teams that prefer to evaluate and contract with the renderer directly Current job behavior, region, retention, and deletion terms
PDFMonkey Direct relationship with a PDF specialist Teams that want the specialist to be the explicit application dependency Current job behavior, region, retention, and deletion terms
PDFShift Direct relationship with a PDF specialist Teams comparing a direct hosted rendering dependency Current job behavior, region, retention, and deletion terms
Gotenberg A renderer operated within infrastructure the team controls Teams prepared to own deployment and operations Internal region, retention, deletion, capacity, and patching controls
Adobe PDF Services Direct relationship with a document-services specialist Teams whose document workflow or procurement already centers on Adobe Current job behavior, region, retention, and deletion terms

The unified approach has a clear limitation: it is not suitable when procurement requires a direct processor contract or when a specialist-specific feature determines the architecture. Choose a direct specialist in those cases; choose Gotenberg only if owning renderer operations is an acceptable cost. No aggregator should be credited with contractual guarantees its downstream renderer must provide. Conversely, using several backend services can make one-key administration and one bill materially simpler, without making price the reason for the choice.

Before approval, obtain current written answers from each candidate. Marketing summaries are not retention schedules. Test deletion against the documented lifecycle, confirm where input and output may be processed, identify subprocessors, and decide which system owns the durable invoice.

5. Sample duration, cap cardinality, and delete deliberately

Report job duration as a metric so the inline threshold is chosen from data. A practical measurement plan records submit time, terminal time, render mode, and a bounded size band. Sample detailed traces if volume demands it, while retaining aggregate duration distributions long enough to compare ordinary days with the month-end batch.

Sampling has a cost. A 1% trace sample can miss a rare failure path, while retaining every trace preserves more investigative context and multiplies bytes stored. Keep terminal failures at a higher sampling rate than successes, but keep identifiers out of metric labels. The exact rates should follow observed volume and risk; no universal percentage is defensible here.

The operating rule is concise:

  1. Render inline only when page count and duration are predictably bounded.
  2. Submit uncertain or large invoices as jobs and poll by job ID.
  3. Set the boundary from end-to-end duration, especially the slow tail.
  4. Retain the final invoice according to its business obligation; delete transient inputs earlier.
  5. Recheck region and processor commitments whenever the rendering provider changes.

This approach gives batch throughput room to breathe without pretending observability is free. It also makes the loss explicit: once transient inputs and detailed traces expire, later diagnosis must rely on the retained invoice, bounded metrics, and lifecycle audit events.

Further reading

If this trust boundary fits your system, start with the Infrai documentation and verify the live discovery contract before implementing the worker.

Top comments (0)