SQLite in Production: When a Single-File Database Is the Right Call
Most backend engineers, the moment they spin up a new project, reach for Postgres without a second thought. It is a reasonable default — battle-tested, feature-rich, and broadly supported. But defaults can become blind spots. There is a class of software products where SQLite is not just acceptable in production — it is the superior architectural choice. Understanding that class is what separates a reflexive decision from a deliberate one.
The Reputation Problem SQLite Doesn't Deserve
SQLite ships inside every Android device, every iOS app, every Firefox installation, and most embedded systems on the planet. It processes more queries per day than all other databases combined. Yet the moment a developer hears "production SaaS," they assume SQLite is off the table.
The concern usually boils down to three things: no network access, no concurrent writes, and no horizontal scaling. These are real constraints. They are also only relevant if your architecture actually requires those capabilities — and a surprising number of products do not.
The Product Profiles Where SQLite Wins
1. Embedded and Desktop Tools
If you are building a desktop application, a CLI tool, or a local-first app, SQLite is the obvious choice — not a compromise. Bundling a Postgres server with an Electron app is operationally absurd. SQLite gives you a full relational database in a single file, with zero configuration, zero daemon management, and instant startup.
Tools like Obsidian, Notion's local sync engine, and countless internal enterprise tools quietly use SQLite because it removes an entire operational layer. There is no connection pool to tune, no auth surface to secure, no separate backup job to schedule. The file is the database.
2. Per-Tenant SaaS Architecture
This is where SQLite's production story gets genuinely interesting. The conventional multi-tenant SaaS design puts every customer into one shared Postgres instance, separated by a tenant_id column. This works — until it doesn't. Noisy neighbors, schema migrations that lock shared tables, and backup granularity all become expensive problems at scale.
The alternative: one SQLite database file per tenant. Each tenant's data is physically isolated. A single bad query from one customer cannot degrade another's experience. Rolling back one tenant's data is a file copy, not a surgical SQL restore. Schema migrations can be rolled out incrementally per tenant rather than in one high-risk batch.
Platforms like Turso (built on libSQL, a fork of SQLite) and Cloudflare D1 have commercialized this pattern precisely because the isolation and simplicity properties are real and valuable. For SaaS products with hundreds or low-thousands of tenants, the per-tenant SQLite model often delivers better performance and simpler operations than a shared Postgres cluster.
3. Edge and Serverless Deployments
Network latency is the silent killer of API performance. When your serverless function cold-starts in a Frankfurt data center and your Postgres instance lives in us-east-1, you are paying a latency tax on every query — before your application logic runs a single line of code.
SQLite deployed at the edge eliminates this entirely. The database is co-located with the compute. Query latency drops to microseconds. There is no TCP handshake, no connection pool, no round trip across a continent.
Cloudflare D1, Fly.io's distributed SQLite approach with LiteFS, and similar platforms are not novelty projects — they are serious infrastructure responses to a real architectural problem. For read-heavy APIs, content delivery, configuration lookups, and feature flag systems, edge SQLite is measurably faster and cheaper than a centralized relational database.
Where SQLite Genuinely Does Not Belong
Being a fair advocate means being honest about the limits.
- High-concurrency write workloads: SQLite uses file-level locking for writes. If your product has dozens of processes hammering concurrent writes — think a high-traffic e-commerce checkout flow or a real-time auction system — you will hit contention. WAL mode helps significantly, but there is a ceiling.
- Multi-node shared state: Anything requiring multiple application servers to read and write the same live dataset in real time needs a network-accessible database. SQLite is not that.
- Analytics at scale: Columnar stores like DuckDB or BigQuery handle analytical queries over millions of rows far better than SQLite's row-oriented storage.
The signal is clear: if your bottleneck is write concurrency across distributed processes, choose Postgres. If your bottleneck is operational complexity, latency, or cost, SQLite deserves a serious look.
A Practical Architecture Decision Framework
Before defaulting to Postgres, answer these questions:
- Does the database need to be network-accessible from multiple hosts simultaneously? If no, SQLite is viable.
- Is tenant data isolation a first-class concern? If yes, per-tenant SQLite may be cleaner than row-level Postgres isolation.
- Is the deployment target the edge or a serverless environment? If yes, co-located SQLite will outperform a remote database on latency.
- What is the write concurrency profile? If peak concurrent writes are low (most SaaS products sit well under SQLite's practical ceiling), the locking concern is theoretical, not practical.
A quick illustrative migration check you can run on an existing SQLite file:
# Inspect page size, WAL mode, and integrity in one pass
sqlite3 ./myapp.db "PRAGMA page_size; PRAGMA journal_mode; PRAGMA integrity_check;"
Enabling WAL mode (PRAGMA journal_mode=WAL;) alone dramatically improves concurrent read performance and is the first thing you should configure for any production SQLite deployment.
The Operational Simplicity Dividend
Engineers undervalue operational simplicity until 2 AM when something breaks. A SQLite-backed service has no connection pool to exhaust, no replication lag to monitor, no separate database server to patch. Backups are a file copy. Restores are a file copy. The entire database is inspectable with a single open-source GUI tool.
For early-stage startups, indie SaaS products, and internal tooling — where engineering bandwidth is the scarcest resource — this simplicity dividend compounds over time.
Why This Matters for Your Project
If you are building a SaaS product at Code!nk Technologies or anywhere else, the database layer is one of the highest-leverage architectural decisions you will make early on. Choosing Postgres reflexively is not wrong, but choosing SQLite deliberately — for an embedded tool, a per-tenant data model, or an edge-deployed API — can meaningfully reduce your infrastructure costs, improve your latency profile, and cut your operational burden. The best database for your product is the one that fits your actual access patterns, not the one with the most GitHub stars.




