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.

DevOps Coach
DevOps Coach
DevOps Coach
Why Cloudflare Ditches ORM: sqlc’s Compile‑Time Type‑Safe SQL Beats GORM in Performance

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.

Cloudflare architecture diagram
Cloudflare architecture diagram

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 time

The 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 queries

Because 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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

performanceGoORMbenchmarkPostgressqlc
DevOps Coach
Written by

DevOps Coach

Master DevOps precisely and progressively.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.