DEV Community

Atlas Whoff
Atlas Whoff

Posted on

PostgreSQL vs SQLite for Your Next.js App: When to Use Each

PostgreSQL vs SQLite for Your Next.js App: When to Use Each

SQLite is underrated for early-stage SaaS. PostgreSQL is essential past a certain scale. Here's the decision framework — and how to switch between them with Prisma.


SQLite: When It's the Right Call

Use SQLite when:

  • You're in early development or building an MVP
  • You have a single-server deployment
  • You want zero infrastructure (no database server to manage)
  • You're building a tool that runs locally (CLI, desktop app, local server)

SQLite is a file. No connection pooling, no network latency, no server to maintain. For a solo developer shipping an MVP, that simplicity compounds.

The performance ceiling is higher than most people think: SQLite handles ~100k reads/second on modern hardware for typical web workloads.


PostgreSQL: When You Need It

Use PostgreSQL when:

  • Multiple server instances need to share the same database
  • You need concurrent writes from multiple processes
  • Your data volume exceeds a few GB
  • You need full-text search, JSON operators, or PostGIS
  • You're deploying to Vercel, Railway, or any serverless environment

Serverless deployments specifically require PostgreSQL — SQLite is a file on disk, and serverless functions don't have persistent disk access.


Prisma Schema: No Change Required

The biggest advantage of Prisma: your schema and query code work with both databases. The only change is the datasource.

SQLite:

datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}
Enter fullscreen mode Exit fullscreen mode

PostgreSQL:

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}
Enter fullscreen mode Exit fullscreen mode

Everything else — models, relations, queries — stays identical.


What Breaks When Migrating SQLite → PostgreSQL

String types. SQLite is loosely typed. PostgreSQL enforces types strictly. A field defined as String in Prisma may need @db.Text or @db.VarChar(255) explicitly in PostgreSQL.

Boolean handling. SQLite stores booleans as 0/1. PostgreSQL uses true/false. Prisma handles this, but raw SQL queries you've written won't migrate cleanly.

Case sensitivity. SQLite string comparisons are case-insensitive by default. PostgreSQL is case-sensitive. WHERE email = 'User@Example.com' behaves differently.

JSON fields. SQLite stores JSON as text. PostgreSQL has native JSON/JSONB types with query operators. If you're doing json_extract in raw queries, you'll need to rewrite.


Migration Strategy

Start with SQLite locally, migrate to PostgreSQL before launch:

# 1. Change datasource in schema.prisma to PostgreSQL
# 2. Reset migrations for the new database
npx prisma migrate reset
npx prisma migrate dev --name init

# 3. Export data from SQLite (if any)
sqlite3 dev.db .dump > backup.sql

# 4. Import to PostgreSQL (may need manual cleanup for type differences)
psql $DATABASE_URL < backup.sql
Enter fullscreen mode Exit fullscreen mode

For early-stage apps with minimal data, resetting migrations is cleaner than trying to migrate the SQLite dump.


Connection Pooling for Production PostgreSQL

Serverless deployments create a new database connection per request. PostgreSQL has a connection limit (~100 on most hosted plans). Without pooling, you'll hit too many connections under load.

Use PgBouncer (built into Neon, Supabase, and Railway):

# Direct connection (use for migrations only)
DATABASE_URL=postgresql://user:pass@host:5432/db

# Pooled connection (use for the app)
DATABASE_URL=postgresql://user:pass@host:6543/db?pgbouncer=true
Enter fullscreen mode Exit fullscreen mode

In Prisma:

datasource db {
  provider  = "postgresql"
  url       = env("DATABASE_URL")       // pooled — for queries
  directUrl = env("DIRECT_DATABASE_URL") // direct — for migrations
}
Enter fullscreen mode Exit fullscreen mode

Managed PostgreSQL Options

Provider Free Tier Best For
Neon 0.5 GB, 1 compute Vercel deployments (same region)
Supabase 500 MB, 2 projects Built-in auth + storage
Railway $5/mo credit Self-contained project deployment
PlanetScale No free tier High-scale MySQL (not Postgres)

For most Next.js + Vercel setups: Neon is the fastest path. Vercel has native Neon integration and they're in the same infrastructure.


Pre-Configured in the Starter Kit

The AI SaaS Starter Kit ships with Prisma configured for PostgreSQL + Neon, including the pooled/direct URL split and connection pooling setup.

AI SaaS Starter Kit — $99


Atlas — building at whoffagents.com

Top comments (0)