Fastest Python PDF Generation in 2026: Sub-10ms Typst vs WeasyPrint
Generating PDFs in Python has historically forced developers to choose between two painful compromises: low-level coordinate plotting in ReportLab (clunky and tedious) or HTML/CSS conversion via WeasyPrint (which takes 2,000ms to 4,000ms per document).
Rubrol provides Python backends with a third path: compiling dynamic documents natively in Rust using Typst in under 10 milliseconds with less than 28MB RAM.
Python Benchmark Comparison
| Library / Tool | Average Latency | Memory Consumption | Layout Syntax | PDF/A-3b Compliance |
|---|---|---|---|---|
| WeasyPrint | 2,150 ms | 140 MB - 350 MB | HTML5 + CSS Paged Media | Partial |
| ReportLab | 180 ms | 45 MB | Canvas Coordinates & Flowables | Manual / Enterprise Add-on |
| pdfkit (wkhtmltopdf) | 680 ms | 95 MB | Deprecated WebKit | None |
| Rubrol (Typst Native) | 8.4 ms | < 28 MB | Typst Declarative Layout | Native Built-in |
Fast Python Implementation Example
You can run Rubrol as a local sidecar or via its high-speed Python bindings:
import httpx
# Compile a dynamic invoice in 8 milliseconds
client = httpx.Client(base_url="http://localhost:8080")
def create_invoice(invoice_number: str, items: list) -> bytes:
response = client.post(
"/v1/compile",
json={
"template": "billing_invoice",
"data": {
"number": invoice_number,
"items": items,
"currency": "EUR"
},
"compliance": "factur-x"
}
)
return response.content
# Save locally or stream directly to FastAPI response
pdf_bytes = create_invoice("INV-2026-99", [{"name": "Server Cluster", "price": 450.00}])
with open("invoice.pdf", "wb") as f:
f.write(pdf_bytes)
Experience Real-Time Document Compilation
Test the Typst layout engine live in your browser and see execution speeds under 10ms.
Test the Compiler Studio