We don’t make mistakes 🎨

Alex Blokh
Drizzle Stories
4 min readNov 26, 2023

--

Drizzle is giving away 1000$ for your HEX colors

We’re happy to announce Drizzle Themes 🎉🎉🎉

You can now create your own Drizzle Studio themes and apply them with just one click.

Drizzle Studio HTMX Theme

We’ve been handcrafting Drizzle Themes for the past several months and now we need your help!
Shadcn❤️ themes served us well and we love them, but it’s time to move on. We need your help to build our next Drizzle Theme and win $1000, hop on this Twitter thread to participate.
To create your own themes — visit our Themes Studio.

Benchmarks

Drizzle has always been fast, we just wanted you to have meaningful benchmarks, meet Drizzle DevOps experience dashboard 🚀

Drizzle Benchmarks

Drizzle has been originally designed to be a thin layer on top of SQL and introduce minimal runtime overhead and by introducing Prepared Statements and Relational Queries — we’ve smashed it. It’s now both fast and has exceptional DX and no n+1 problem for relational queries.

But how fast is it? Is it Drizzle or is it SQL who’s fast? What to measure?

What is a meaningful benchmark?
We’ve spent quite some time doing synthetic benchmarks with mitata, tested everything in one runtime and then in separate containerised so there’s no GC cross-influence, community made their own benchmarks and helped us allocate Relational Queries performance and row reads bottlenecks and make them really fast and efficient.

We’ve tested different SQL dialects across all the competitors, and while we were crazy fast, in some cases 100+ times faster than Prisma with SQLite, we only wanted to share benchmarks that were meaningful for businesses and developers.

From business perspective— request roundtrip is the most important metric when it comes down to the server-side performance. While you can influence network latency with services like Cloudflare Argo, on the server side it usually comes down to the database queries.

We’ve composed a test case with a ~370k records in a PostgreSQL database and generated production-like E-commerce traffic benchmarks on 1GB ethernet to eliminate any discrepancies. On Lenovo M720q Drizzle can handle 4.6k reqs/s while maintaining a ~100ms p95 latency.

Drizzle Studio got a massive upgrade 🚀

Apart from themes, Drizzle Studio now has a full blown TypeScript playground with linter, prettier and autocompletes!

We’ve also migrated away from AGgrid to React Data Grid and we now have a way smaller bundle size and smooth smooth smooth scrolling animations.

Drizzle Studio is now also capable of accessing Cloudflare D1 through their Wrangler CLI calls. You just need to provide the file path to your wrangler.toml file and specify the dbName you are using in Cloudflare D1

import { defineConfig } from 'drizzle-kit'

export default defineConfig({
schema: "./schema.ts",
out: "./drizzle",
driver: "d1",
dbCredentials: {
wranglerConfigPath: 'wrangler.toml', // here
dbName: 'd1-test', // and here
},
verbose: true,
strict: true,
})

Then make sure you have wrangler cli installed globally or inside your project and you invoked wrangler login, then just run drizzle-kit studio and voila, you’re browsing your D1 database. What a time to be alive 😎

Read replicas 🚀

You can now use the Drizzle withReplica function to specify different database connections for read replicas and the main instance for write operations

const primary = drizzle(client);
const replica1 = drizzle(client);
const replica2 = drizzle(client);

const db = withReplicas(primary, [replica1, replica2]);

// read from primary
db.$primary.select().from(usersTable);

// read from either read1 connection or read2 connection
db.select().from(usersTable)

// use primary database for delete operation
db.delete(usersTable).where(eq(usersTable.id, 1))

We provide a flexible api for you define any kind replicas selection logic

const db = withReplicas(primary, [replica1, replica2], (replicas) => {
const weight = [0.7, 0.3];
let cumulativeProbability = 0;
const rand = Math.random();

for (const [i, replica] of replicas.entries()) {
cumulativeProbability += weight[i]!;
if (rand < cumulativeProbability) return replica;
}
return replicas[0]!
});

Set operators in Drizzle ORM 🚀

In the latest Drizzle ORM release we’ve added support for UNIONS, INTERSECT and EXCEPT operators

import { union } from 'drizzle-orm/pg-core'

const allUsersQuery = db.select().from(users);
const allCustomersQuery = db.select().from(customers);

const result = await union(allUsersQuery, allCustomersQuery)

// or with the builder

const result = await db.select().from(users).union(db.select().from(customers));

Batch API support for Cloudflare D1

You can now use D1 batch API with Drizzle

const batchResponse = await db.batch([
db.insert(usersTable).values({ id: 1, name: 'John' }).returning({
id: usersTable.id,
}),
db.update(usersTable).set({ name: 'Dan' }).where(eq(usersTable.id, 1)),
db.query.usersTable.findMany({}),
db.select().from(usersTable).where(eq(usersTable.id, 1)),
db.select({ id: usersTable.id, invitedBy: usersTable.invitedBy }).from(
usersTable,
),
]);

Drizzle Kit now supports tsconfig imports, all NextJS app starters should work just fine!
We’ve also introduced PostgreSQL and MySQL proxy drivers — check here.
Bug fixes and performance improvements!

Honorable mentions 🫡

All above would not be possible without you, our beloved sponsors ❤️
Special thanks to Turso, Payload, Xata and Neon!

Clap, clap, clap, like and subscribe to our Twitter!

--

--