JM

Justin McKelvey

Fractional CTO · 15 years, 50+ products shipped

Lean Software 6 min read Mar 01, 2026

SQLite in Production: Why It's Ready for Your Startup in 2026

TL;DR: SQLite in Production Works

I run SQLite in production for a business-critical application — the platform that runs my consulting business. No managed Postgres, no $50/month database bill, no DBA. Just a SQLite file on disk, backed up continuously to S3 via Litestream. It handles my website, blog, CRM, booking system, and content management without breaking a sweat. As of 2026, the "SQLite isn't for production" advice is outdated for single-server applications. Rails 8 made it a first-class citizen, and the ecosystem has caught up.

Why I Ditched Postgres

My previous setup was a standard Rails + Postgres stack on Heroku, then Render. The database worked fine — that was never the issue. The issues were cost and complexity.

Cost: Managed Postgres runs $15-50/month for a small instance. For a solo consulting business generating a few hundred database queries per minute, that's paying for capacity I'd never use. The database server sat at 2-5% CPU utilization 24/7.

Complexity: A separate database server means connection pooling configuration, SSL certificate management, backup scheduling, and a network hop on every query. When the database is a file on the same disk as the application, all of that disappears.

The migration: Switching from Postgres to SQLite took one afternoon. Export the data, update database.yml, import into SQLite, test. The application code didn't change at all — Active Record abstracts the database engine. The only code change was removing a pg gem dependency and adding the litestream configuration.

How Rails 8 Makes SQLite Production-Ready

Rails 8 was the inflection point. Before Rails 8, using SQLite in production meant giving up background jobs (Sidekiq needs Redis), caching (also Redis), and real-time features (Action Cable needs Redis or Postgres). Rails 8 eliminated all three dependencies:

Solid Queue replaces Sidekiq/Redis for background jobs. It stores job queues in a SQLite database. My booking reminders, email sends, and follow-up scheduling all run through Solid Queue without any external service.

Solid Cache replaces Redis for caching. Page fragments, database query results, and computed values are cached in SQLite. Read performance is actually faster than Redis for small-to-medium cache sizes because there's no network round-trip.

Solid Cable replaces Redis/Postgres for Action Cable (WebSockets). Real-time features like the CRM Kanban board drag-and-drop work through SQLite-backed pub/sub.

The result: my entire production stack has zero external services beyond the application server. No Redis instance. No Postgres server. No managed database. Just one Rails process, one SQLite file, and one Litestream backup process.

The Performance Reality

SQLite's performance characteristics are different from Postgres, not worse. Understanding the trade-offs lets you use it effectively.

Reads are essentially free. SQLite reads from a file on the local disk. No network hop, no connection negotiation, no query parsing on a remote server. For a read-heavy application (which most web apps are — 90%+ reads), SQLite is measurably faster than Postgres. My blog post pages render in 15-40ms including database queries. The same pages with Postgres were 30-80ms.

Writes are sequential. SQLite uses a single writer model — only one write transaction can execute at a time. In WAL (Write-Ahead Logging) mode, reads don't block writes, but writes still queue behind each other. For my application with one primary user and occasional concurrent visitors, this is never a bottleneck. For an app with 100+ concurrent users all writing data simultaneously, it would be.

The practical limit: SQLite handles thousands of writes per second on modern hardware. The bottleneck appears when you have many concurrent write transactions competing for the lock, not when you have high write volume from a single process. A SaaS application with 50 active users creating records is fine. A real-time chat application with 10,000 concurrent users is not.

Backup Strategy: Litestream

The biggest concern with SQLite in production is data safety. A single file on disk means a server failure could lose your database. Litestream solves this completely.

How it works: Litestream watches the SQLite WAL file and continuously replicates changes to S3-compatible storage (I use Cloudflare R2). Every write to the database is streamed to the backup target within seconds. It's not periodic backup — it's continuous replication.

Recovery: If the server dies, deploy a new instance and restore from the latest Litestream replica. The restore command takes 10-30 seconds for a typical database. My docker-entrypoint script automatically restores from Litestream backup if the SQLite file doesn't exist — so redeployment is fully automatic.

Cost: Cloudflare R2 charges $0.015/GB/month for storage with no egress fees. My production database is 15MB. The backup cost is literally pennies.

What Litestream doesn't do: Point-in-time recovery to an arbitrary timestamp. It restores to the latest state. If you need to roll back to "yesterday at 3pm," you'll need periodic snapshot backups in addition to Litestream. For my use case, the latest state is always what I want.

When SQLite Is the Wrong Choice

I'm not a SQLite evangelist — I'm pragmatic. Here's when you should use Postgres instead:

Multiple application servers. If you're running 2+ app servers behind a load balancer, they can't share a SQLite file. SQLite is single-server only. The moment you need horizontal scaling, you need a client-server database.

Heavy concurrent writes. If your application has 100+ users simultaneously creating or updating records (think: a busy marketplace, a real-time collaboration tool, or a social network), SQLite's single-writer model will create contention. Postgres handles this natively with row-level locking.

Advanced database features. PostGIS for geographic queries, advanced full-text search with custom dictionaries, JSONB indexing, materialized views, database-level row security — these are Postgres-specific features with no SQLite equivalent.

Regulatory requirements. Some compliance frameworks (SOC 2, HIPAA) require a managed database service with audit logs, encryption at rest, and access controls. SQLite on disk with Litestream backup may not satisfy auditors, even if the technical security is equivalent.

The Setup: Rails 8 + SQLite + Railway

Here's the actual configuration that runs my production application:

database.yml: Three SQLite databases — one for the application, one for Solid Queue jobs, one for Solid Cache. All stored in the /app/storage directory on Railway's persistent volume.

Dockerfile: Installs Litestream alongside the Rails application. The entrypoint script restores from backup if the database doesn't exist, runs migrations, runs seeds, then starts Litestream wrapping the Puma server.

Railway configuration: Persistent volume mounted at /app/storage. Environment variable RAILWAY_RUN_UID=0 for volume permissions. Auto-deploy from GitHub pushes. Total cost: $5-10/month.

The gotcha: Railway volumes mount at runtime, not build time. Database migrations and seeds must run in the entrypoint script, not in the Dockerfile build step. This tripped me up for 2 days during initial deployment.

Who Should Use SQLite in Production

Solo businesses and consultants. If you're the only person writing to the database, SQLite is faster, cheaper, and simpler than any managed database service. This is my use case, and it's perfect.

Early-stage startups (pre-product-market-fit). You don't need Postgres at 10 users. You might not need it at 100. Start with SQLite, validate your business, and migrate to Postgres when — and if — you hit the scaling limits. The migration takes a day, not a month.

Internal tools and dashboards. Company-internal applications with known user counts and predictable write patterns are ideal for SQLite. No DBA required, no database server to manage, no monthly database bill.

Side projects and indie products. If the total cost of running your product matters (and for indie developers, it always does), eliminating a $15-50/month database service is significant. SQLite lets you run a full-stack application for $5-10/month total.

The Bottom Line

SQLite in production isn't a hack or a compromise. With Rails 8's Solid Queue/Cache/Cable, Litestream's continuous backup, and modern hardware that handles thousands of writes per second, it's a legitimate production database for single-server applications. I've been running it for months with zero issues, zero data loss, and zero regrets.

The old advice was right when SQLite had no backup story and Rails had no SQLite-backed infrastructure. Both of those changed. The advice hasn't caught up yet.

This is the database behind my $25/month SaaS replacement. If you're considering SQLite for your next project, or thinking about building your own tools with vibe coding, the stack works. If you want help with the architecture — whether SQLite is right for your use case, how to configure Litestream, or how to structure a Rails 8 deployment — book a strategy call.

Frequently Asked Questions

Is SQLite production-ready in 2026?
Yes, for single-server applications. Rails 8 treats SQLite as a first-class production database with Solid Queue, Solid Cache, and Solid Cable all backed by SQLite. Combined with Litestream for continuous backup, SQLite handles production workloads for small-to-medium applications with better performance than Postgres for read-heavy workloads.
When should you NOT use SQLite in production?
Don't use SQLite when: you need multiple application servers writing to the same database, you have more than 100 concurrent write-heavy users, you need advanced Postgres features (full-text search with custom dictionaries, PostGIS, JSONB indexing), or you're in a horizontally-scaled infrastructure. SQLite is single-server only.
How do you back up SQLite in production?
Use Litestream for continuous replication to S3 or S3-compatible storage (Cloudflare R2). Litestream streams every WAL frame to your backup target in real-time. If the server dies, you restore the database from the latest replica in under 60 seconds. Cost: $1-2/month for storage.
Is SQLite faster than Postgres?
For read-heavy workloads on a single server, SQLite is significantly faster because there's no network overhead — the database is a file on the same disk. Reads are essentially free. For write-heavy workloads with many concurrent writers, Postgres is faster because it handles concurrent writes natively. Most web applications are 90%+ reads, which is SQLite's sweet spot.
How does Rails 8 support SQLite in production?
Rails 8 ships with three SQLite-backed services: Solid Queue (background jobs), Solid Cache (caching), and Solid Cable (WebSockets). These replace Redis entirely. Combined with the built-in SQLite adapter improvements (WAL mode, busy timeout, connection pooling), Rails 8 makes SQLite a zero-configuration production database.
How much does SQLite in production cost compared to Postgres?
SQLite costs $0/month for the database itself (it's a file). Add $1-2/month for Litestream backup to S3. Compare to managed Postgres: $15/month (Render), $25/month (Supabase), $50+/month (AWS RDS). For a solo business or early-stage startup, SQLite saves $150-600/year in database costs alone.

If this was useful, here are two ways I can help: