Omaship

February 2, 2026 · 11 min read

SQLite vs PostgreSQL for Rails SaaS in 2026: Which Database Do You Actually Need?

Jeronim Morina

Jeronim Morina

Founder, Omaship

Rails 8 defaults to SQLite. This is controversial. Many experienced developers still insist PostgreSQL is required for any production app. Here is an honest look at what has changed and when each database actually makes sense.

The database debate in the Rails community has been settled for over a decade: use PostgreSQL. It is what Heroku defaulted to. It is what every tutorial recommended. It is what every boilerplate shipped with. PostgreSQL was the "right" answer, and SQLite was the toy you used for development before switching to a "real" database.

Then Rails 8 shipped with SQLite as the default — not just for development, but for production. The Solid Trifecta (Solid Queue, Solid Cache, Solid Cable) replaced Redis. Kamal made single-server deployment first-class. And suddenly the question was not "why SQLite?" but "why not?"

What changed: SQLite in 2026 is not the SQLite you remember

The SQLite that most developers dismissed years ago is not the SQLite that ships with Rails 8. Several technical changes make it genuinely production-viable:

  • WAL mode (Write-Ahead Logging): Concurrent readers no longer block writers. Rails 8 enables this by default. Multiple processes can read the database simultaneously while writes happen in a separate log file.
  • IMMEDIATE transactions: Rails 8 configures SQLite with IMMEDIATE transaction mode, which acquires write locks at the start of a transaction rather than on the first write statement. This eliminates most SQLITE_BUSY errors.
  • Solid Queue: Background job processing backed by SQLite. No Redis required. Handles job scheduling, concurrency controls, and recurring jobs.
  • Solid Cache: Database-backed caching that replaces Redis or Memcached. Automatic eviction, no external process to manage.
  • Solid Cable: WebSocket support through SQLite, replacing the Redis dependency that Action Cable traditionally required.

The result: a Rails 8 app with background jobs, caching, and real-time features runs on a single process with a single database file. No Redis. No separate database server. No connection pooling to configure.

The honest comparison

Dimension SQLite (Rails 8) PostgreSQL
Ops complexity Zero — it is a file Moderate — separate server process
Read performance Excellent (no network round-trip) Excellent (with connection pooling)
Write concurrency Single writer (WAL helps reads) Full MVCC, many concurrent writers
Backup Copy the file (or Litestream) pg_dump, WAL archiving, managed snapshots
Scaling ceiling ~100K requests/day comfortably Millions of requests/day with replicas
Full-text search FTS5 (good for small-medium datasets) Built-in tsvector (production-grade at scale)
JSON support json_extract, json_each (solid) jsonb with indexing (best-in-class)
Geospatial SpatiaLite (limited) PostGIS (industry standard)
Monthly cost $0 (included in VPS) $0 (self-managed) to $50+ (managed)
AI agent compatibility Excellent (fewer config files) Good (more setup, well-documented)
Migration path Can switch to PostgreSQL later Already there

Real numbers: what SQLite actually handles

The fear around SQLite in production usually comes from assumptions, not benchmarks. Here is what the numbers actually look like in a Rails 8 app with WAL mode enabled on a $20/month VPS (4 vCPUs, 8 GB RAM):

  • Reads: 50,000+ queries per second. SQLite reads are faster than PostgreSQL in many cases because there is zero network latency — the database is a local file.
  • Writes: 2,000-5,000 writes per second in WAL mode. For context, a SaaS doing $50K MRR typically generates 10-50 writes per second during peak hours.
  • Database size: SQLite handles databases up to 281 TB in theory. In practice, most SaaS products never exceed 10 GB, which SQLite handles without breaking a sweat.
  • Concurrent connections: The single-writer constraint means one write at a time, but each write takes microseconds. Readers are never blocked. For most SaaS workloads, this is not the bottleneck you think it is.

PostgreSQL numbers on equivalent hardware: 10,000-30,000 reads per second (network overhead), 5,000-20,000 writes per second with full MVCC. PostgreSQL wins on concurrent writes, but SQLite wins on read latency and operational simplicity.

When SQLite is the right choice

SQLite is the right database for your Rails SaaS if:

  • You are a solo founder or small team. Every external service you eliminate is one fewer thing to monitor, debug, and pay for. SQLite removes the database from your ops burden entirely.
  • You are building with AI coding agents. Cursor, Claude Code, and Codex generate better results when the stack has fewer moving parts. No database.yml connection string to configure. No Redis URL. No connection pool tuning. The AI agent just works.
  • Your SaaS is read-heavy. Most SaaS products are. Dashboards, reports, content pages, settings screens — reads dominate. SQLite excels here.
  • You want simple backups. Your entire database is a single file. Copy it. Sync it with Litestream to S3 for continuous replication. Done. No pg_dump scripts, no WAL archiving, no managed database snapshots to configure.
  • You want to keep costs low. A $5-20/month VPS running Rails 8 with SQLite handles more traffic than most SaaS products ever see. No managed database fee. No Redis fee.
  • You might sell the product someday. More on this below.

When PostgreSQL is the right choice

PostgreSQL genuinely wins in specific scenarios. Do not force SQLite if your use case falls into one of these categories:

  • Heavy concurrent writes. If your app has dozens of users writing simultaneously — collaborative editing, real-time bidding, high-frequency event tracking — PostgreSQL's MVCC handles this natively. SQLite serializes writes, and while each write is fast, the queue can become a bottleneck under sustained concurrent write pressure.
  • Geospatial queries. PostGIS is the industry standard for geospatial data. If your SaaS involves maps, location search, or geographic computations, PostgreSQL with PostGIS is the clear choice.
  • Advanced full-text search at scale. SQLite's FTS5 works well for small-to-medium datasets, but PostgreSQL's full-text search with tsvector, ranking, and custom dictionaries is more mature for large-scale search features.
  • Enterprise compliance requirements. Some enterprise customers require specific database certifications or configurations. PostgreSQL has a longer track record in enterprise audits and compliance frameworks.
  • Multi-server architecture. If you already know you need horizontal scaling with read replicas, PostgreSQL's replication is battle-tested. SQLite is inherently single-node (though Litestream and LiteFS provide replication options).
  • Complex JSON querying. If your application relies heavily on querying into JSON documents, PostgreSQL's jsonb with GIN indexes is substantially more powerful than SQLite's JSON support.

The exit angle: why SQLite apps are easier to sell

This is a factor most database comparison articles ignore entirely: what happens when you want to sell your SaaS?

Acquirers doing technical due diligence love simplicity. A Rails app backed by SQLite has a dramatically smaller operational footprint:

  • No database server to transfer. The database is just a file in the app. Transfer the server, transfer the database. There is no managed RDS instance to migrate, no connection strings to update, no database user credentials to rotate.
  • No Redis dependency. Solid Queue, Solid Cache, and Solid Cable all run on SQLite. One fewer service to document, transfer, and maintain post-acquisition.
  • Lower monthly burn. Acquirers calculate ROI on total infrastructure cost. A $15/month VPS running everything looks better than $15/month VPS + $30/month managed PostgreSQL + $15/month Redis.
  • Simpler disaster recovery. Backup is a file copy. Recovery is deploying the file. The new owner does not need a DBA to understand the backup strategy.

The simplest architecture that handles your traffic wins — not just for development speed, but for exit multiples. Fewer moving parts means faster due diligence and higher buyer confidence.

The migration question: can you switch later?

Yes. If you start with SQLite and outgrow it, migrating to PostgreSQL is straightforward:

  • Active Record abstracts the database. If you use standard Active Record queries (and you should), switching databases means changing database.yml and running migrations. No query rewriting required.
  • The Solid Trifecta works with PostgreSQL too. Solid Queue, Solid Cache, and Solid Cable can all use PostgreSQL as their backend. You can migrate incrementally.
  • Avoid raw SQL. The one trap: if you write raw SQL that uses SQLite-specific syntax, you will need to update those queries. Stick to Active Record and this is not a problem.

Most SaaS products never need to make this switch. The ones that do are usually doing well enough that a database migration is a manageable engineering project, not an existential crisis.

Why Omaship chose SQLite

Omaship ships with SQLite and the Solid Trifecta because the math is simple: 95% of SaaS products will never need PostgreSQL. The ones that do will know it, and the migration path is clear.

For the solo founder building their first SaaS, the indie hacker validating an idea, or the small team shipping fast with AI coding agents — SQLite eliminates an entire category of operational complexity without sacrificing anything that matters at their scale.

The database that requires zero configuration, zero maintenance, and zero monthly cost is the right default. PostgreSQL is there when you need it. But you probably do not need it yet.

Start building with the simplest production stack

Omaship ships with SQLite, Solid Queue, Solid Cache, and Solid Cable out of the box. No Redis. No managed database. Just a Rails 8 app that runs on a single server.

Continue reading

We use analytics and session recordings to learn which parts of Omaship help and which need work. Accept all, or customize what you share.

Privacy policy