← Graph

How (and why) to run SQLite in production

talk 32 connections

Stephen Margheim's wroclove.rb 2024 single-speaker talk arguing that SQLite is a viable choice for production Rails applications and often a better default than cloud-managed Postgres for solo developers and small teams. Frames SQLite as the 'one-person database engine' paired with Rails as the 'one-person framework' (simplicity, control, speed). Addresses the linear-writes objection by benchmarking: you can run ~10 SQLite writes in the time one self-hosted Postgres write takes on the same machine, ~20-30 across availability zones, and ~1,000 when Postgres is in a different AWS region (using Ben Johnson's 2021 GopherCon data). Uses a Hacker News clone ('laurem news') with a load-testing CLI to reveal four performance problems and their fixes: (1) SQLite3::BusyException under concurrent writes → solve with immediate-mode transactions via the sqlite3 gem's default_transaction_mode (1.6.9+) instead of deferred mode, because Rails always writes inside transactions and deferred mode errors immediately on retry; (2) 5-second latency spikes caused by SQLite's C busy_timeout holding Ruby's GVL → replace with a Ruby-level busy_handler callback that uses Sleep (which releases the GVL), letting Puma workers do real work during DB waits; (3) long-tail p99.9 latency caused by SQLite's native timeout algorithm penalizing older queries with exponential-ish backoff (a 12-entry delays array ending at 100ms) while new queries retry at 1-2ms → replace with a fair constant-1ms retry (now merged into sqlite3 main, aimed at Rails 8); (4) contended connection pool when reads wait on writes → experimental isolated reader/writer connection pools via Active Record's multiple-database support pointing two role configs at the same file, a custom database selector that defaults every request to reading and a monkey-patched transaction method that switches to the writer role for writes ('deferred requests'). Also notes WAL (write-ahead-log) journal mode became the Rails 7.1 default. Resilience section recommends Litestream for point-in-time backups to any S3-compatible bucket from day one. Discusses additional features of the enhanced-sqlite3-adapter gem: backported deferred foreign keys, virtual columns, custom returning values, pragmas via database.yml, SQLite extension loading via database.yml, and branch-specific databases via ERB shell expansion in database.yml and active_record tasks database prepare. Promotes sqlite-compile-flags tuning through Bundler (work done with Mike Dalessio) for compilation customization. Q&A covers security trade-offs of an embedded database (single attack surface vs. hardening trade-off) and migrating from SQLite to Postgres (easier than the reverse — SQLite's types are a subset, Active Record abstracts the rest).

type
talk
talk How (and why) to run SQLite in production
about
SQLite tool
Core subject of the talk.
talk How (and why) to run SQLite in production
about
Focuses on SQLite for Rails applications specifically.
talk How (and why) to run SQLite in production
about
The talk walks through what the gem does and why.
talk How (and why) to run SQLite in production
about
Litestream tool
Talk recommends Litestream and the litestream Ruby gem for resilience.
talk How (and why) to run SQLite in production
about
First performance fix demonstrated in the talk.
talk How (and why) to run SQLite in production
about
Second and third performance fixes (GVL release and fair retry) are implementations of a custom busy_handler.
talk How (and why) to run SQLite in production
about
Fourth of the four performance keys; now a Rails 7.1 default.
talk How (and why) to run SQLite in production
about
Experimental fifth performance technique demonstrated via Active Record's multi-database support.
talk How (and why) to run SQLite in production
about
Invented concept for making isolated reader/writer pools transparent to controllers.
talk How (and why) to run SQLite in production
about
Developer-experience tip demonstrated near the end of the talk.
talk How (and why) to run SQLite in production
about
Core reason SQLite's native busy_timeout harms Rails concurrency — it holds the GVL.
talk How (and why) to run SQLite in production
about
Active Record concept
Discusses Active Record's connection pool, transaction wrapping, and multi-database support.
talk How (and why) to run SQLite in production
about
PostgreSQL tool
Extensive comparison between running SQLite and running Postgres in various cloud topologies.
talk How (and why) to run SQLite in production
about
N+1 Queries concept
Notes the SQLite docs' advice that you should probably not prematurely optimize away N+1 queries when using SQLite.
talk How (and why) to run SQLite in production
about
Solid Queue project
Mentions the 'solid' ecosystem as a good fit for a SQLite-foundation future of Rails.
talk How (and why) to run SQLite in production
about
Solid Cache project
Mentions Solid Cache alongside Solid Queue in the SQLite-foundation vision.
talk How (and why) to run SQLite in production
about
Solid Cable project
Margheim looks forward to having a cable.sqlite3 file once Solid Cable ships.
talk How (and why) to run SQLite in production
about
Turso company
Cited as an example of a generous free tier enabled by SQLite's cost profile.
talk How (and why) to run SQLite in production
about
DHH person
Cites DHH's Rails World keynote reiterating Rails as the one-person framework.
talk How (and why) to run SQLite in production
about
Hatchbox tool
Cites Hatchbox as making single-node deployment easy.
talk How (and why) to run SQLite in production
about
LiteFS tool
Mentioned as the option when you genuinely need multi-node SQLite.
asked_at
How (and why) to run SQLite in production talk
Q&A after Margheim's talk.
asked_at
How (and why) to run SQLite in production talk
Q&A after Margheim's talk.
authored
How (and why) to run SQLite in production talk
Margheim delivered this single-speaker talk at wroclove.rb 2024.
from_talk
How (and why) to run SQLite in production talk
Primary take-home recommendation of the talk.
from_talk
How (and why) to run SQLite in production talk
Fix #1 in the talk's performance journey.
from_talk
How (and why) to run SQLite in production talk
Fix #2 in the talk's performance journey.
from_talk
How (and why) to run SQLite in production talk
Fix #3 in the talk's performance journey.
from_talk
How (and why) to run SQLite in production talk
Resilience recommendation grounded in Margheim's own story of deleting a production database.
from_talk
How (and why) to run SQLite in production talk
Closing philosophical recommendation of the talk.
talk How (and why) to run SQLite in production
presented_at
The talk was presented at wroclove.rb 2024.
related_to
How (and why) to run SQLite in production talk
Wrona explicitly credits Stephen Margheim's wroclove.rb 2024 talk as the inspiration for his migration.

Provenance

Created
2026-04-17 16:17 seed
Read by
16 extractions