DocRaptor es un producto competente. Envuelve a Prince — el motor HTML-a-PDF de referencia — en una API REST alojada, con reintentos, jobs asíncronos y documentación decente. Lleva más de una década en el mercado y para muchos equipos es la opción evidente «no quiero ejecutar Prince yo mismo».
Nosotros somos una herramienta de otra forma. gPdf no acepta HTML en absoluto; toma JSON estructurado y renderiza directamente en el edge de Cloudflare. La diferencia en precio de lista a 100K páginas/mes: $5/mes (gPdf Basic) vs $89/mes (DocRaptor Basic) — alrededor de 18×. Esa diferencia no es promoción de apertura. Es estructural. Este post explica por qué la estructura produce ese precio y dónde encaja realmente cada herramienta.
Las dos arquitecturas, lado a lado
| Capa | DocRaptor (HTML → PDF) | gPdf (JSON → PDF) |
|---|---|---|
| Entrada | HTML + CSS (con extensiones Prince paged-media) | JSON DocumentRequest |
| Renderizador | Prince (motor C++ compilado) | Motor Rust propio, compilado a WebAssembly |
| Hosting | Servidores DocRaptor centralizados (datacenter US) | Cloudflare Workers, cada colo CF (300+ ciudades) |
| Cold start | Pool de workers en servidor | Boot de isolate V8, ms de un dígito |
| Compute por render | Pase de layout sobre HTML/CSS, luego Prince pagina | Composición directa, sin pase de interpretación de layout |
| p50 por render | ~250–800 ms wall-clock (red + render) | ~3–8 ms (red + render) |
| Determinismo de salida | Alto (Prince es maduro) | Byte-idéntico (mismo JSON → mismos bytes) |
Si lees esas dos columnas como «impresora HTML genérica» vs «renderizador de documentos hecho a medida», ya entendiste la decisión arquitectónica. Todo lo demás (latencia, costo, incluso las listas de funciones) es río abajo de esa única elección.
El impuesto Prince
Prince es bueno. También hace un trabajo que la mayoría de workflows de factura/recibo/etiqueta no necesitan: implementar CSS Paged Media — reglas de salto de página, headers continuos, notas al pie, referencias cruzadas, contenido generado — para HTML arbitrario que el usuario podría arrojar.
Esa generalidad tiene costo de runtime. Para paginar HTML arbitrario, el motor debe:
- Parsear y validar el HTML
- Resolver la cascada CSS (posiblemente con extensiones propias de Prince)
- Construir el árbol de render
- Ejecutar layout multi-pase (especialmente para tablas que cruzan páginas, o columnas que se balancean)
- Resolver referencias cruzadas entre páginas
- Emitir objetos PDF
La mayoría de esos pases son el costo de aceptar HTML como entrada. Si tu entrada ya son datos estructurados (que casi siempre lo son — tu factura existe como objeto JSON antes de envolverla en HTML), pagas esos pases en compute y latencia en cada render, y no agregan valor a la salida.
gPdf se salta el paso de interpretación de layout por completo. El JSON DocumentRequest ya especifica el layout estructuralmente — { pages: [{ size, elements: [...] }] }. El renderizador compone los elementos, pagina tablas/listas determinísticamente y emite PDF. Sin cascada CSS que resolver, sin layout de floats que computar, sin pase de resolución de referencias cruzadas.
Resultado: la misma factura de una página que toma ~300 ms en DocRaptor toma ~3 ms en gPdf. No somos más rápidos porque escribimos un Prince más rápido — somos más rápidos porque no hacemos la mayoría de lo que hace Prince.
«Demasiado barato para ser real» es una objeción de procurement real
Vamos a abordarlo directo porque sale en cada llamada de venta B2B.
«$5/mes por 100K renders. DocRaptor cuesta $89. Anvil cuesta $0,10/PDF (o sea $10.000 al mismo volumen). ¿Qué les pasa?»
Tres razones honestas por las que podemos cobrar esto:
1. No ejecutamos un navegador
DocRaptor amortiza la infraestructura de Prince entre clientes. gPdf amortiza un Cloudflare Worker, que cuesta cerca de $0,50/millón de requests en Workers Bundled. Con entrada en forma de JSON, nuestro renderizador toma cerca de 1,5 ms de CPU por render. Apila 50 % de margen y aún estás en el rango de centavos por mil renders. La aritmética es el precio.
2. No ejecutamos un control plane
No hay jobs asíncronos, callbacks, cola de retry, almacenamiento de documentos, UI de link de previsualización ni base de datos multi-tenant. Cada render es un único round-trip a una función sin estado y de vuelta. Eso elimina toda la superficie de ops que la mayoría de empresas de «PDF API» presupuestan — que también es la superficie que justifica su precio.
3. El modelo se autoselecciona fuera de las cargas en las que perderíamos dinero
Si tu documento genuinamente necesita HTML-a-PDF (contrato legal de 60 páginas, reporte CSS-Grid complejo), rebotarás del modelo JSON en la primera hora e irás a DocRaptor de todos modos. No tenemos que tarifar defensivamente para esas cargas porque se autoenrutan. Solo tenemos que tarifar para la cola larga pero estrecha de cargas «datos-estructurados-a-documento», donde el costo por render es genuinamente diminuto.
Juntos: $5/100K no es loss-leader, es el costo real de bienes vendidos más margen. Podemos mantenerlo ahí indefinidamente porque el compute subyacente es así de barato cuando no embarcas un navegador.
Dónde DocRaptor es la elección correcta
Tratamos de no escribir comparativas autointeresadas. Los casos donde DocRaptor genuinamente gana:
- Tu entrada es HTML que no controlas completamente. Reportes generados por usuarios, plantillas de terceros, Markdown-de-CMS-renderizado-a-HTML. No quieres escribir un mapper JSON para entradas arbitrarias.
- Necesitas funciones CSS Paged Media que Prince soporta. Headers/footers continuos por capítulo, reflow complejo de notas al pie, selectores de página nombrados, índices y tablas de contenido generadas. gPdf tiene equivalentes estructurados para el subconjunto común, pero si vives en selectores
@page :left, Prince es tu amigo. - Tienes un equipo de contenido que escribe HTML/CSS, no JSON. No impongas un workflow de autoría JSON a un equipo no de ingeniería. Te odiarán.
- Async + callbacks + almacenamiento de documentos como servicio. DocRaptor almacena los PDFs generados y te da URLs firmadas para entrega. gPdf es estrictamente sin estado — tu código almacena el resultado.
Si estás en cualquiera de esos cubos, quédate con DocRaptor. Es la herramienta correcta.
Dónde gPdf es la elección correcta
La imagen espejo:
- Tus entradas ya son datos estructurados (filas de base de datos, payloads de API JSON, mensajes de cola).
- La latencia importa — flujos de checkout interactivo, impresión de etiquetas en tiempo real, generación de extractos bajo demanda.
- Te importa la reproducibilidad byte-idéntica para tests / pistas de auditoría / retención de facturas electrónicas.
- Eres sensible al costo en cualquier volumen sobre unos miles de renders/mes.
- Necesitas códigos de barras (GS1-128, QR, Data Matrix, PDF417, Aztec, MaxiCode) con precisión submilimétrica.
- Necesitas PDF/A (1b/2b/3b/4) o adjuntos Factur-X / Facturae para compliance — especialmente relevante para el mandato español de factura electrónica B2B desde 2026 y los mandatos alemán/francés ya en vigor.
- Preferirías no ejecutar un pipeline JSON-a-HTML-a-PDF cuando puedes ejecutar un pipeline JSON-a-PDF.
Nota específica para equipos en España
Si tu contexto es el mandato español de factura electrónica B2B (en vigor desde 2026 vía sistema FACe / Facturae), gPdf produce el formato Factur-X esperado en una sola llamada API — PDF/A-3 + XML EN-16931 integrado en un paso:
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 factura.pdf
Sin post-pase Ghostscript, sin segunda herramienta para adjuntar el XML, sin lotería de validación entre pasos. Los bytes de salida son byte-idénticos entre versiones del motor, así que tu hash de retención para la obligación fiscal de 6 años puede mantenerse estable.
La migración es mecánica, no estratégica
Una preocupación común: «Cambiar significa reescribir todas nuestras plantillas». Generalmente no. La mayoría de plantillas HTML-a-PDF son 20 % layout (que se vuelve estructura JSON una sola vez) y 80 % interpolación de datos (que es exactamente lo mismo independientemente de qué tome el renderizador).
Camino práctico:
- Elige un tipo de documento para migrar. Empieza por el de mayor volumen — mayor ahorro, menor radio de explosión.
- Toma la interfaz de datos de la plantilla HTML (las variables que interpola) y escribe una pequeña función
mapToDocumentRequest(data). - Itera contra el Playground hasta que la salida coincida.
- A/B en producción: enruta 5 % del tráfico a gPdf durante dos semanas. Diff los PDFs. Compara facturas.
- Avanza o retrocede en base a datos, no a vibras.
TL;DR
| DocRaptor | gPdf | |
|---|---|---|
| Mejor para | HTML → PDF para contenido arbitrario | JSON → PDF para documentos estructurados |
| Precio (100K páginas/mes) | $89 | $5 |
| Render p50 | 250–800 ms | 3–8 ms |
| Edge-deployed | ❌ centralizado | ✅ 300+ colos Cloudflare |
| Async + storage | ✅ incluido | ❌ sin estado por diseño |
| PDF/A + Factur-X / ZUGFeRD | ⚠️ vía extensiones Prince | ✅ integrado |
Si tus documentos son datos estructurados disfrazados de HTML para un renderizador, estás pagando por un paso de traducción que no necesita existir. Prueba el Playground — describe una de tus facturas en JSON, renderízala en tu navegador en menos de 5 ms, mira si la diferencia coincide con tu intuición.