🟢The Backend
Lesson 75 of 117
15 min
Choosing an ORM
Prisma vs Drizzle vs raw SQL. Use-case-driven decisions.
You have learned Prisma. You have learned Drizzle. You also know SQL. Three valid choices, and the right one depends on the project. This lesson is the decision matrix.
The same query in three layers
Find the 10 most recent published posts with their author name. Here is how each layer handles it:
Raw SQL
sql
SELECT p.id, p.title, u.name AS author
FROM posts p
JOIN users u ON u.id = p.author_id
WHERE p.published = true
ORDER BY p.id DESC
LIMIT 10;Drizzle
ts
await db
.select({ id: posts.id, title: posts.title, author: users.name })
.from(posts)
.innerJoin(users, eq(users.id, posts.authorId))
.where(eq(posts.published, true))
.orderBy(desc(posts.id))
.limit(10);Prisma
ts
await prisma.post.findMany({
where: { published: true },
orderBy: { id: "desc" },
take: 10,
include: { author: { select: { name: true } } },
});Decision matrix
| Raw SQL | Drizzle | Prisma | |
|---|---|---|---|
| Bundle size | 0 | tiny | ~bigger (client engine) |
| Edge runtime | via driver | great | via driver adapters |
| Migration tooling | manual / sqitch | drizzle-kit | prisma migrate (best in class) |
| Type safety | via codegen libs | native | native (after generate) |
| Learning curve | SQL only | SQL + builder API | schema language + client |
| Studio / GUI | pgAdmin, TablePlus | drizzle-kit studio | Prisma Studio (slickest) |
Picking by use case
- Greenfield Next.js app deployed to Vercel - Drizzle. Tiny bundle, edge-friendly, migrations are clean.
- Team that wants the migration toolkit done for them - Prisma.
prisma migrateis still the gold standard, and Studio is gorgeous. - You already know SQL really well - Drizzle or raw SQL. Drizzle keeps your knowledge usable; an ORM that hides SQL is a downgrade for you.
- Polyglot team, mostly junior - Prisma. The schema language doubles as documentation, and the generated client is hard to misuse.
- Performance-critical query (reports, analytics) - drop to raw SQL inside Drizzle (
db.execute(sql`...`)) or Prisma ($queryRaw). Both let you escape hatch when you need to. - Cloudflare Workers / edge isolates - Drizzle with a Neon or Turso HTTP driver. Prisma works but historically wanted Accelerate.
Use raw SQL inside the ORM
ORMs are not all-or-nothing. Both Drizzle and Prisma have escape hatches. Use them for one tricky reporting query without throwing out your whole stack.
Anti-patterns regardless of ORM
- N+1 queries. If you find yourself looping and calling the DB inside the loop, replace it with a JOIN or batched IN-list.
- Treating the ORM as a magical sleep aid. Always read the generated SQL for hot paths. ORM-generated joins are sometimes slower than what you would write.
- Skipping indexes. No ORM makes a missing index fast.
- Transactions as an afterthought. Wrap multi-write operations in a transaction; both ORMs make this trivial.
Quiz
Quiz1 / 3
Which ORM has historically had the best built-in migration tooling?
Recap
- Three layers: Prisma (most polished DX), Drizzle (closest to SQL, edge-ready), raw SQL (full control).
- New Vercel-deployed app in 2026 - Drizzle is the default. Migration-heavy team - Prisma.
- ORMs do not replace SQL knowledge; they amplify it.
- Both ORMs let you escape to raw SQL when you need to.
- Watch for N+1 queries, missing indexes, and untransacted multi-writes regardless of which ORM you pick.