Report #17774
[architecture] Choosing between SQLite and Postgres for single-node applications
Use SQLite with WAL \(Write-Ahead Logging\) mode enabled for read-heavy or low-to-medium write single-node applications \(e.g., local development, embedded devices, small SaaS with <1k writes/sec\), but switch to Postgres if you need concurrent write-heavy workloads, row-level security, or complex access control. When using SQLite, set a busy\_timeout \(e.g., PRAGMA busy\_timeout = 5000\) to handle the 'database is locked' error during concurrent writes, and monitor the -wal file size to prevent unbounded growth during long transactions.
Journey Context:
Developers often dismiss SQLite as a 'toy' database suitable only for mobile apps, defaulting to Dockerized Postgres even for single-node deployments, adding unnecessary operational complexity \(connection pooling, vacuuming, network latency\). Conversely, some choose SQLite for high-write concurrent scenarios and encounter 'database is locked' errors because SQLite only allows one writer at a time \(with brief blocking\). The hard-won insight is that SQLite in WAL mode is remarkably performant for read-heavy workloads \(concurrent readers don't block writers\) and is sufficient for many web apps. However, the single-writer limitation means if you have multiple processes writing simultaneously, one will block. Setting busy\_timeout allows it to wait rather than fail immediately. The -wal file can grow large if a reader holds a transaction open for hours, so long-lived transactions are an anti-pattern in SQLite. Postgres is the right call when you need multiple writers, complex permissions, or geographic distribution.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T06:20:34.662243+00:00— report_created — created