Engineering

PDF Generator API: Real Costs & Performance in Production

Explore PDF generator API realities: median render times, cold start penalties, and hidden costs. Compare APIs vs. libraries for invoices, reports, and labels.

M Mikel Rougstone · 7 September 2026 · 8 min read
PDF Generator API: Real Costs & Performance in Production

A PDF generator API can reduce typical document rendering times to a median of 0.6 seconds, eliminating the operational overhead of self-hosting tools like wkhtmltopdf or Puppeteer. For backend and full-stack developers tasked with shipping invoices, receipts, contracts, certificates, reports, and labels, a hosted API offloads the complexities of browser management and scaling.

The Hidden Costs of Self-Hosting PDF Generation

Maintaining an in-house PDF generation pipeline often appears cheaper on paper until the full operational costs are factored in. The primary contenders for self-hosted HTML-to-PDF rendering are typically wkhtmltopdf and headless Chromium (via Puppeteer or Playwright). While wkhtmltopdf is not 'dead', it is unmaintained, and its real cost is the modern CSS it never learned, leading to inconsistent rendering and developer time spent on workarounds. Chromium-based solutions provide superior rendering fidelity but introduce significant infrastructure challenges.

Cold Starts and Resource Consumption

One critical performance aspect for self-hosted Chromium is the cold start penalty. A cold headless Chromium instance requires approximately 7.8 seconds per request to initialize. This latency is unacceptable for user-facing applications requiring on-demand document generation. Keeping the browser warm reduces this to around 0.65 seconds, but this requires persistent instances, consuming memory and CPU even when idle. For instance, a single warm Chromium instance can easily consume hundreds of megabytes of RAM. Scaling this for concurrent requests means running multiple such instances, leading to increased cloud infrastructure costs for EC2 instances, Fargate tasks, or Kubernetes pods.

PDFGeny addresses this by managing warm Chromium pools, delivering a median render time of 0.6 seconds. This performance is achieved without requiring developers to provision or scale their own browser infrastructure. The API also supports WeasyPrint as a second engine for specific needs and Ghostscript for PDF/A-2b output, offering a range of rendering capabilities.

Security Implications of URL-to-PDF Endpoints

Offering a URL-to-PDF conversion feature introduces a significant security vulnerability: Server-Side Request Forgery (SSRF). An unmitigated URL-to-PDF endpoint allows attackers to force your server to make requests to internal network resources, metadata endpoints (e.g., AWS EC2 metadata service at 169.254.169.254), or even local loopback addresses (127.0.0.1). This can expose sensitive information or facilitate further attacks.

Mitigating SSRF requires careful validation. The system must resolve the host specified in the URL and reject private, loopback, and metadata addresses before the renderer attempts to fetch the content. This involves maintaining a robust allowlist or denylist of IP ranges and specific hostnames, a non-trivial engineering task that needs continuous updating as network configurations evolve.

PDFGeny handles this validation internally, securing its URL-to-PDF endpoint against common SSRF vectors. Developers can confidently submit URLs without implementing complex network security checks on their application's side. The API ensures that the URL provided is safe for rendering.

Rendering Fidelity: Web Fonts and Page Breaks

Achieving pixel-perfect PDF rendering from HTML is challenging due to the inherent differences between browser rendering and static document generation. Two common failure modes are web font loading and unpredictable page breaks.

Web Font Handling

Web fonts silently fall back to system defaults in PDFs when the renderer finishes before the font asset loads. This often occurs under network latency or when font files are large. The PDF output will display an unexpected font, degrading the document's visual integrity. To prevent this, renderers need to explicitly wait for web fonts to load or embed them directly within the HTML payload. For a hosted API, this means the rendering engine must have robust font loading and embedding mechanisms.

PDFGeny's headless Chromium engine is configured to manage web font loading efficiently, aiming for consistent rendering. Developers using custom fonts should ensure they are properly linked and, if possible, subsetted for optimal performance. Generating PDFs from plain text or highly controlled HTML can simplify font management.

Managing Page Breaks and Layout

Page breaks are notoriously difficult to control in HTML-to-PDF conversion. CSS properties like page-break-before, page-break-after, and page-break-inside are inconsistently supported across different renderers, and even when supported, their behavior can be unpredictable. This leads to awkward content splits, truncated tables, or blank spaces, requiring manual adjustments to the HTML structure. For complex documents like contracts or reports, this can involve significant trial and error.

PDFGeny provides 40 ready document templates designed to handle common layout challenges, including page breaks. These templates serve as a starting point, reducing the need for extensive CSS debugging. Developers can also fine-tune their HTML and CSS to work optimally with the Chromium engine, leveraging its robust rendering capabilities. For example, using CSS flexbox or grid layouts can offer more predictable control over content flow than older table-based approaches.

API vs. Local Library: When to Choose Which

For a handful of documents a day, a local library beats any API. This is a critical distinction often overlooked in the push for API-first solutions. If your application generates fewer than, say, 50 documents per month, and you have the developer resources to manage dependencies, a local solution like a Python library for PDF generation or a basic wkhtmltopdf wrapper might be more cost-effective. The PDFGeny free plan, however, also offers 50 documents a month without requiring a card, providing a zero-cost entry point to evaluate API benefits.

FeaturePDFGeny APILocal Library (e.g., wkhtmltopdf)Local Headless Chromium (e.g., Puppeteer)
Setup TimeMinutes (API key, basic code)Hours (installation, dependency management)Days (containerization, scaling, monitoring)
MaintenanceNone (managed by PDFGeny)High (updates, security patches, OS compatibility)Very High (browser updates, resource scaling, OS-level dependencies)
Median Render Time0.6 sVaries, often slower for complex CSS0.65 s (warm), 7.8 s (cold)
ConcurrencyManaged by APILimited, single processRequires explicit scaling (e.g., multiple Docker containers)
SecurityManaged (SSRF protection)Developer responsibilityDeveloper responsibility (SSRF, container hardening)
Cost (per document over free tier)$0.009Developer time, infrastructureDeveloper time, infrastructure

The inflection point for choosing an API typically occurs when document volume scales, when multi-language support (Python, Node.js, PHP, Go, Ruby, cURL) is required across a team, or when the operational burden of maintaining rendering infrastructure becomes a bottleneck. PDFGeny supports batch processing of up to 100 documents in one API call, offering efficiency for larger workloads.

What We Got Wrong / What Surprised Us

One aspect that consistently surprised us was the subtlety of web font failures. We initially assumed that if a font was linked, it would simply render. However, observing web fonts silently fall back in PDFs when the renderer finished before the font assets fully loaded highlighted a critical timing dependency. This isn't a hard error but a silent degradation of design quality, often missed in initial testing. The fix involves explicit waiting mechanisms or pre-loading, which is complex to implement reliably across varied network conditions in a self-hosted environment. This underscores the value of a managed service where such nuances are handled at the platform level.

Another unexpected finding was the specific challenge of running sync_playwright inside a Django application. It consistently raises a SynchronousOnlyOperation error unless the rendering process is explicitly moved to its own thread. This isn't a Playwright-specific issue but a Django ORM constraint, preventing synchronous database access from an asynchronous context. It adds a layer of complexity for Python developers integrating browser automation, requiring explicit threading or asynchronous task queues like Celery, which increases architectural overhead for self-hosted solutions. For example, converting DOCX to PDF in Python often involves such operations. Python developers converting DOCX to PDF might encounter similar threading challenges.

Practical Takeaways

  • Evaluate Document Volume and Developer Time: If you generate fewer than 50 documents monthly, a local library might suffice (Difficulty: Low, Time: 1-2 hours for basic setup). Beyond that, or if developer time for infrastructure is scarce, consider an API.
  • Prioritize Security for URL-to-PDF: Implement robust SSRF protection if you expose a URL-to-PDF endpoint (Difficulty: High, Time: 1-3 days for initial implementation and ongoing maintenance). Resolve hostnames and reject private IP ranges.
  • Address Web Font Loading Explicitly: If self-hosting, ensure your renderer waits for web fonts to load or embed them (Difficulty: Medium, Time: 4-8 hours for debugging and implementation per document type). This prevents silent font fallbacks.
  • Offload Infrastructure Overhead: For applications requiring consistent performance (median 0.6 s render time) and scalability, a hosted API like PDFGeny eliminates the need to manage cold starts, warm instances, and browser updates (Difficulty: Low, Time: Minutes for API integration).
  • Leverage Templates for Consistency: Use pre-built templates for common documents like invoices or reports to ensure consistent rendering and reduce design-to-PDF debugging time (Difficulty: Low, Time: 1-2 hours to adapt an existing template). PDFGeny offers 40 ready document templates.

Ready to streamline your PDF generation process? PDFGeny lets you send HTML, a URL, or one of 40 ready document templates and get a finished PDF back in one API call — no Chromium to run, no fonts to install. Get started with 50 documents a month on our free plan, no card required.

Get a free API key

FAQ Section

How fast is PDFGeny's PDF generation API?

PDFGeny delivers a median render time of 0.6 seconds for PDF generation. This is achieved by maintaining warm headless Chromium instances, avoiding the 7.8-second cold start penalty often associated with self-hosted solutions.

What rendering engines does PDFGeny use?

PDFGeny primarily uses headless Chromium as its default rendering engine for high fidelity. It also offers WeasyPrint as a second engine for specific use cases and Ghostscript for generating PDF/A-2b compliant documents.

Can PDFGeny handle batch PDF generation?

Yes, PDFGeny supports batch generation, allowing developers to process up to 100 documents in a single API call. This feature is efficient for generating multiple invoices, reports, or labels concurrently.

Is there a free plan available for PDFGeny?

PDFGeny offers a free plan that includes 50 document generations per month. No credit card is required to sign up for the free tier. Overage is priced at $0.009 per document.

M

Mikel Rougstone

Founder, PDFGeny

I build and run PDFGeny — the API, the rendering fleet and the template catalog. Most of what I write here comes from something that broke in production first.