Blog/Compare

Self-host Gotenberg vs a managed PDF API

Compare··7 min read

Gotenberg is a Docker HTTP API that wraps headless Chromium and LibreOffice. A managed PDF API is the same print job with someone else holding the process. The gotenberg vs api question is not print quality. Both can emit a Chromium PDF from HTML. The question is who owns Chromium at 3 a.m.: you, or a host that already has keys, a wallet, and logs. HTML path: https://relaypdf.com/html-to-pdf. Feature table, not rewritten here: https://relaypdf.com/compare/gotenberg. Fields: https://relaypdf.com/docs/pdf. Upstream: https://gotenberg.dev/.

What Gotenberg actually is

Official docs describe a container you start and a multipart form you POST. Default image: gotenberg/gotenberg:8 on port 3000. HTML, a URL, or Markdown go through Chromium. Office files go through LibreOffice. PDF engines in the same image cover merge, split, rotate, flatten, encrypt, watermark, stamp, metadata, bookmarks, and attachments. Variants: 8-chromium drops Office; 8-libreoffice drops URL, HTML, Markdown, and screenshots. Ask a missing route and you get an error, not a silent fallback.

Chromium routes can wait for a JS expression. The page is a browser, not a static dump. The live demo on gotenberg.dev is a small Render box (512 MB RAM, 0.5 CPU), a tight per-IP rate cap, and a 5 MB body limit. Demo, not a capacity plan.

The install page is blunt: do not expose Gotenberg to the public internet. Treat it like a database. Prefer a loopback bind unless you already have a private network. There is no dashboard and no API-key product in the box. Auth is whatever you put in front of it.

The ops cost of Chromium at home

Chromium is not a 40 MB sidecar. The full image is on the order of a gigabyte because Chromium and LibreOffice are inside it. Kubernetes docs on gotenberg.dev suggest at least 512 Mi and 0.2 CPU as a floor. Cloud Run variants want at least 1 Gi. Those are process-start floors, not concurrent invoice floors. Treat 2-4 GB under concurrency as operator folklore, not a RelayPDF benchmark.

You own the flags that keep the browser from rotting: auto-start, a concurrency cap, a restart-after-N, and an API timeout. You own the queue when month-end reports land at 23:00. You own image upgrades when Chromium or the Go API ships a security fix.

Gotenberg 8.32.0 is a reminder that this is a network service. Recent releases tightened file-scheme URLs on convert/url, stamp and watermark sources that used to accept a path without an upload, and outbound fetches from Chromium and LibreOffice. Internet-facing deployments opt into a stricter SSRF posture. Publish the service port to the world and you are the incident.

This is not an argument against Gotenberg. It is an argument against treating a one-line start as the whole cost model.

What a managed API is buying

A managed HTML to PDF API is a Chromium print you do not schedule. RelayPDF is one of those. POST JSON to https://api.relaypdf.com/v1/pdf with exactly one of html, url, markdown, or templateId. HTML is UTF-8 JSON, not Base64. response is binary, url, or async. Office is POST /v1/convert. Merge is POST /v1/pdf/merge. Product: https://relaypdf.com/html-to-pdf. Fields: https://relaypdf.com/docs/pdf.

The host rejects private, loopback, and metadata URLs. Timeout max is 60 seconds. waitUntil is load, domcontentloaded, networkidle0, or networkidle2. format is letter, legal, tabloid, ledger, or a0-a6. printBackground defaults to true. A url response expires in 24 hours. render_failed is not billed. You do not get a shell on the browser. That is the trade: less surface, less control.

https://relaypdf.com/compare/gotenberg already states the contrast. Gotenberg is strong for self-hosted teams. RelayPDF is managed: auth, wallet billing, request logs, API keys, async jobs, webhooks, and SDK/CLI tooling are already wired. Operational burden is low because you are not running the infrastructure. This post stays on ops cost and when self-host is the right call.

When self-host is the right call

Run Gotenberg when the network boundary is the product. If the HTML or the URL must never leave a VPC, a managed fetch of a public URL is the wrong contract. Gotenberg sits on the same Compose or cluster network as the app. That is a real win, and it is why the project spends release notes on SSRF. An open convert/url route inside a flat network will print whatever an internal client can name.

Run Gotenberg when you already operate containers as a habit. Someone can explain the memory request, the readiness probe, the image pin, and the ingress rule without a new ticket type. On-call already pages for disk and CPU. Adding one more fat image is cheaper than adding a vendor and a second set of keys.

Run Gotenberg when volume is high, burst is predictable, and the node is already paid for. Per-document vendor pricing looks expensive next to a box that is on anyway. Do the arithmetic with staff time and idle capacity, not a registry pull count.

Run Gotenberg when you need LibreOffice and Chromium on one host you control. The 8-chromium and 8-libreoffice cuts exist so you do not pay the full image if you only print HTML or only convert Office. A managed API may split those jobs across routes and rate cards.

Do not run Gotenberg to avoid thinking about browsers. You will think about browsers. Do not run it as a public service without an auth layer you wrote.

When a managed API is the right call

Buy the API when the app team's job is the document, not the renderer. A single POST from CI, an agent, or a backend is enough. You want keys, a ledger, and a failure that is not a node-level incident. You are fine sending HTML or a public URL. You do not need Chromium to see RFC1918 hosts.

Buy the API when serverless or small containers are the default and a 1 GB image with a browser does not fit. Gotenberg publishes Cloud Run and AWS Lambda variants because people try. Lambda buffered mode still caps the response. That is more moving parts than a JSON POST that writes a PDF to disk.

Buy the API when you also want templates, Markdown, screenshots, merge, and a CLI or MCP on the same account without assembling them. Gotenberg can merge files. You operate that merge.

Request shape, not a migration sermon

Gotenberg is multipart form fields. RelayPDF is JSON. Same mental model: document in, PDF out. Illustrative Gotenberg call from the public docs (not a RelayPDF route):

# image: gotenberg/gotenberg:8 (loopback port 3000)

# POST /forms/chromium/convert/url

# form field url=https://example.com

# response body is the PDF

Managed Chromium print, fields from https://relaypdf.com/docs/pdf:

POST https://api.relaypdf.com/v1/pdf

Authorization: Bearer pdf_live_...
Content-Type: application/json
{"html":"<h1>Invoice 1042</h1>","filename":"invoice.pdf"}

Side by side

TopicSelf-host GotenbergManaged PDF API (RelayPDF)
Where Chromium runsYour container / clusterTheir fleet
AuthYou put something in frontAPI keys, already on
BillingNodes, disk, peoplePrepaid wallet per success
HTML / URL / Markdown PDFChromium routesPOST /v1/pdf
OfficeLibreOffice in the image you chosePOST /v1/convert
Private / VPC URLsPossible; you own SSRFRejected by contract
Timeout / waitFlags you set60s max; waitUntil enum
Internet exposureDocs: do notPublic HTTPS API
Dashboard / logs / walletBuildShipped
When it is the right callBoundary, capacity, existing opsDocument job, not browser job

Limits

RelayPDF Chromium timeout is 60 seconds. Private URLs are rejected. The worker is not a general browser-automation host. render_failed is not billed; that is not unlimited retries.

Gotenberg will not invent auth, a usage ledger, or a dashboard. The demo limits are demo limits. The Kubernetes floor is a floor. Lambda and Cloud Run variants have platform caps you must design around. A convert/url route that can see your network is a feature and a foot-gun.

Neither side is described here as archival, healthcare, OCR, or signature infrastructure. No ratings.

Pricing (verified)

RelayPDF prepaid wallet (https://relaypdf.com/pricing, checked 23 Aug 2026): HTML, URL, Markdown PDF or screenshot $0.015; template PDF $0.015; AI generate $0.05; LibreOffice $0.04; wkhtmltopdf $0.025; tools $0.005. Failures never billed. Credit does not expire. $5 signup credit, no card. Pack bonuses 5/6/10/15 percent. Gotenberg has no per-document price. You pay compute and the people who keep the image current. No made-up TCO number here.

Pick the owner of the browser

If the renderer must live on your network and you already run fat containers, Gotenberg is the right call. If the job is HTML in, PDF out, and you do not want Chromium in the deploy graph, POST the document: https://relaypdf.com/html-to-pdf. Capability grid, not rewritten here: https://relaypdf.com/compare/gotenberg. Options: https://relaypdf.com/docs/options. Upstream install: https://gotenberg.dev/docs/getting-started/installation.

Ready to generate?

One API for HTML, Markdown, URLs, and Office. REST, SDK, CLI, or MCP.