Postgres + Drizzle, after a year
Not a tutorial. Lessons from a year of running Drizzle in production across JomJual, Lunara, and a few side builds.
· 4 min read
A year ago I migrated a side project from Prisma to Drizzle over one long Saturday. I have not gone back. This is not a Drizzle vs Prisma post. This is what Drizzle looks like once the honeymoon is over and you are actually running the thing.
What I love
The schema is just TypeScript. That sounds like nothing until you have gone through a Prisma migration where the generator hangs on a Windows filesystem and you cannot explain to your cofounder why a no-code schema change is blocking deployment.
pgTable('orders', { ... }) is ugly. It is also a function call. I can loop over it. I can factor shared columns into a helper. I can write a test that asserts every tenant-scoped table has a store_id foreign key, and the test runs before any migration goes near Neon. Try doing that with a .prisma file.
What I had to unlearn
Prisma's relation helpers hide N+1 under a friendly API. Drizzle does not. with is a real join, and you have to think about it. The first time I shipped a product listing that did 31 round-trips for "select products with variants" I learned this the hard way, at 22:00, staring at Neon query logs.
The fix was reading the docs — Drizzle's with generates a single query with lateral joins when you configure relations properly. But the default when you forget is not magic. It is slow. You get what you asked for.
Migrations
drizzle-kit generate is fast and deterministic. drizzle-kit push is fine for early development, and dangerous after your first user. Once the database has real data, every migration goes through generate → review the SQL → run in a transaction.
I still use push for local iteration. I do not use it in CI. There is no world in which an unreviewed ALTER TABLE hits production.
The actual ergonomics win
Type-safe query builders are a meme category now, but the one that changed my life is the query response type. When I select five fields from three joined tables with a filter, the returned row is typed exactly for those five fields. No any, no partial, no as unknown as SomeType. You change the select, the consumer breaks at compile time, you fix it, you move on. This is the actual reason to use Drizzle.
Would I pick it again
Yes. But I would also not judge anyone who picks Prisma. The right answer for most people is "the one your team already knows." Pick something and ship. Database tools are a worse rabbit hole than editors.
Keep reading
- custom software costmalaysia
How Much Does Custom Software Actually Cost?
Custom software can cost anywhere from RM20,000 to RM500,000 or more. Here's a plain-language breakdown of development, maintenance, and hidden fees so you can decide if the investment pays off for your business.
- static site generatorsjamstack
The Unreasonable Effectiveness of Simple Static Site Generators in 2026
Forget the JAMstack hype cycle. Plain HTML generated from Markdown with a makefile still beats most modern stacks for docs, blogs, and internal tools. Here's why, and when to resist the urge to add a JavaScript framework.
- automationworkflow
When Your Business Systems Are Just Digital Paper
Your software looks like progress, but if it just moves paper to a screen, you're paying a silent tax in time, errors, and trust. Here's how to spot the difference between digitized and truly automated, and why it hits your bottom line.