<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="atom.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://pdf.example.com/blog/</id>
    <title>PDF Server Blog</title>
    <updated>2026-07-11T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://pdf.example.com/blog/"/>
    <subtitle>PDF Server Blog</subtitle>
    <icon>https://pdf.example.com/img/favicon.svg</icon>
    <entry>
        <title type="html"><![CDATA[Rendering HTML to PDF with a headless-browser pool]]></title>
        <id>https://pdf.example.com/blog/render-html-to-pdf-with-a-browser-pool/</id>
        <link href="https://pdf.example.com/blog/render-html-to-pdf-with-a-browser-pool/"/>
        <updated>2026-07-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Why PDF Server drives a real browser over CDP, and how the pool keeps it fast and leak-free.]]></summary>
        <content type="html"><![CDATA[<p>The most honest way to turn HTML into a PDF is to let a browser print it. Here's
how PDF Server does that at scale.</p>
<!-- -->
<p>There are two ways to make a PDF from HTML: reimplement a slice of a browser's
layout engine, or use an actual browser. PDF Server takes the second path — it
drives headless Chromium (or Firefox) over the Chrome DevTools Protocol, so the
PDF is exactly what the browser would print. Modern CSS, web fonts, SVG, flexbox,
grid, and JavaScript all just work.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="templates-not-code">Templates, not code<a href="https://pdf.example.com/blog/render-html-to-pdf-with-a-browser-pool/#templates-not-code" class="hash-link" aria-label="Direct link to Templates, not code" title="Direct link to Templates, not code" translate="no">​</a></h2>
<p>You don't fork the service to add a document — you add a <strong>template directory</strong>:
an HTML template (Mustache, Handlebars, Go, or static), an optional JSON Schema,
PDF parameters, assets, partials, and examples. Build your image on top of the
base image, and you have a PDF microservice.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-interesting-part-managing-browsers">The interesting part: managing browsers<a href="https://pdf.example.com/blog/render-html-to-pdf-with-a-browser-pool/#the-interesting-part-managing-browsers" class="hash-link" aria-label="Direct link to The interesting part: managing browsers" title="Direct link to The interesting part: managing browsers" translate="no">​</a></h2>
<p>Browsers are heavy and, notoriously, leaky — Chromium spawns helper processes
(GPU, renderers, a crash handler) that aren't children of the main process. PDF
Server pools browser instances and, on teardown, launches each browser in its own
process group and escalates from <code>SIGTERM</code> to <code>SIGKILL</code> across the whole group,
polling <code>/proc</code> to confirm every helper is gone. No zombie processes, even under
churn.</p>
<p>Rendering is asynchronous: a small futures scheduler runs renders on a worker
pool sized to the browser pool, so concurrency and browser count stay in lockstep.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="compositions">Compositions<a href="https://pdf.example.com/blog/render-html-to-pdf-with-a-browser-pool/#compositions" class="hash-link" aria-label="Direct link to Compositions" title="Direct link to Compositions" translate="no">​</a></h2>
<p>Some documents are assembled from parts. A <strong>composition</strong> produces a data-driven
plan — with a jq or JavaScript planner — renders each part, and merges the PDFs
into one. Cover page + body + a remotely-fetched appendix, in one request.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="try-it">Try it<a href="https://pdf.example.com/blog/render-html-to-pdf-with-a-browser-pool/#try-it" class="hash-link" aria-label="Direct link to Try it" title="Direct link to Try it" translate="no">​</a></h2>
<p>Explore the <a class="" href="https://pdf.example.com/gallery/">Gallery</a> to see real PDFs rendered from the examples, or
start with the <a class="" href="https://pdf.example.com/docs/getting-started/quickstart/">Quickstart</a>.</p>
<p>Want a feature or commercial support? <a class="protected-email" href="https://pdf.example.com/blog/render-html-to-pdf-with-a-browser-pool/#" data-e="aGVsbG9AZXhhbXBsZS5jb20=">Email me</a>.</p>]]></content>
        <author>
            <name>Dmitrii Fedorenko</name>
            <uri>https://gitlab.com/c0va23</uri>
        </author>
    </entry>
</feed>