DocRaptor — компетентний product. Він загортає Prince, gold-standard engine для HTML-to-PDF, у hosted REST API з retries, async jobs і добрими docs. Існує понад десятиліття, і для багатьох teams це obvious choice, коли “не хочу запускати Prince сам”.
Ми інший тип tool. gPdf взагалі не приймає HTML; він приймає structured JSON і render PDF безпосередньо на Cloudflare edge. List-price gap для 100K pages/month: $5/mo (gPdf Basic) vs $89/mo (DocRaptor Basic), приблизно 18×. Це не opening promo. Це structural. Ця стаття пояснює, чому structure створює таку price, і де кожен tool реально fit.
Дві архітектури поруч
| Layer | DocRaptor (HTML → PDF) | gPdf (JSON → PDF) |
|---|---|---|
| Input | HTML + CSS, з Prince extensions for paged media | JSON DocumentRequest |
| Renderer | Prince, compiled C++ engine | Custom Rust engine, compiled to WebAssembly |
| Hosting | Centralised servers DocRaptor, US datacentre region | Cloudflare Workers, кожен CF colo, 300+ cities |
| Cold start | Server-side worker pool | V8 isolate boot, single-digit ms |
| Per-render compute | Layout pass over HTML/CSS, потім Prince paginates | Direct typesetting, без layout interpretation pass |
| Per-render p50 | ~250-800 ms wall-clock, network + render | ~3-8 ms, network + render |
| Output determinism | High, Prince mature | Byte-identical, same JSON → same bytes |
Якщо читати ці two columns як “general HTML printer” проти “purpose-built document renderer”, ви вже зрозуміли architectural decision. Усе інше, latency, cost і навіть feature lists, є downstream від цього choice.
Податок Prince
Prince добрий. Він також робить роботу, яка не потрібна більшості invoice/receipt/label workflows: implement CSS Paged Media для arbitrary HTML, який user може надіслати; page-break rules, running headers, footnotes, cross-references, generated content boxes.
Ця generality має runtime cost. Щоб paginate arbitrary HTML document, engine має:
- Parse і validate HTML
- Parse і resolve CSS cascade, потенційно з власними Prince extensions
- Build render tree
- Run multi-pass layout, особливо для tables across pages або balanced columns
- Resolve cross-references across pages
- Emit PDF objects
Більшість цих passes — це вартість прийняття HTML як input. Якщо input уже structured data, що майже завжди так, бо invoice існує як JSON object до того, як ви wrap його в HTML, ви платите за ці passes у compute і latency на кожному render, а вони не додають value до output.
gPdf повністю пропускає layout-interpretation step. JSON DocumentRequest уже structurally specifies page layout: { pages: [{ size, elements: [...] }] }. Renderer typesets elements, deterministic paginate tables/lists і emit PDF. Немає CSS cascade для resolve, немає float layout для compute, немає cross-reference resolution pass.
Результат: той самий single-page invoice, який займає ~300 ms у DocRaptor, займає ~3 ms у gPdf. Ми швидші не тому, що написали швидший Prince; ми швидші тому, що не робимо більшість того, що робить Prince.
”Занадто дешево, щоб бути правдою” — реальне procurement objection
Це потрібно address directly, бо воно виникає на кожному B2B sales call.
“$5/mo for 100K renders. DocRaptor — $89. Anvil — $0.10/PDF, тобто $10,000 для same volume. Що з вами не так?”
Є три чесні reasons, чому ми можемо charge таку price:
1. Ми не запускаємо browser
DocRaptor amortises Prince infrastructure across customers. gPdf amortises one Cloudflare Worker, який коштує приблизно $0.50/million requests на Workers Bundled. З JSON-shaped input наш renderer займає приблизно 1.5 ms CPU per render. Додайте 50% margin, і ви все ще в cents-per-thousand-renders range. Arithmetic і є price.
2. Ми не запускаємо control plane
Немає async jobs, callbacks, retry queue, document storage, preview-link UI, multi-tenant database. Кожен render — single round-trip до stateless function і назад. Це прибирає весь ops surface, який більшість “PDF API” companies закладає в budget, і саме цей surface виправдовує їхню price.
3. Model сам відсіює workloads, на яких ми втрачали б гроші
Якщо document справді потребує HTML-to-PDF, наприклад 60-page legal contract або complex CSS-Grid report, ви bounce від JSON model у першу hour і підете до DocRaptor. Нам не потрібно price defensively для цих workloads, бо вони self-route. Ми price лише long-but-narrow tail “structured-data-to-document” workloads, де per-render cost справді tiny.
Разом: $5/100K не loss leader; це actual cost-of-goods-sold plus margin. Ми можемо тримати це, бо underlying compute дійсно настільки дешевий, коли ви не ship browser.
Де DocRaptor правильний вибір
Ми намагаємося не писати self-serving comparison. Cases, де DocRaptor справді wins:
- Ваш input — HTML, який ви не повністю control. User-generated reports, third-party templates, Markdown-from-CMS-rendered-to-HTML. Не варто писати JSON mapper для arbitrary input.
- Вам потрібні CSS Paged Media features, які supports Prince. Running headers/footers per chapter, complex footnote reflow, named-page selectors, generated tables of contents, indexes. gPdf має structured equivalents для common subset, але якщо ви живете в
@page :leftselectors, Prince — ваш friend. - Ваша content team пише HTML/CSS, а не JSON. Не нав’язуйте JSON authoring workflow non-engineering team. Вони це зненавидять.
- Async + callbacks + document storage as a service. DocRaptor stores generated PDFs і дає signed URLs для delivery. gPdf strictly stateless; result stores ваш code.
Якщо ви в будь-якому з цих buckets, залишайтесь на DocRaptor. Це правильний tool.
Де gPdf правильний вибір
Дзеркальна ситуація:
- Ваші inputs уже structured data: database rows, JSON API payloads, queue messages.
- Latency важлива: interactive checkout flows, real-time label printing, on-demand statement generation.
- Вам потрібна byte-identical reproducibility для tests, audit trails або e-invoice retention.
- Ви cost-sensitive на будь-якому volume понад кілька thousand renders/month.
- Вам потрібні barcodes, як GS1-128, QR, Data Matrix, PDF417, Aztec, MaxiCode, з sub-millimetre precision. Prince technically supports SVG barcodes, але 0.1 mm overall length precision через HTML/CSS non-trivial.
- Вам потрібні PDF/A (1b/2b/3b/4) або Factur-X / ZUGFeRD attachments for compliance.
- Ви не хочете запускати JSON-to-HTML-to-PDF pipeline, коли можна запускати JSON-to-PDF pipeline.
Migration механічна, не стратегічна
Поширене worry: “Switching означає rewrite усіх templates.” Зазвичай ні. Most HTML-to-PDF templates — це 20% layout, який один раз стає JSON structure, і 80% data interpolation, що однаковий незалежно від renderer.
Practical path:
- Виберіть один document type для migration. Почніть із highest-volume one: biggest savings, smallest blast radius.
- Візьміть data interface HTML template, тобто variables, які він interpolates, і напишіть невелику
mapToDocumentRequest(data)function. - Iterate у Playground, доки output match.
- A/B у production: route 5% traffic до gPdf на два weeks. Diff PDFs. Compare bills.
- Roll forward або roll back на основі data, не vibes.
Ми бачили teams, які робили це за один sprint і економили 90% PDF bill наступного місяця. Ми також бачили teams, які розуміли, що їхній workload насправді HTML-to-PDF case, і залишалися на DocRaptor; це теж правильне decision.
TL;DR
| DocRaptor | gPdf | |
|---|---|---|
| Best at | HTML → PDF для arbitrary content | JSON → PDF для structured documents |
| Price (100K pages/mo) | $89 | $5 |
| p50 render | 250-800 ms | 3-8 ms |
| Edge-deployed | Ні, centralised | Так, 300+ Cloudflare colos |
| Async + storage | Так, included | Ні, stateless by design |
| PDF/A + Factur-X | Через Prince extensions | built-in |
Якщо ваші documents — це structured data, одягнена в HTML для renderer, ви платите за translation step, якого не має бути. Спробуйте Playground: describe один invoice у JSON, render у browser менш ніж за 5 ms і подивіться, чи gap збігається з вашим gut feeling.