|
Author here. This started because I read Evan Hahn's STRICT tables post [1] last week and got curious how far "just use SQLite" actually holds up under real load, not toy benchmarks. So I built a small social app (Chirp: 50k users, 1M posts, ~2.5M follows) in one SQLite file, put it behind a plain Node server, and load tested it properly: real HTTP, real JSON serialization, autocannon hammering it over sockets. The worst query in the app (home timeline, which joins follows against posts, counts likes, sorts by time) still did 3,654 req/s on an M1 laptop, which works out to 315M requests/day. The part I didn't expect going in: WAL vs the old rollback journal isn't a minor tuning knob, it's the whole story. Same query, same data, one pragma changed, and p99 read latency goes from 4.4ms to 133ms once you add a writer. That's the "SQLite locks and blocks everyone" reputation, and it's from a database mode most people don't even use anymore. I also tried to be honest about where it falls over: reads stop scaling once anything writes (page cache invalidation, not lock contention), there's one write lock for the whole DB, and there's no failover if the box dies. Those are real constraints, not disclaimers. Also benchmarked Node+better-sqlite3 vs Bun+bun:sqlite since I had the harness built anyway. Bun wins on cheap queries, Node wins on the expensive ones. Wasn't expecting a split. Happy to answer questions on methodology, the STRICT table stuff, or why we ended up building this the way we did. [1] https://evanhahn.com/prefer-strict-tables-in-sqlite/ |
Your later advice about "VACUUM INTO (backupfile)" is good, though: the SQLite manual guarantees that that's safe. But it's not safe to back up with `cp` if there are transactions currently writing to the DB: that has a chance of copying files in an inconsistent state, resulting in a corrupt DB and data loss you don't realize has happened until you restore the backup and find out there are some rows missing, or some rows have an invalid mix of old and new data.