Why Most Startups Fail at Database Design
The hidden cost of Prisma, TypeORM, and other ORMs that make your code 'clean' but your database unusable.
Core Concept
Every startup begins with “clean code.” They use Prisma or TypeORM because it feels elegant. Six months later, they discover their database schema is a mess of auto-generated foreign keys, no indexes, and impossible to query.
The problem: ORMs optimize for developer ergonomics, not database performance.
The Constraint
When you reach 10K users, you need:
- Complex aggregations (user analytics, dashboards)
- N+1 query optimization (eager loading fails at scale)
- Manual index tuning (ORMs can’t predict your query patterns)
- Raw SQL flexibility (for reports, migrations, batch jobs)
But your ORM has trained you to think in objects, not sets. Your database is now “frozen” — any schema change requires a massive refactor.
The Solution
We use Supabase with raw SQL migrations.
Workflow:
- Design the schema in PostgreSQL first (proper normalization, indexes, constraints)
- Write migrations as
.sqlfiles (version controlled) - Use Supabase auto-generated TypeScript types for type safety
- Write queries in SQL (via Supabase client or
kyselyfor composition)
Why this works:
- Your database schema is first-class (not generated junk)
- You can hire any Postgres DBA to optimize it later
- Query performance is visible (not hidden behind ORM magic)
- Switching clients is trivial (SQL is portable, ORM DSLs are not)
The Trade-Off
What you lose: The “magic” of user.posts.comments.author chaining.
What you gain:
- 10x faster queries (proper indexes)
- Ability to hire senior engineers (they refuse to work with ORMs)
- Schema that survives Series B (when you need real data engineers)
The First Principle: Your database is your IP. Don’t let a framework control it.