Part 3 · 1 chapters · ~8 min

Prisma

Prisma's schema language, the generated client and type inference limits, the query engine and its move from a Rust binary to TypeScript and WASM, relation queries and the relationJoins choice, migrations with the shadow database and drift detection, connection pooling and serverless (Accelerate, driver adapters), reading the generated SQL, and known pathologies.

7

Schema, client and engine

code
// schema.prisma
model Account {
  id          String    @id @default(cuid())
  ownerId     String
  currency    String
  balanceKobo BigInt    @default(0)
  postings    Posting[]
  @@index([ownerId])
}

const accts = await prisma.account.findMany({
  where: { ownerId: userId }, include: { postings: { take: 20, orderBy: { createdAt: 'desc' } } },
});
// see the SQL Prisma sends
const prisma = new PrismaClient({ log: [{ emit: 'event', level: 'query' }] });
prisma.$on('query', e => console.log(e.query, e.params, e.duration + 'ms'));
known pathologymitigation
deeply nested include fan-outselect only needed fields; split queries; raw SQL for reports
connection storms in serverlessa pooler (PgBouncer, Prisma Accelerate) or driver adapters with HTTP drivers
no row locking API (SELECT ... FOR UPDATE)$queryRaw inside an interactive transaction
large migrations generated naivelyedit generated SQL (CONCURRENTLY, NOT VALID) before deploying
PRISMA'S ARCHITECTURE
a schema, a generated client, and a query engine
schema.prismamodels, relationsprisma generatetyped clientPrismaClientyour queriesquery engineRust (historically) → TS/WASMdatabasevia driver adaptersprisma migrateshadow DB, drift
swipe the figure sideways, or tap expand for full screen
1/5
schema first
schema.prisma declares models and relations in Prisma's own language; it is the source of truth for both the client types and migrations.
one schema for types and migrationsPrisma Schema Language