Language Guide

Fastest Python PDF Generation in 2026: Sub-10ms Typst vs WeasyPrint

By Rubrol Engineering Team • 5 min read • Updated September 2026

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