We’ve built TypeScript ORM for 821 days then this happened

Alex Blokh
Drizzle Stories
Published in
7 min readAug 6, 2023

--

Drizzle is a menace. It became so good other ORMs will have to get better now

Drizzle ORM got faster

If you want to make something fast — make it slow first 🐌. That’s exactly what we did.

We went public on Jan 3, had completely humble beginnings and then things went wild, Drizzle went off the charts, through the roof and I can’t wait to tell you more about it.

If you’ve been watching us closely — you know we began our journey 7 months ago. We’ve created a Twitter(X) account, made a logo and came out a closet. Despite using Drizzle on production projects internally for 20 months we were overwhelmed by feature requests, feedback, size of the community, sponsorships, mostly everything tbh.

It all comes down to a single point in time. We’ve had a completely regular start, slowly building our user base and then.. we’ve been Dax’ed

Big Bang

Graham’s Number of GitHub stars

If you’ve built a product — you know that it’s really really really really hard to gain your first audience. We’ve spent countless hours on all social platforms promoting Drizzle, gradually building community, collecting feedback and finally found our first major audience on Cloudflare D1 community in Discord.

We’ve been slowly approaching 700 stars, that was completely surreal. Having 700 stars for OSS library means a world, at least we’ve thought that way. Then this video on SST channel happened:

I mean, things went nuts. Hold on a sec, let me grab my milk..

Fast forward today, we now have 7.9k subscribers in Twitter, our Discord community grew to 2.4k developers. We’re overwhelmed with amount of contributions and trying to keep our pace of iterating and managing PRs. We do have a massive product expertise, but OSS is a different game and we’re still learning.

For most developers GitHub stars and NPM downloads are the “proof”. Mainly the only metric they rely on while choosing next tool for the project. It’s sad, but it’s true. We knew that regardless of how good Drizzle was, we needed GitHub stars and downloads as a validation for developers.
Drizzle has 11.9k stars now

We’ve hit the Best of JS charts and went 1st place in May with a whooping 3.4k GitHub stars per month, still can’t believe it

YouTube

One of the most important exposure mediums for us is YouTube.
Drizzle is built for experienced developers first and YouTube videos and tutorials are an exceptional onboarding flow for newcomers.

I can’t express how thankful we are for YouTube creators sharing a word about Drizzle, that means a world

Theo have shared his production experience with Drizzle at Ping.

Fireship mentioned us as a new kid in town.

Marius Espejo, Josh, Ben Davis and Dave Gray are exploring Drizzle and our new Drizzle Studio.

Justin made a mind blowing 6hrs long, ground top complete NextJS+Neon+Vercel+Drizzle tutorial.

Sébastien Chopin talked about NuxtJS on the edge and featured DrizzleORM.

Good stuff, good stuff, still can’t believe it… **milk sip**

Is Drizzle production ready?

That’s the biggest concern of new developers coming to Drizzle and it’s a very broad one. We’ve been using Drizzle for over 27 months on commercial projects and were completely happy with it, it took us quite some time to fully understand the question of production readiness.

We broke it down into domains, prioritised those and addressing them one by one. Top 5 are — docs, IntelliSense performance, database performance, data studio and relational querying. We’ve addressed them all.

Drizzle studio and RQB. We’ve never thought shipping data viewer studio or relational query builder would be a mandatory key for increasing developers adoption. It turned out we’re not only building an ORM, we’re building a complete development experience. Things’ve changed when we realised that. If only there were 25 hrs a day!

Performance. If you want to make something fast — make it slow first. That’s exactly what we did, smart isn’t it? I know, I know, don’t judge us, how else would we improve if it’s perfect since the beginning. It’s way easier to market something when you make it 40 times better!

Types performance. We’ve spent quite some time investigating TypeScript types performance, allocated issues and fixed them. We removed higher kinded types, I don’t know what’s that, ask Dan. It worked, there’re no issues with types performance any more 🚀

Numbers! 85 tables, 666 columns, 26 enums, 172 indexes and 133 foreign keys:

Query performance. Drizzle has 2 ways of composing queries. Conventional SQL-like for developers familiar with SQL and willing to be in control, and recently released relational query builder for people who like relational json-like syntax without necessity to think about joins.
While SQL query builder has exceptional performance, especially with prepared statements, relational one is a little tricky.

To tackle the problem of edge/server-less — we made our relational query builder always generate 1 query and that had certain caveats with both performance and rows reads(they matter when you use PlanetScale for example).

Good news is we fixed them all, we’ve launched Drizzle Accelerate and now partnering with cloud providers to deliver best in class developer experience all around the world. Nah, I’m just kidding, sorry.
We changed a generated SQL query(Dan changed). It’s still exactly 1 query every time and it’s even faster now!
What a day.. I love Drizzle releases 🚀

If you feel geeky you can have a look at how query looked like before:

SELECT "id",
"user_id",
"post_id",
"content",
"user"::JSON,
"post"::JSON
FROM
(SELECT "comments".*,
CASE
WHEN count("comments_post"."id") = 0 THEN '[]'
ELSE json_agg(json_build_array("comments_post"."title", "comments_post"."user"::JSON))::text
END AS "post"
FROM
(SELECT "comments".*,
CASE
WHEN count("comments_user"."id") = 0 THEN '[]'
ELSE json_agg(json_build_array("comments_user"."name"))::text
END AS "user"
FROM "comments"
LEFT JOIN
(SELECT "comments_user".*
FROM "users" "comments_user") "comments_user" ON "comments"."user_id" = "comments_user"."id"
GROUP BY "comments"."id",
"comments"."user_id",
"comments"."post_id",
"comments"."content") "comments"
LEFT JOIN
(SELECT "comments_post".*
FROM
(SELECT "comments_post".*,
CASE
WHEN count("comments_post_user"."id") = 0 THEN '[]'
ELSE json_agg(json_build_array("comments_post_user"."name"))
END AS "user"
FROM "posts" "comments_post"
LEFT JOIN
(SELECT "comments_post_user".*
FROM "users" "comments_post_user") "comments_post_user" ON "comments_post"."user_id" = "comments_post_user"."id"
GROUP BY "comments_post"."id") "comments_post") "comments_post" ON "comments"."post_id" = "comments_post"."id"
GROUP BY "comments"."id",
"comments"."user_id",
"comments"."post_id",
"comments"."content",
"comments"."user") "comments"
LIMIT 1

And after:

select "comments"."id",
"comments"."user_id",
"comments"."post_id",
"comments"."content",
"comments_user"."data" as "user",
"comments_post"."data" as "post"
from "comments"
left join lateral (select json_build_array("comments_user"."name") as "data"
from (select *
from "users" "comments_user"
where "comments_user"."id" = "comments"."user_id"
limit 1) "comments_user") "comments_user" on true
left join lateral (select json_build_array("comments_post"."title", "comments_post_user"."data") as "data"
from (select *
from "posts" "comments_post"
where "comments_post"."id" = "comments"."post_id"
limit 1) "comments_post"
left join lateral (select json_build_array("comments_post_user"."name") as "data"
from (select *
from "users" "comments_post_user"
where "comments_post_user"."id" = "comments_post"."user_id"
limit 1) "comments_post_user") "comments_post_user"
on true) "comments_post" on true
order by "comments"."id"
limit 1

You know what, I’m nowhere near geeky for that stuff. I will let Dan explain.

As you see, we now have different strategies for different dialects and it’s not only faster, it also performs way way way way less row reads on PlanetScale now.
Fetching 10 users with their posts and comments for the database with 1000 users, 5000 posts and 10000 comments looks like this:

Almost forgot!

According to State of the Databases 2023 — people are both using Drizzle and they are happy and willing to use it further. Of course they are!

Supabase is an ORM?

Honorable mentions
Our recently launched docs website is gaining some views and some search clicks. I will merge all the PRs, I promise.

We have 35 GitHub sponsors and it’s been both inspiring seeing people contributing financially and heartbreaking when they churn. If you’re our sponsor and you’re reading this — thank you and don’t churn!

Thank you for reading this far! We maintain our pace of development and delivery and not planning to slow down.

We have so much more in the backlog and we can’t wait to ship it as soon as we can. Btw we’ve partnered with Turso and Payload and something’s going on in our labs, so stay tuned!

If there’s something preventing you from migrating to Drizzle — don’t hesitate and reach out to us in the comments or on Twitter and Discord!

Like, subscribe and clap clap clap 👏👏👏

--

--