NOW LET US – AI RAG SaaS Studio TP.HCM
NOW LET US
Digital Product Studio
Back to news
DEV-TOOLS...2 min read

SQLite in Production: Lessons from Running a Store on a Single File

Share
NOW LET US Article – SQLite in Production: Lessons from Running a Store on a Single File

A deep dive into running a real-world e-commerce store on SQLite, exploring the benefits of Rails 8, the mechanics of WAL mode, and the hidden risks of rapid deployments.

We run a production e-commerce store on SQLite. Not as a proof of concept. Not for a side project with three users. A real store, processing real Stripe payments, serving real customers.

Rails 8 made this a first-class choice. And for most of our operation, it's been excellent — simpler deploys, zero connection pooling headaches, no database server to manage. But "most of our operation" isn't all of it. Here's the part nobody warns you about.

The Setup: Four Databases, One Volume

Our database.yml defines four SQLite databases in production: Primary, Cache, Queue, and Cable. All four live in a storage/ directory that maps to a named Docker volume. One Docker volume. Four database files. Every container that mounts this volume shares the same data. This is both the feature and the footgun.

WAL Mode: Why It Works at All

SQLite's default journal mode locks the entire database on writes. WAL (Write-Ahead Logging) changes the model. Writers append to a separate -wal file instead of modifying the database directly. Readers continue reading from the main file. Multiple readers and a single writer can operate concurrently. Rails 8 enables WAL by default for SQLite databases.

The Day We Lost Two Orders

February 4th. We pushed 11 commits to main in two hours. Each push triggers a deploy via GitHub Actions. Kamal runs blue-green deploys — it starts a new container, health-checks it, then stops the old one. During the switchover, both containers are running. Both mount the storage. Both have the SQLite files open.

Eleven deploys in two hours? The overlap windows started overlapping. Three processes with the same WAL file open, all trying to write. Orders 16 and 17 completed successfully in Stripe, but the order records never made it to the database. Somewhere in the WAL file contention, the writes were lost.

We diagnosed it through sqlite_sequence: The auto-increment counter said 17 IDs had been assigned, but only 15 rows existed.

The Fix: Stop Deploying So Fast

The fix was procedural, not technical: stop pushing to main every ten minutes. This isn't a SQLite problem. It's a deployment pipeline problem that SQLite makes visible. Postgres handles this fine because connections go through a TCP socket. SQLite's write ordering depends on filesystem-level locking on a shared Docker volume, and that breaks down when containers overlap.

The Gotchas Nobody Mentions

  • No ILIKE: Use WHERE LOWER(name) LIKE '%term%' instead.
  • JSON types: Always CAST(json_extract(...) AS TEXT) when you need string comparison.
  • RAM usage: Spawning an exec container for a quick database query adds significant RAM overhead. On small machines, this can trigger the OOM killer during deploys.
  • Timeout 5000: If you're hitting SQLITE_BUSY regularly, you have a concurrency problem that configuration can't fix.

Would We Choose SQLite Again?

Yes. For a single-server deployment with moderate write volume, SQLite eliminates an entire category of infrastructure complexity. The constraint is real: one server, and careful deploy pacing. The day we need horizontal scaling, we'll migrate to Postgres. Until then, a single file handles everything.

© 2026 Now Let Us. All rights reserved.

Source: Hacker News

Advertisement
Ad slot ready: 5887729102

More in this category

NOW LET US Related – Treating pancreatic tumours may have revealed cancer's master switch

dev-tools

Treating pancreatic tumours may have revealed cancer's master switch

A promising new drug called daraxonrasib has shown breakthrough results in treating pancreatic cancer, doubling median survival times. This achievement could pave the way for an entirely new class of cancer treatments.

NOW LET US Related – Leaving Mozilla

dev-tools

Leaving Mozilla

A poignant and candid reflection from a 15-year Mozilla veteran upon their departure. The author highlights the leadership's missteps in trying to emulate tech giants and urges Mozilla to return to its core values: community and uniqueness.

NOW LET US Related – Shepherd's Dog: A Game by the Most Dangerous AI Model

dev-tools

Shepherd's Dog: A Game by the Most Dangerous AI Model

A developer tested Anthropic's latest, supposedly 'too dangerous' AI model by asking it to build a long-held game idea in a single shot. The model succeeded, generating a complete 2,319-line game after a 45-minute reasoning session.

NOW LET US Related – Open source AI must win

dev-tools

Open source AI must win

If artificial intelligence becomes a utility rented only from a few closed institutions, humanity loses its operational freedom. Open-source AI is a vital infrastructure for the future of our digital society.

NOW LET US Related – Statement on US government directive to suspend access to Fable 5 and Mythos 5

dev-tools

Statement on US government directive to suspend access to Fable 5 and Mythos 5

The US government has issued an export control directive forcing Anthropic to suspend all access to its Fable 5 and Mythos 5 models due to national security concerns, a move the AI safety startup strongly disputes.

NOW LET US Related – Electric motors with no rare earths

dev-tools

Electric motors with no rare earths

Renault Group is pioneering the development of electrically excited synchronous motors (EESM) that eliminate the need for rare earth magnets, reducing dependency on global monopolies while driving efficiency and sustainability.

EXPLORE TOPICS

Discover All Categories

Deep dive into the specific technology sectors that matter most to you.