> Every UQL docs page, as Markdown: https://uql-orm.dev/llms.txt
> The same docs over MCP: https://uql-orm.dev/mcp
> Before writing UQL code, read the skill: https://uql-orm.dev/.well-known/agent-skills/uql-orm/SKILL.md

# What does an ORM really cost you?

> A full PostgreSQL round trip through six TypeScript ORMs, and what each adds over hand-written driver code. The totals hide where the time goes.

Source: https://uql-orm.dev/blog/what-orms-really-cost

My bench now does real stuff, full PostgreSQL round-trip operations.

Six ORMs, one real PostgreSQL, and a full lifecycle per pass: insert 10 rows, read 200 back with a filter and a sort, update one, read it again, load 50 parents with their children, delete, read the empty table. Every step timed separately, median of 250 interleaved iterations.

## The results

| Entry | Adds | Total |
| - | - | - |
| UQL | +232µs | 1,621µs |
| Drizzle | +685µs | 2,074µs |
| TypeORM | +838µs | 2,227µs |
| Sequelize | +1,185µs | 2,574µs |
| Prisma | +1,345µs | 2,734µs |
| MikroORM | +2,236µs | 3,625µs |

> Figures as measured when this was written, on `pg` throughout. The harness is re-run as versions move, so the [current results](https://uql-orm.dev/benchmark.md) will differ.

**Adds** is the number to read. Every entry pays the same PostgreSQL bill, so the totals compress into a 2.2x range and every ORM looks about the same. Subtract the floor, which is hand-written SQL with the rows mapped by hand at 1,389µs, and what is left is the ORM’s own contribution. That spans nearly 9.6x.

Everything above runs on node-postgres, so the driver is not the variable. Four of the six support nothing else.

## Prisma

Prisma is not slow across the board, and it does not finish last; it was MikroORM at 3,625µs against Prisma’s 2,734µs. Prisma’s nested read, the hardest step in the set, is the second fastest of any ORM here at 440µs. Its update, delete and single-row reads are all mid-field.

It is one step:

| INSERT 10 rows | |
| - | - |
| raw pg (hand-written) | 454µs |
| UQL | 488µs |
| MikroORM | 625µs |
| Drizzle | 635µs |
| Sequelize | 643µs |
| TypeORM | 668µs |
| **Prisma** | **1,366µs** |

That one step is 2.0x the next slowest ORM and it is most of why Prisma places fifth. Turning on its query log shows what it sends:

```sql title="What Prisma sends for createManyAndReturn"
INSERT INTO "public"."User" ("name","email","companyId") VALUES ($1,$2,$3), ($4,$5,$6), ...
COMMIT
```

So `createManyAndReturn` wraps the batch in an explicit transaction, where the other five send one statement and stop. That is reasonable, but it does not explain the gap: a BEGIN/COMMIT pair on this machine costs 88µs, and the gap to TypeORM, the next slowest here, is 698µs. The transaction is about an eighth of it. The rest is Prisma’s own overhead on the way in and out, which is the part you cannot opt out of.

Prisma 7 dropped its Rust query engine, and the client runtime is now TypeScript. This is the faster Prisma, not the old one.

## The nested read is where ORMs are actually decided

It is the only step that loads a relation, and it has the widest spread of any read:

| SELECT 50 parents with their children | |
| - | - |
| raw pg (hand-written) | 256µs |
| UQL | 346µs |
| Prisma | 440µs |
| TypeORM | 498µs |
| Drizzle | 535µs |
| Sequelize | 680µs |
| MikroORM | 1,205µs |

This step matters most, because turning two result sets into an object graph without an N+1 is the main job of an ORM, and here the field spans 3.5x.

## Run it yourself

```bash
git clone https://github.com/rogerpadilla/ts-orm-benchmark.git
cd ts-orm-benchmark
bun install

DATABASE_URL=postgres:///postgres npm run bench
```

It creates its own database and rewrites its own result tables, so the published numbers cannot drift from the last run. CI runs the full lifecycle with assertions on every push.

The latest set always lives on the [benchmark page](https://uql-orm.dev/benchmark.md), and there is a feature-by-feature [comparison](https://uql-orm.dev/comparison.md) if speed is not your only axis. If your numbers come out different, open an issue.

---

---

*[UQL](https://uql-orm.dev/index.md) is a JSON-native TypeScript ORM for Node.js, Bun and Deno. Supports PostgreSQL, PGlite, MySQL, MariaDB, MSSQL, SQLite, CockroachDB, Turso, Neon, Cloudflare D1 and MongoDB. Queries are plain JSON, typed to the leaf.*
