Why Cloudflare Ditches ORM: sqlc’s Compile‑Time Type‑Safe SQL Beats GORM in Performance
The article explains how Cloudflare’s production stack uses Go, Postgres and sqlc to avoid ORM overhead, presents benchmark data showing sqlc delivering double the throughput and far lower latency and memory usage than GORM, and offers a practical migration and learning roadmap.
Introduction
At massive scale (billions of requests), Cloudflare runs a Go + PostgreSQL stack with sqlc, achieving 99.99% uptime without the overhead of an ORM.
ORM Tax
ORMs such as GORM or Ent introduce N+1 query patterns, runtime reflection overhead, and fragile migrations. Under high load these issues cause tail‑latency spikes, memory bloat, and often force a fallback to raw SQL.
Compile‑time type safety with sqlc
sqlc reads .sql files and generates Go code (structs and query methods). The typical workflow is:
1. Write SQL in .sql files
2. Run `sqlc generate` → creates queries.go
3. Import generated types and call methods as native Go code
4. SQL syntax and type errors are caught at compile timeThe generated code encodes column types, nullability, and parameters, providing IDE autocomplete and immediate feedback on schema changes.
Performance benchmark
API query performance (10k concurrency)
Go + sqlc + pgx | 85K qps / p99=1.2ms
Go + GORM | 42K qps / p99=3.8ms (N+1)
Go + Ent | 38K qps / p99=4.2ms (reflection) Memory usage at scale
sqlc | 180 MB
GORM | 1.2 GB (reflection)Production stack used at Cloudflare
Cloudflare Go + sqlc + Postgres stack
├── sqlc (queries.sql → queries.go)
├── pgx (native driver, connection pool)
├── sqlc-pg (Postgres‑specific optimisations)
├── Zerolog (structured logging)
└── Prometheus (query‑latency histograms)SQL files are version‑controlled. Migrations run first; then sqlc generate regenerates code, ensuring observability without hidden query planners.
Zero‑downtime schema evolution
Migration workflow
1. Write new SQL and migration script
2. Run `sqlc generate` (adds new methods)
3. Deploy with dual‑read of old and new queries
4. Switch writes to new schema, then remove old queriesBecause each query is type‑checked, the compiler enforces compatibility, allowing gradual rollouts without service interruption.
Conclusion
The Go + Postgres + sqlc stack eliminates the ORM tax, delivering roughly double the throughput (85 K qps vs 42 K qps), two‑thirds lower p99 latency (1.2 ms vs 3.8 ms), and an order‑of‑magnitude lower memory usage (~180 MB vs >1 GB). Converting a single table to sqlc yields immediate performance and stability improvements.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
