DocRaptor é um produto competente. Encapsula Prince — o motor padrão-ouro de HTML-para-PDF — em uma API REST hospedada, com retries, jobs assíncronos e documentação decente. Existe há mais de uma década e para muitas equipes é a escolha óbvia «não quero rodar Prince eu mesmo».
Somos uma ferramenta de outra forma. gPdf não aceita HTML de forma alguma; recebe JSON estruturado e renderiza diretamente no edge da Cloudflare. A diferença de preço de tabela em 100K páginas/mês: $5/mês (gPdf Basic) vs $89/mês (DocRaptor Basic) — cerca de 18×. Essa diferença não é promoção de abertura. É estrutural. Este post explica por que a estrutura produz esse preço e onde cada ferramenta realmente se encaixa.
As duas arquiteturas, lado a lado
| Camada | DocRaptor (HTML → PDF) | gPdf (JSON → PDF) |
|---|---|---|
| Entrada | HTML + CSS (com extensões Prince paged-media) | JSON DocumentRequest |
| Renderer | Prince (engine C++ compilada) | Engine Rust própria, compilada para WebAssembly |
| Hospedagem | Servidores DocRaptor centralizados (datacenter US) | Cloudflare Workers, todo colo CF (300+ cidades) |
| Cold start | Pool de workers do lado servidor | Boot de isolate V8, ms de um dígito |
| Compute por render | Pass de layout sobre HTML/CSS, depois Prince pagina | Composição direta, sem pass de interpretação de layout |
| p50 por render | ~250–800 ms wall-clock (rede + render) | ~3–8 ms (rede + render) |
| Determinismo da saída | Alto (Prince é maduro) | Byte-idêntico (mesmo JSON → mesmos bytes) |
Se você lê essas duas colunas como «impressora HTML genérica» vs «renderer de documentos construído para o propósito», já entendeu a decisão arquitetural. Tudo mais (latência, custo, até as listas de features) é a jusante dessa única escolha.
O imposto Prince
Prince é bom. Também faz um trabalho que a maioria dos workflows fatura/recibo/etiqueta não precisa: implementar CSS Paged Media — regras de quebra de página, headers contínuos, notas de rodapé, referências cruzadas, conteúdo gerado — para HTML arbitrário que o usuário possa jogar.
Essa generalidade tem custo de runtime. Para paginar HTML arbitrário, a engine deve:
- Parsear e validar o HTML
- Resolver cascata CSS (potencialmente com extensões próprias do Prince)
- Construir árvore de render
- Executar layout multi-pass (especialmente para tabelas que cruzam páginas, ou colunas balanceando)
- Resolver referências cruzadas entre páginas
- Emitir objetos PDF
A maioria desses passes é o custo de aceitar HTML como entrada. Se sua entrada já é dado estruturado (e quase sempre é — sua fatura existe como objeto JSON antes de envolvê-la em HTML), você está pagando por esses passes em compute e latência a cada render, e eles não adicionam valor à saída.
gPdf pula completamente o passo de interpretação de layout. O DocumentRequest JSON já especifica o layout de página estruturalmente — { pages: [{ size, elements: [...] }] }. O renderer compõe os elementos, pagina tabelas/listas deterministicamente e emite PDF. Sem cascata CSS para resolver, sem layout de floats para computar, sem pass de resolução de referências cruzadas.
Resultado: a mesma fatura de uma página que leva ~300 ms no DocRaptor leva ~3 ms no gPdf. Não somos mais rápidos porque escrevemos um Prince mais rápido — somos mais rápidos porque não fazemos a maior parte do que Prince faz.
«Barato demais para ser verdade» é uma objeção real de procurement
Vamos endereçar isso diretamente porque surge em toda call de vendas B2B.
«$5/mês para 100K renders. DocRaptor é $89. Anvil é $0,10/PDF (ou seja $10.000 no mesmo volume). O que há de errado com vocês?»
Três razões honestas pelas quais podemos cobrar isso:
1. Não rodamos um navegador
DocRaptor amortiza infraestrutura Prince entre clientes. gPdf amortiza um Cloudflare Worker, que custa cerca de $0,50/milhão de requests no Workers Bundled. Com entrada em forma JSON, nosso renderer leva cerca de 1,5 ms de CPU por render. Empilhe 50% de margem e você ainda está na faixa de centavos-por-mil-renders. A aritmética é o preço.
2. Não rodamos um control plane
Sem jobs assíncronos, sem callbacks, sem fila de retry, sem armazenamento de documentos, sem UI de link de preview, sem banco multi-tenant. Cada render é um único round-trip a uma função stateless e volta. Isso remove toda a superfície ops que a maioria das empresas «PDF API» orçam — que é também a superfície que justifica o preço delas.
3. O modelo se autoseleciona fora dos workloads em que perderíamos dinheiro
Se seu documento genuinamente precisa de HTML-para-PDF (contrato legal de 60 páginas, relatório CSS-Grid complexo), você vai ricochetear do modelo JSON na primeira hora e ir para DocRaptor de qualquer forma. Não precisamos precificar defensivamente para esses workloads porque eles se autoroteiam. Só precisamos precificar para a cauda longa mas estreita de workloads «dados-estruturados-para-documento», onde o custo por render é genuinamente minúsculo.
Juntos: $5/100K não é loss-leader, é o custo de bens vendidos real mais margem. Podemos manter isso indefinidamente porque o compute subjacente é tão barato quando você não embarca um navegador.
Onde DocRaptor é a escolha certa
Tentamos não escrever comparativos auto-interessados. Os casos onde DocRaptor genuinamente vence:
- Sua entrada é HTML que você não controla completamente. Relatórios gerados por usuários, templates de terceiros, Markdown-de-CMS-renderizado-para-HTML. Você não quer escrever um mapper JSON para entradas arbitrárias.
- Você precisa de features CSS Paged Media suportadas por Prince. Headers/footers contínuos por capítulo, reflow complexo de notas de rodapé, seletores de página nomeados, índices e sumários gerados. gPdf tem equivalentes estruturados para o subconjunto comum, mas se você vive em seletores
@page :left, Prince é seu amigo. - Você tem time de conteúdo escrevendo HTML/CSS, não JSON. Não imponha workflow de autoria JSON a um time não-engineering. Eles vão te odiar.
- Async + callbacks + armazenamento de documentos como serviço. DocRaptor armazena PDFs gerados e te dá URLs assinadas para entrega. gPdf é estritamente stateless — seu código armazena o resultado.
Se você está em qualquer desses baldes, fique no DocRaptor. É a ferramenta certa.
Onde gPdf é a escolha certa
A imagem espelho:
- Suas entradas são já dados estruturados (linhas de banco, payloads JSON API, mensagens de fila).
- Latência importa — fluxos de checkout interativo, impressão de etiquetas em tempo real, geração de extratos sob demanda.
- Você se importa com reprodutibilidade byte-idêntica para testes / trilhas de auditoria / retenção de notas fiscais eletrônicas.
- Você é sensível a custo em qualquer volume acima de alguns milhares de renders/mês.
- Você precisa de códigos de barras (GS1-128, QR, Data Matrix, PDF417, Aztec, MaxiCode) com precisão sub-milimétrica.
- Você precisa de PDF/A (1b/2b/3b/4) ou anexos Factur-X / ZUGFeRD para compliance — particularmente relevante para o mandato brasileiro NF-e (em vigor há mais de uma década) e os mandatos europeus em rollout 2024-2027.
- Você prefere não rodar um pipeline JSON-para-HTML-para-PDF quando pode rodar um pipeline JSON-para-PDF.
Nota específica para times no Brasil sobre NF-e
Se seu contexto é o ecossistema brasileiro de Nota Fiscal Eletrônica (NF-e) — XML estruturado obrigatório transmitido via SEFAZ desde 2008, com DANFE (representação visual em PDF) — a arquitetura conceitual é idêntica ao Factur-X: XML máquina-legível + representação visual humana. gPdf produz tanto o DANFE quanto pode anexar o XML NF-e via PDF/A-3:
curl -X POST https://gpdf.com/api/v1/e-invoice/render \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
--data '{
"document": { "pages": [{ "size": "a4", "elements": [...] }] },
"einvoice": {
"format": "factur-x",
"profile": "BASIC",
"xml": "<rsm:CrossIndustryInvoice>...</rsm:CrossIndustryInvoice>"
}
}' \
--output nfe.pdf
Para integração internacional (clientes EU exigindo Factur-X, ou exportação para mercados com mandatos próprios), o mesmo endpoint com format: factur-x produz o formato EN 16931 padrão.
Sem post-pass Ghostscript, sem segunda ferramenta para anexar o XML, sem loteria de validação entre passos. Os bytes de saída são byte-idênticos entre versões da engine, então seu hash de retenção para a obrigação de guarda fiscal de 5 anos pode permanecer estável.
Migração é mecânica, não estratégica
Uma preocupação comum: «Trocar significa reescrever todos os nossos templates». Geralmente não. A maioria dos templates HTML-para-PDF são 20% layout (que vira estrutura JSON uma vez) e 80% interpolação de dados (que é exatamente o mesmo independente do que o renderer aceita).
Caminho prático:
- Escolha um tipo de documento para migrar. Comece pelo de maior volume — maior economia, menor raio de explosão.
- Pegue a interface de dados do template HTML (as variáveis que ele interpola) e escreva uma pequena função
mapToDocumentRequest(data). - Itere contra o Playground até a saída combinar.
- A/B em produção: roteie 5% do tráfego para gPdf por duas semanas. Diff os PDFs. Compare faturas.
- Avance ou recue baseado em dados, não vibrações.
TL;DR
| DocRaptor | gPdf | |
|---|---|---|
| Melhor para | HTML → PDF para conteúdo arbitrário | JSON → PDF para documentos estruturados |
| Preço (100K páginas/mês) | $89 | $5 |
| Render p50 | 250–800 ms | 3–8 ms |
| Edge-deployed | ❌ centralizado | ✅ 300+ colos Cloudflare |
| Async + storage | ✅ incluído | ❌ stateless por design |
| PDF/A + Factur-X / ZUGFeRD | ⚠️ via extensões Prince | ✅ embutido |
Se seus documentos são dados estruturados disfarçados de HTML para um renderer, você está pagando por um passo de tradução que não precisa existir. Experimente o Playground — descreva uma de suas faturas em JSON, renderize-a no seu navegador em menos de 5 ms, veja se a diferença bate com sua intuição.