Back to Blog
Engineering March 5, 2026 · 9 min read

SQLite Is the Production Database You Already Know (You Just Don't Know It Yet)

GM

Gonzalo Monzón

Founder & Lead Architect

In January 2024, DHH — creator of Ruby on Rails, CTO of 37signals — tweeted something that made a lot of database administrators uncomfortable: "We were testing out ONCE #1 on a big AWS instance and hitting 30,000 concurrent users on our metrics. Pretty cool to see that using sqlite!" Two years later, the trend he signaled has become a full-blown movement. And we've been living it — 14+ products running on SQLite at the edge via Cloudflare D1. $5/month for the database layer.

DHH's Bet: SQLite for Real Products

When DHH tested ONCE Campfire (37signals' self-hosted team chat) with 30,000 concurrent users hitting SQLite, the response from the community was predictable: "But can it handle writes?" His answer: yes, it was writing.

The conversation that followed was revealing:

"Are these 30k concurrent users just reading or writing as well to SQLite?" — @mistyHarsh

"Writing." — @dhh

When someone pointed out Ruby might be the bottleneck, DHH clarified they actually hit max IOPS against SQLite on that particular box — and wanted to rerun the test on Gen 5 SSD hardware to push it further. The bottleneck wasn't the language or the framework. It was disk speed.

For backups? "Just periodic backups that rollup both the sqlite DB and the Active Storage stuff into a single file you can do whatever with." No streaming replication. No WAL shipping to S3. A file copy. That's it.

This isn't a toy experiment. Campfire is a production chat app where concurrent writes are constant — messages, presence updates, notifications. DHH acknowledged the write lock is real ("The lock can definitely be an issue, if you're not paying attention") but said the optimizations they made were "very helpful optimizations anyway. So no biggie!"

Why SQLite? The Numbers Don't Lie

SQLite is the most deployed database in the world. Not Postgres. Not MySQL. Not MongoDB. SQLite. It runs on every smartphone, every browser, every Mac, every IoT device. Over 1 trillion active databases exist worldwide.

Here's why the industry is converging on it for server workloads too:

FactorTraditional DBSQLite
DeploymentSeparate server, connection strings, authA single file. Deploy with your app
LatencyNetwork round-trip (1-10ms)In-process (~0.01ms per read)
OperationsBackups, replication, failover, upgradesCopy a file. That's the backup
Cost (managed)$50-200+/month (RDS, PlanetScale, Neon)$0-5/month
Scaling readsRead replicas, connection poolingReplicate the file to edge nodes
SQL supportFullFull: window functions, CTEs, JSON, FTS5

A colleague once told me when he learned about our stack: "The problem is that people are going to freak out if you tell them you'll use SQLite to store their data in production." And he's right — there's a perception gap. But that gap is closing fast as more companies prove it works.

The one limitation everyone brings up — single writer — turns out to be fine for most applications. DHH proved it with 30K concurrent users. We prove it daily with our entire platform.

Our Stack: 14+ Products on D1 (SQLite at the Edge)

We don't run SQLite on a single server. We use Cloudflare D1 — SQLite distributed globally across Cloudflare's 300+ data centers. Every query runs at the edge, near the user. Here's what we run on a single D1 database:

ProductWhat D1 StoresMigrations
CadencesProjects, tasks, AI call logs, workflows, users107+
CIMAD RISPatient records, appointments, DICOM refs15+
GoViajesTravel leads, bookings, AI interactions12+
NutriNenBaby nutrition data, meal plans, recipes8+
VOIDGame state, player data, AI narratives5+
NewsletterSubscribers across all orgs (unified table)1
HeartbeatHealth metrics, wellness data, alerts6+

Total: 150+ migrations, single D1 database, $5/month. The same data on AWS RDS PostgreSQL would cost $50-150/month minimum — and that's before you add read replicas, connection pooling (PgBouncer), and backup storage.

The Write Lock: Real But Overblown

The most common objection to SQLite in production is the single-writer limitation. WAL mode (Write-Ahead Logging) helps enormously — concurrent reads continue while writes happen — but you still get one writer at a time.

DHH's take on it is pragmatic:

"The lock can definitely be an issue, if you're not paying attention. We had to change a few things to ensure we were being more efficient with the writes, but in the end those were very helpful optimizations anyway."

Our experience is identical. The optimizations you make for SQLite's write discipline — batching writes, keeping transactions brief, avoiding long-held locks — are just good engineering practices that make any database perform better. Here's what we do:

  • Batch inserts — Instead of 100 individual INSERTs, one transaction with 100 statements. 50-100x faster
  • Quick transactions — Get in, write, get out. No API calls or AI inference inside a transaction
  • Separate databases for separate concerns — DHH mentioned "1 dbfile per service" for things like Solid Queue. We keep our D1 focused on application data, not job queues or caching
  • Async writes where possible — Log the event immediately, process it asynchronously. The user doesn't wait for the analytics write

In practice, the write lock has never been our bottleneck. Network latency, AI provider response times, and external API calls are orders of magnitude slower than any SQLite lock wait.

D1: SQLite + Edge Distribution = Superpowers

What makes D1 different from just running SQLite on a VPS is the edge distribution. Your database isn't in us-east-1 — it's replicated to wherever your users are.

User in Barcelona → Cloudflare Madrid edge → D1 read  (~2ms)
User in São Paulo  → Cloudflare GRU edge    → D1 read  (~3ms)
User in Tokyo      → Cloudflare NRT edge    → D1 read  (~2ms)

vs. Traditional DB:
User in Barcelona → AWS us-east-1           → DB query (~80-120ms)

For writes, D1 routes to the primary (which is in a single region), but reads — which are 80-90% of most workloads — are served locally. Combined with Workers' zero cold start, our API responses consistently land in the 5-15ms range globally.

And the tooling is solid. D1 supports:

  • Migrations via Wrangler (wrangler d1 migrations apply)
  • Time travel — query your database as it was at any point in the last 30 days
  • Branching — create a copy of your DB for testing without affecting production
  • HTTP API — query from anywhere, not just Workers

The SQLite-Everywhere Movement

It's not just us and DHH. The industry is converging:

  • Turso/libSQL — SQLite fork with server mode, embedded replicas, multi-tenancy. $0 to start
  • LiteFS by Fly.io — Distributed SQLite with automatic replication
  • Cloudflare D1 — SQLite on the edge (what we use)
  • Litestream — Streaming SQLite replication to S3
  • SQLite in Bun — Built-in SQLite support, no driver needed
  • Expo SQLite — SQLite for React Native with sync capabilities
  • val.town, Notion, Plausible — More companies adopting SQLite for production

The pattern is clear: take the most reliable, best-tested database engine in history (SQLite has 100% branch coverage in its test suite — over 92,000 test cases), and solve the distribution problem at the infrastructure layer. Don't replace SQLite with a "cloud-native" database. Put SQLite in the cloud.

When NOT to Use SQLite

We're not SQLite zealots. There are cases where it's the wrong choice:

  • Multi-writer requirements — If you genuinely need multiple processes writing simultaneously at very high throughput, Postgres or MySQL are better
  • Complex replication topologies — Multi-primary, geo-distributed writes with conflict resolution requires a distributed database
  • Very large datasets — D1 has a 10GB limit per database. If you need terabytes, look elsewhere
  • Heavy analytics — OLAP workloads with massive JOINs across huge tables favor columnar stores like ClickHouse or DuckDB

But here's the thing — most applications don't hit these limits. Most apps are CRUD with some complexity. And for CRUD, SQLite is absurdly fast, absurdly reliable, and absurdly cheap.

The Cost Argument Alone Is Enough

ServiceMonthly CostWhat You Get
Cloudflare D1$55M reads/day, 100K writes/day, 5GB storage
Neon (Postgres)$19+Comparable tier
PlanetScale (MySQL)$39+Comparable tier
AWS RDS (Postgres)$50-150+db.t3.micro + storage + backups
Supabase (Postgres)$25+Comparable tier

We run 14+ products, 150+ migrations, multiple tables with millions of rows, real-time queries from AI agents and voice bots, workflow state machines, and a newsletter system serving multiple organizations — all for $5/month in database costs.

Even if SQLite were slightly less capable than Postgres (it isn't, for our use case), the 10-30x cost reduction alone justifies the choice.

Key Takeaways

1. SQLite is production-ready for serious workloads. DHH proved it with 30K concurrent writers. We prove it daily with 14+ products. The "SQLite is for testing" era is over. The write lock exists, but the optimizations you make to handle it are just good engineering — batch writes, short transactions, async processing.

2. The edge changes everything for SQLite. D1, Turso, LiteFS — these projects solve SQLite's biggest limitation (single-server) by distributing reads globally. Your database is a 2ms query away from any user on Earth, not a 100ms round-trip to us-east-1.

3. Cost at our scale is 10-30x lower than managed Postgres/MySQL. $5/month vs. $50-150/month. For a startup or small team, that's the difference between viable and burning cash on infrastructure. Every dollar not spent on database hosting is a dollar invested in product.

4. The backup story is elegantly simple. As DHH said: "Just periodic backups that rollup both the sqlite DB and the Active Storage stuff into a single file." No WAL shipping, no replication lag, no point-in-time recovery complexity. Copy a file. Done. D1 adds time travel on top of this for up to 30 days.

5. The industry is converging on SQLite. When DHH, Cloudflare, Fly.io, Bun, and a growing list of companies all bet on SQLite for production workloads, it's not a fad — it's a correction. The market overindexed on complex distributed databases when 90% of applications would be better served by the most tested database engine ever written.

Tags

SQLite D1 Cloudflare Database Architecture Edge Computing DHH

About the Author

Gonzalo Monzón

Gonzalo Monzón

Founder & Lead Architect

Gonzalo Monzón is a Senior Solutions Architect & AI Engineer with over 26 years building mission-critical systems in Healthcare, Industrial Automation, and enterprise AI. Founder of Cadences Lab, he specializes in bridging legacy infrastructure with cutting-edge technology.

Stay in the loop

Get notified when we publish new articles about AI automation, use cases, and practical guides.