DocRaptor là product có năng lực. Nó wrap Prince, gold-standard engine của HTML-to-PDF, trong hosted REST API với retries, async jobs và docs tốt. Nó đã tồn tại hơn một decade, và với nhiều teams đó là obvious choice khi “không muốn tự vận hành Prince”.
Chúng tôi là một tool có shape khác. gPdf không nhận HTML; nó nhận structured JSON và render PDF trực tiếp tại Cloudflare edge. List-price gap ở 100K pages/month là $5/mo (gPdf Basic) vs $89/mo (DocRaptor Basic), khoảng 18×. Đây không phải opening promo. Nó mang tính structural. Post này giải thích vì sao structure tạo ra price đó, và mỗi tool thật sự fit ở đâu.
Hai kiến trúc đặt cạnh nhau
| Layer | DocRaptor (HTML → PDF) | gPdf (JSON → PDF) |
|---|---|---|
| Input | HTML + CSS, với Prince extensions for paged media | JSON DocumentRequest |
| Renderer | Prince, compiled C++ engine | Custom Rust engine, compiled to WebAssembly |
| Hosting | Centralised servers của DocRaptor, US datacentre region | Cloudflare Workers, mọi CF colo, 300+ cities |
| Cold start | Server-side worker pool | V8 isolate boot, single-digit ms |
| Per-render compute | Layout pass trên HTML/CSS, rồi Prince paginate | Direct typesetting, không có 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 |
Nếu bạn đọc hai columns này như “general HTML printer” so với “purpose-built document renderer”, bạn đã hiểu architectural decision. Mọi thứ khác, latency, cost, kể cả feature lists, đều downstream từ choice đó.
Thuế Prince
Prince tốt. Nó cũng làm việc mà hầu hết invoice/receipt/label workflows không cần: implement CSS Paged Media cho arbitrary HTML mà user có thể đưa vào; page-break rules, running headers, footnotes, cross-references, generated content boxes.
Generality đó có runtime cost. Để paginate arbitrary HTML document, engine phải:
- Parse và validate HTML
- Parse và resolve CSS cascade, có thể với extensions riêng của Prince
- Build render tree
- Run multi-pass layout, nhất là tables spanning pages hoặc balanced columns
- Resolve cross-references across pages
- Emit PDF objects
Hầu hết các passes này là chi phí của việc chấp nhận HTML làm input. Nếu input của bạn đã là structured data, điều gần như luôn đúng vì invoice tồn tại như JSON object ở đâu đó trước khi bạn wrap nó thành HTML, bạn đang trả compute và latency cho các passes này ở mỗi render mà chúng không thêm value cho output.
gPdf bỏ hẳn layout-interpretation step. JSON DocumentRequest đã structurally specify page layout: { pages: [{ size, elements: [...] }] }. Renderer typeset elements, paginate tables/lists deterministically và emit PDF. Không có CSS cascade để resolve, không có float layout để compute, không có cross-reference resolution pass.
Kết quả: cùng một single-page invoice mất ~300 ms trên DocRaptor chỉ mất ~3 ms trên gPdf. Chúng tôi nhanh hơn không phải vì viết Prince nhanh hơn; chúng tôi nhanh hơn vì không làm phần lớn việc Prince làm.
”Quá rẻ để là thật” là procurement objection thực tế
Cần address trực tiếp vì nó xuất hiện trong mọi B2B sales call.
“$5/mo cho 100K renders. DocRaptor là $89. Anvil là $0.10/PDF, tức $10,000 cho same volume. Có gì sai với các bạn?”
Có ba lý do trung thực khiến chúng tôi có thể charge price này:
1. Chúng tôi không run browser
DocRaptor amortises Prince infrastructure across customers. gPdf amortises one Cloudflare Worker, có cost khoảng $0.50/million requests trên Workers Bundled. Với JSON-shaped input, renderer của chúng tôi dùng khoảng 1.5 ms CPU per render. Thêm margin 50% vẫn nằm trong range cents-per-thousand-renders. Arithmetic chính là price.
2. Chúng tôi không run control plane
Không async jobs, callbacks, retry queue, document storage, preview-link UI, multi-tenant database. Mỗi render là một single round-trip tới stateless function rồi quay về. Điều này loại bỏ toàn bộ ops surface mà đa số “PDF API” companies phải budget, cũng là surface justify price của họ.
3. Model tự lọc workloads khiến chúng tôi lỗ
Nếu document của bạn thật sự cần HTML-to-PDF, ví dụ 60-page legal contract hoặc complex CSS-Grid report, bạn sẽ bounce khỏi JSON model trong giờ đầu và đi DocRaptor. Chúng tôi không cần defensive pricing cho các workloads đó vì chúng self-route. Chúng tôi chỉ cần price long-but-narrow tail của “structured-data-to-document” workloads, nơi per-render cost thật sự tiny.
Gộp lại: $5/100K không phải loss leader; đó là actual cost-of-goods-sold plus margin. Chúng tôi có thể giữ nó vì underlying compute thật sự rẻ như vậy khi bạn không ship browser.
Khi DocRaptor là choice đúng
Chúng tôi cố không viết comparison tự phục vụ. Các cases DocRaptor thật sự thắng:
- Input của bạn là HTML bạn không control hoàn toàn. User-generated reports, third-party templates, Markdown-from-CMS-rendered-to-HTML. Bạn không muốn viết JSON mapper cho arbitrary input.
- Bạn cần CSS Paged Media features Prince supports. Running headers/footers per chapter, complex footnote reflow, named-page selectors, generated tables of contents, indexes. gPdf có structured equivalents cho common subset, nhưng nếu bạn sống trong
@page :leftselectors, Prince là bạn của bạn. - Bạn có content team viết HTML/CSS, không viết JSON. Đừng ép JSON authoring workflow lên non-engineering team. Họ sẽ ghét bạn.
- Async + callbacks + document storage as a service. DocRaptor stores generated PDFs và đưa signed URLs để delivery. gPdf strictly stateless; code của bạn stores result.
Nếu bạn thuộc bất kỳ bucket nào, hãy ở lại DocRaptor. Đó là tool đúng.
Khi gPdf là choice đúng
Ảnh đối xứng:
- Inputs của bạn đã là structured data: database rows, JSON API payloads, queue messages.
- Latency quan trọng: interactive checkout flows, real-time label printing, on-demand statement generation.
- Bạn quan tâm byte-identical reproducibility cho tests, audit trails hoặc e-invoice retention.
- Bạn cost-sensitive ở bất kỳ volume nào trên vài thousand renders/month.
- Bạn cần barcodes như GS1-128, QR, Data Matrix, PDF417, Aztec, MaxiCode ở sub-millimetre precision. Prince technically supports SVG barcodes, nhưng đạt 0.1 mm overall length precision qua HTML/CSS là non-trivial.
- Bạn cần PDF/A (1b/2b/3b/4) hoặc Factur-X / ZUGFeRD attachments cho compliance.
- Bạn không muốn run JSON-to-HTML-to-PDF pipeline khi có thể run JSON-to-PDF pipeline.
Migration là mechanical, không strategic
Worry phổ biến: “Switching nghĩa là rewrite toàn bộ templates.” Thường không phải vậy. Most HTML-to-PDF templates là 20% layout, thứ trở thành JSON structure một lần, và 80% data interpolation, giống nhau bất kể renderer nhận gì.
Practical path:
- Chọn một document type để migrate. Bắt đầu với highest-volume one: biggest savings, smallest blast radius.
- Lấy data interface của HTML template, tức variables nó interpolates, rồi viết function nhỏ
mapToDocumentRequest(data). - Iterate trong Playground đến khi output match.
- A/B trong production: route 5% traffic sang gPdf trong hai weeks. Diff PDFs. Compare bills.
- Roll forward hoặc roll back theo data, không theo vibes.
Chúng tôi đã thấy teams làm việc này trong một sprint và giảm 90% PDF bill tháng tiếp theo. Chúng tôi cũng thấy teams nhận ra workload của họ thật ra là HTML-to-PDF case và ở lại DocRaptor; đó cũng là decision đúng.
TL;DR
| DocRaptor | gPdf | |
|---|---|---|
| Best at | HTML → PDF cho arbitrary content | JSON → PDF cho structured documents |
| Price (100K pages/mo) | $89 | $5 |
| p50 render | 250-800 ms | 3-8 ms |
| Edge-deployed | Không, centralised | Có, 300+ Cloudflare colos |
| Async + storage | Có, included | Không, stateless by design |
| PDF/A + Factur-X | Qua Prince extensions | built-in |
Nếu documents của bạn là structured data mặc áo HTML cho renderer, bạn đang trả tiền cho translation step không cần tồn tại. Thử Playground: describe một invoice bằng JSON, render trong browser dưới 5 ms, rồi xem gap có khớp gut feeling của bạn không.