Prisma + PostgreSQL para SaaS en 2026: el default razonable
Schema único, type-safety, migrations, Prisma Studio. Por qué Prisma + Postgres son el stack de DB con menor fricción para SaaS indie.
Israel Palma
3 min de lectura
El stack "PostgreSQL + Prisma" se ha consolidado como el default para SaaS indie en 2026. No porque
sea la única opción (Drizzle, Kysely, raw SQL existen), sino porque la combinación de type-safety +
migrations + DX es difícil de igualar.
Esta guía explica por qué este combo gana, qué patrones funcionan y qué errores evitar.
## Qué te da Prisma + PostgreSQL
- **Schema declarativo único**: defines modelos en `schema.prisma` y de ahí salen tipos TS, cliente,
migrations.
- **Type-safety end-to-end**: TypeScript sabe la forma de cada tabla, autocompletas queries.
- **Migraciones automáticas**: cambias el schema, lanzas `migrate dev`, lista.
- **Prisma Studio**: GUI para inspeccionar la DB sin instalar nada extra.
PostgreSQL aporta:
- Madurez y compatibilidad universal (cualquier provider lo soporta)
- JSON nativo (`@db.JsonB`) para campos flexibles
- Full-text search built-in
- Triggers, vistas, etc., si los necesitas
## Schema básico SaaS
```prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(cuid())
email String @unique
name String?
createdAt DateTime @default(now())
posts Post[]
}
model Post {
id String @id @default(cuid())
title String
content String
authorId String
author User @relation(fields: [authorId], references: [id])
createdAt DateTime @default(now())
@@index([authorId, createdAt])
}
```
Schema corto, todo lo necesario para arrancar.
## Patrón cliente único
Mal:
```ts
// Cada vez que importas, instancias un PrismaClient nuevo
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
```
En desarrollo, hot-reload abre nuevas conexiones cada vez. Acabas saturando la DB.
Bien:
```ts
// src/lib/db/client.ts
import { PrismaClient } from '@/generated/prisma/client';
declare global {
var prisma: PrismaClient | undefined;
}
export const db = globalThis.prisma ?? new PrismaClient();
if (process.env.NODE_ENV !== 'production') {
globalThis.prisma = db;
}
```
Y en cualquier parte: `import { db } from '@/lib/db/client'`.
## Migrations en equipo
```bash
bunx prisma migrate dev --name add-billing-table
```
Crea archivo SQL, lo aplica a tu DB local, regenera el cliente. Lo commiteas con el código.
En producción:
```bash
bunx prisma migrate deploy
```
Aplica las migraciones pendientes. No genera SQL nuevo, solo aplica lo que ya está en
`prisma/migrations/`.
## Patrón query repetida
Si haces la misma query en 3+ sitios, sácala a un archivo:
```ts
// src/lib/db/queries/users.ts
import { db } from '@/lib/db/client';
export async function getUserById(id: string) {
return db.user.findUnique({
where: { id },
include: { posts: { orderBy: { createdAt: 'desc' } } },
});
}
```
Esto te da:
- Reusabilidad
- Un sitio donde cambiar la query si cambia el schema
- Tests más simples (mockeas el helper, no Prisma entero)
## Prisma 7 y el adapter de PostgreSQL
Desde Prisma 7 (2025), el cliente requiere un adapter explícito:
```ts
import { PrismaPg } from '@prisma/adapter-pg';
import { PrismaClient } from '@/generated/prisma/client';
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL! });
const prisma = new PrismaClient({ adapter });
```
Detalle pequeño pero crítico: si te lo saltas, los scripts standalone (`bun script.ts`) explotan con
error de inicialización.
## Errores comunes
**1. Olvidar índices en columnas filtradas**: si haces `where: { userId }`, mete índice. Sin él, en
producción con 100k filas, la query tarda segundos.
**2. `findMany` sin paginación**: si la tabla puede crecer, paginar (`take`, `skip`, o cursor).
Devolver 50k filas a un endpoint mata el server.
**3. Hacer `findUnique` con campos no únicos**: solo funciona con campos `@unique`. Para otros,
`findFirst`.
**4. Cargar relaciones que no usas**: `include: { posts: true }` siempre que no las necesites es
trabajo de DB que tiras a la basura.
## Cuándo NO usar Prisma
- Necesitas SQL muy custom (CTEs complejos, window functions avanzadas) — usa raw queries para esos
casos puntuales o pásate a Kysely
- Equipo backend que prefiere SQL puro — válido también
- Datasets enormes (>10TB) donde controlas cada query
Para el 95% de SaaS indie, Prisma es el default razonable.
## Conclusión
Prisma + PostgreSQL en 2026 es el stack de DB con menor fricción para SaaS indie. Un schema, un
cliente, type-safety, migraciones. Todo lo demás es ruido.
Si arrancas hoy, empieza aquí. Cuando crezcas y necesites algo más afilado, ya tendrás los datos
para decidir.
¿Te gustó este artículo?
Suscríbete para más tutoriales y tips sobre crear productos con IA