Head to head

YATTA VS
THE FIELD

Seven frameworks. Ten weighted criteria. Real benchmarks. Zero cherry-picking.

GET /json · 20k req · 100 concurrent

RAW SPEED

Elysia49,966 req/s
Hono38,604 req/s
Yatta33,646 req/s
Fastify19,439 req/s
Koa14,889 req/s
Express14,560 req/s

Live from benchmarks.json — regenerated by GitHub Actions on every push to main. Same runner, same load, no cherry-picking.

Auth + validation + DB read · Yatta vs Hono + Drizzle · measured 2026-10-06

REAL-WORLD API

Raw /json speed is one thing. Real APIs do auth checks, validate input, and hit the database. We benchmarked the identical route on both stacks: in-process Bearer token check, param validation, SQLite point-read, JSON response. Same 10,000 users, same operations — no network hops in either.

Stackreq/sp50p95p99
Yatta (built-in ORM)2,02636.9ms130.4ms192.9ms
Hono + Drizzle1,71645.5ms144.0ms200.9ms

Honest result: on an identical real-world route, Yatta is ~1.18x the throughput of a well-assembled Hono + Drizzle single-process app. Not 7-12x — that old figure compared in-process Yatta against network-hop microservices (an architecture difference, not a framework one). This is the apples-to-apples test.

Methodology: GET /api/user/:id, 2k warmup + 20k requests at 100 concurrency, 3 runs each (fresh server + DB per run), median run reported. In-memory SQLite, 10k seeded users. Absolute req/s is capped by the test VM; the relative gap was consistent across all runs.

SQLite · Yatta ORM vs Drizzle · same database · measured 2026-10-06

DATABASE BENCHMARK

Same SQLite file, same table, same 10,000 rows, same operations. The only variable is the ORM. Yatta ships a typed SQLite ORM with zero setup.

OperationYatta ORMDrizzle
Indexed point read0.009ms0.043ms
Filtered list (100)0.071ms0.162ms
Insert + return0.188ms0.801ms
Transaction (3 ops)0.240ms0.667ms

Methodology: one shared SQLite file (bun:sqlite), users table with 10k rows, identical PRAGMAs for both ORMs. 500 warmup + 5,000 timed iterations per operation, 3 full runs; reported = median of per-run medians. Lower is better.

Auth + users + posts + DB + validation + tests + deploy · estimates

TIME TO BUILD

Estimated hours for one developer to ship a complete app. These are estimates based on the number of packages to configure — not measured stopwatch times.

Yatta~4h
AdonisJS~6h
Elysia~8h
NestJS~10h
Fastify~12h
Hono~12h
Express~16h
Koa~16h

Shorter bar = faster to ship. Yatta wins because auth, DB, validation, and jobs are built in — no assembly required.

What ships in the box

BATTERIES INCLUDED

FeatureYattaNestJSFastifHonoAdonisElysiaExpresKoa
Auth (sessions/JWT)●○○○●○○○
Database ORM●○○○●○○○
Realtime (WS/SSE)●○○○●○○○
Job queue●○○○○○○○
Cache●○○○○○○○
File storage●○○○○○○○
Mail●○○○●○○○
Rate limiting●○●○●○○○
Validation●●●●●●○○
Observability●○○○○○○○

Yatta ships these ten capabilities through its core runtime. Competing frameworks generally compose them through additional official or community packages (like @nestjs/* or @adonisjs/*) — each with its own config, version drift, and docs to manage.

RSS under load · measured 2026-10-06

MEMORY FOOTPRINT

Real RSS measurements — each framework’s /json server in its own OS process, 10k requests at 50 concurrency, RSS read from the OS.

Elysia66 MB
Hono69 MB
Yatta71 MB
Express83 MB
Fastify84 MB
Koa84 MB

Methodology: each framework's /json server in its own OS process, 10,000 requests at 50 concurrency, RSS read from the OS. Two rounds averaged. Lower is better.

10 criteria · published weights

WEIGHTED TOTALS

Scores are editorial (1–10 per criterion). Weights: Performance 15%, Developer experience 15%, Architecture 15%, Ecosystem 15%, TypeScript 10%, Database / ORM 10%, Security 5%, Testing 5%, Deployment 5%, Maturity 5%. Total = Σ(score × weight). Reproduce it: the weights, per-framework scores, and formula live in app/compare/page.tsx in this repo.

Scores are editorial (1–10 per criterion). Weights: Performance 15%, Developer experience 15%, Architecture 15%, Ecosystem 15%, TypeScript 10%, Database / ORM 10%, Security 5%, Testing 5%, Deployment 5%, Maturity 5%. Total = Σ(score × weight). Reproduce it: the weights, per-framework scores, and formula live in app/compare/page.tsx in this repo.

Scores are editorial (1–10 per criterion). Weights: Performance 15%, Developer experience 15%, Architecture 15%, Ecosystem 15%, TypeScript 10%, Database / ORM 10%, Security 5%, Testing 5%, Deployment 5%, Maturity 5%. Total = Σ(score × weight). Reproduce it: the weights, per-framework scores, and formula live in app/compare/page.tsx in this repo.

01NestJS
8.90
02Fastify
8.10
03Hono
7.90
04AdonisJS
7.65
05Elysia
7.65
06Yatta
7.35
07Express
7.30
08Koa
6.40

Worker runtimes · 4 workers · 20k tasks · measured 2026-10-06

RUNTIME ENGINE SHOOTOUT

Task dispatch throughput across worker runtimes. Same machine, same test methodology: 20,000 echo tasks across 4 workers, measuring throughput, p99 latency, memory, and IPC round-trip cost.

Runtime Throughput p99 Memory Workers IPC
Yatta Runtime 85,746 ops/s 10.51ms 52.5 MB 4 0.049ms
Bun Workers 104,623 ops/s 2.13ms 64.6 MB 4 0.086ms
Node worker_threads 40,888 ops/s 7.46ms 143.9 MB 4 0.154ms
Deno Workers 22,248 ops/s 10.88ms 105.1 MB 4 0.181ms

Honest note: Bun's raw workers edge out Yatta on pure echo throughput because Yatta's runtime includes the task scheduler, module isolation, and observability overhead. Yatta wins on batteries included — scheduling, multi-tenancy, and monitoring that raw workers don't provide.

Methodology: 20,000 ping-pong tasks dispatched across 4 workers. Throughput = tasks/second. p99 = 99th percentile task latency. IPC = single round-trip postMessage cost. All measured on the same machine, same day.

The challenge

BUILD THE SAME APP

Pick any framework. Build: user signup/login, posts CRUD, SQLite, validation, tests, deploy to production.

Time yourself. Then build it in Yatta.

ESTIMATED IMPLEMENTATION EFFORT: ~4H.

The rest take 6-16. That gap is the batteries.