Skip to content

In search of the fastest TypeScript ORM

Bar chart comparing SQL generation speed across TypeScript ORMs and query buildersBar chart comparing SQL generation speed across TypeScript ORMs and query builders

I kept reading “just use Drizzle, it’s lightweight” and “ORMs are slow, use a query builder”. So I measured it.

The benchmark measures SQL generation speed alone: no database, no network, no connection pool, so what is left is the overhead the ORM adds to every request. Six entries, eight query types.


  • Environment: Node.js v24.18.1, Apple M4 Pro, 3 runs averaged.
  • Versions: Latest stable of every entry as of August 2026 (TypeORM 1.1.0, MikroORM 7.1.9, Sequelize 6.37.8, Drizzle 0.45.2, Knex 3.3.0, UQL 0.24.0).
  • Fairness: Each ORM uses its most idiomatic API (QueryBuilder for TypeORM/MikroORM), which benefits them by skipping entity overhead.
  • Why no Prisma? Prisma’s query compiler is Rust compiled to WebAssembly rather than pure JS/TS, and it exposes no public SQL-compilation API, so it cannot be measured this way.

Entry ops/sec vs winner
UQL 698K 1.00x
Knex 463K 0.66x
Sequelize 196K 0.28x
MikroORM 111K 0.16x
TypeORM 42K 0.06x
Drizzle 12K 0.02x
Entry ops/sec vs winner
UQL 2,161K 1.00x
Knex 695K 0.32x
TypeORM 282K 0.13x
Sequelize 236K 0.11x
MikroORM 218K 0.10x
Drizzle 79K 0.04x
Entry ops/sec vs winner
UQL 691K 1.00x
Knex 433K 0.63x
Sequelize 327K 0.47x
TypeORM 261K 0.38x
MikroORM 260K 0.38x
Drizzle 36K 0.05x
Entry ops/sec vs winner
UQL 3,996K 1.00x
Sequelize 1,361K 0.34x
Knex 1,084K 0.27x
TypeORM 507K 0.13x
MikroORM 263K 0.07x
Drizzle 207K 0.05x
Entry ops/sec vs winner
UQL 4,675K 1.00x
Sequelize 3,084K 0.66x
Knex 1,092K 0.23x
TypeORM 591K 0.13x
MikroORM 565K 0.12x
Drizzle 229K 0.05x
Entry ops/sec vs winner
UQL 1,365K 1.00x
Knex 614K 0.45x
Sequelize 381K 0.28x
TypeORM 276K 0.20x
MikroORM 73K 0.05x
Drizzle 59K 0.04x
Entry ops/sec vs winner
UQL 741K 1.00x
Knex 243K 0.33x
TypeORM 158K 0.21x
Sequelize 150K 0.20x
Drizzle 34K 0.05x
MikroORM 28K 0.04x
Entry ops/sec vs winner
UQL 1,482K 1.00x
Sequelize 416K 0.28x
Knex 304K 0.21x
TypeORM 277K 0.19x
Drizzle 74K 0.05x
MikroORM 69K 0.05x

Interactive charts


1. The “lightweight” option comes last in six of eight queries.

Drizzle, marketed as lightweight, is slower than Sequelize (a full ORM from 2014) in every category. Its expression trees create more intermediate objects than Sequelize’s string concatenation.

2. A standalone query builder can’t beat a well-designed ORM.

Knex has no entities or relations to deal with; it only builds SQL strings. Yet UQL, a full ORM with entities, relations and migrations, is faster in all eight categories, from 1.5x on batch INSERT to 4.9x on aggregates. “ORMs are slow” stops being true when the ORM precomputes its metadata and avoids intermediate allocations.


I wanted to know why the gap was so large. Most ORMs work out your schema at query time: “What table does User map to? What column is companyId? Is it nullable?” They answer these questions on every query.

UQL answers them once, at startup. Field-to-column mappings, table names and relation paths go into lookup tables before the first query runs, so generating SQL is reading from a cache.

The other difference is allocation. When TypeORM builds a SELECT, it creates a QueryBuilder, then an expression tree, then walks the tree to produce SQL. UQL pushes SQL fragments straight into a string buffer, with no intermediate objects for the garbage collector.


Database latency is 1-50ms and ORM overhead is microseconds, so for a low-traffic app the difference is noise. At scale it starts to count. Take the WHERE + SORT + LIMIT query at 1,000 req/s: UQL (1,365K ops/s) spends under 1ms of CPU per second generating SQL, MikroORM (73K ops/s) roughly 14ms, about 19x more before a byte reaches the network. On serverless, where you pay per millisecond of CPU, that shows up on the bill; in containers, as more instances.


I wrote UQL, which is why the benchmark lives in its own repo that anyone can audit and rerun.

This SQL-generation benchmark is no longer maintained (see the note above). The current one, with its repro steps, is on the benchmark page, and the comparison page goes feature by feature.



UQL is a JSON-native TypeScript ORM for Node.js and Bun. Supports PostgreSQL, PGlite, MySQL, MariaDB, MSSQL, SQLite, CockroachDB, Turso, Neon, Cloudflare D1 and MongoDB. Queries are plain JSON, typed to the leaf.