> 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

# How much memory does an ORM cost per request?

> Weighing the heap around a query looked like an afternoon of work. First I got zero bytes on Bun, then a 19% skew from forcing a collection.

Source: https://uql-orm.dev/blog/measuring-orm-memory

Someone on r/bun [asked how UQL’s RAM usage compares to Drizzle’s](https://www.reddit.com/r/bun/comments/1w2s434/comment/p6vlefo/). I didn’t know, so I measured it: weigh the heap, run the query, weigh it again, subtract.

## Three wrong numbers first

**Bun reported zero.** JavaScriptCore refreshes `heapUsed` only when it collects, so every entry looked like it had allocated nothing. The memory run is on Node, minus the two Bun SQL entries.

**A forced `global.gc()` added 19%.** It frees compiled code along with the garbage, and the rounds after it re-optimise as they run, allocating extra.

**One process ranked them by start order.** The first entry paid to JIT what the rest inherited warm. One process per entry now.

## What came out

Measured against hand-written `raw pg` with rows mapped by hand, so what is left is the ORM’s own allocation.

| Entry | Total KB | Adds KB |
| - | - | - |
| raw pg | 245 | floor |
| **UQL** | 446 | **+201** |
| Drizzle | 769 | +524 |
| Prisma | 1,053 | +808 |
| TypeORM | 1,065 | +820 |
| Sequelize | 1,296 | +1,051 |
| MikroORM | 3,864 | +3,619 |

18x between lightest and heaviest, where the same lifecycle in time spans 10x. One step accounts for nearly all of it: the nested read, the only one that turns two result sets into an object graph, costs UQL 184KB and MikroORM 2,060KB.

## What survives

Sixty more lifecycles, collected either side, leave the worst entry 42KB heavier (Sequelize), identity maps and all. What the table prices is the garbage each request hands the collector, not memory that stays.

## The answer

UQL adds 201KB per request, Drizzle 524KB, MikroORM 3.6MB. That is allocation, not resident memory, on one machine with no pooling and no concurrency.

[Run it yourself](https://github.com/rogerpadilla/ts-orm-benchmark): `bun run bench.memory` rewrites the table it publishes, so the [current numbers](https://uql-orm.dev/benchmark.md#memory) can never drift from the last run.

---

---

*[UQL](https://uql-orm.dev/index.md) 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.*
