SQLite vs MySQL for Small Sites: When Simplicity Wins
The default assumption in web development is that serious applications run on serious databases, and serious databases means a separate server process, connection pooling, user management, and a configuration file that will eventually be wrong in a way that takes an afternoon to diagnose. MySQL and PostgreSQL are excellent databases. They are also, for the median small site, a solution in search of a problem — infrastructure designed for concurrency, scale, and replication requirements that don’t exist at any traffic level the site will realistically see for years.
SQLite is a file-based database that runs in the same process as your application. There is no server to manage, no connection pool to configure, no firewall rules to get wrong. The database is a single file on disk. Backups are a file copy. Migrations are SQL applied to a file. Restoration is moving a file back. The operational surface area is so small that most of the things that can go wrong with a traditional database setup simply don’t exist.
The performance case for SQLite at small scale is also stronger than its reputation suggests. For a site doing a few hundred reads per second with minimal write concurrency, SQLite is fast — often faster than a remote database whose queries have to cross a network boundary, however short. The bottleneck for most small sites is not database throughput; it is application logic and network latency. Optimizing the database for a problem that doesn’t exist while ignoring the actual bottleneck is a classic misallocation of engineering attention.
The deployment simplicity compounds over time in ways that matter for bootstrapped operators. A SQLite-backed application can be deployed to any server that can run the application runtime. There is no provisioning step for the database layer, no separate service to keep alive, no connection string to manage across environments. Development and production have the same database architecture, which eliminates an entire category of environment-specific bugs. The application is portable in a way that MySQL-backed applications are not — move the binary and the file, and it works.
WordPress with SQLite is worth specific mention because it illustrates the practical scope. The wp-sqlite-db plugin (and the more recently maintained SQLite integration) allows a standard WordPress installation to run on SQLite instead of MySQL. For a site with modest traffic and no specific MySQL dependencies in its plugin stack, this works correctly and simplifies deployment considerably. The performance ceiling is real but distant for typical content site loads. The operational simplicity gain is immediate.
The ceiling does exist. SQLite’s write concurrency model — single writer at a time — becomes a genuine constraint at traffic levels where simultaneous writes are frequent. For applications with high write throughput, real-time features, or horizontal scaling requirements, the migration to PostgreSQL is necessary and correct. But the migration path is well-traveled. Starting on SQLite and migrating when you need to is a legitimate strategy. Starting on PostgreSQL “to be ready” when you’re serving a hundred visitors a day is premature optimization with a real ongoing maintenance cost.
The right database for a small site is the simplest one that handles the actual load correctly. For most small sites, that is SQLite. The instinct to reach for full relational infrastructure before it’s needed is a form of the same abundance thinking that leads to over-engineered stacks throughout the web development world — building for a scale you hope to reach rather than for the scale you’re at. Bootstrapping means being honest about which scale that is.