architecture

Portable Database Architecture

The worst time to migrate a database is when you're under pressure to scale. Portable architecture lets you start simple and switch without rewriting everything.

  • Portable = your code speaks to an abstract interface, not "Postgres" or "SQLite" directly
  • SQLite: single file, zero config, perfect for MVP and local dev
  • Postgres: concurrent, cloud-ready, production scale
  • Migration: export from SQLite, import to Postgres. Swap connection string. Done.
  • The key: no database-specific features in business logic. Stick to standard SQL.

Real-world example

You built an MVP with SQLite. Now you need 10 users hitting it at once.

SQLite locks on writes. One user running a report blocks another. You need Postgres—but your queries are sprinkled with SQLite-specific syntax.

  • Non-portable: Used SQLite's AUTOINCREMENT, datetime("now"), and other SQLite-only features. Migration = find and replace, hope you didn't miss any.
  • Portable: Used an abstract DB interface. Queries use standard SQL. Connection comes from config. SQLite for dev, Postgres for prod.
  • Migration: Export SQLite to SQL dump. Import into Postgres. Change connection string. Restart. Same application code.
  • The portable path: a few hours. The non-portable path: days of debugging subtle differences.

Portable database design is insurance. You might not need to switch—but when you do, it's a config change, not a rewrite.

What makes a database portable?
View details →
When SQLite, when Postgres?
View details →
The migration path
View details →
Common mistakes
View details →

Planning an MVP that might need to scale?

More resources

All resources →