From ffee47f57403cf4923f42d690278fcc067f909a2 Mon Sep 17 00:00:00 2001 From: Dinh Le Date: Thu, 10 Sep 2026 11:04:01 +0700 Subject: [PATCH 1/3] docs: update performance comparison for oRPC 2.0.0-beta.35 Refresh the comparison page and homepage stat cards from the latest middleapi/orpc-benchmarks runs: HTTP RPC and OpenAPI throughput, Clinic Doctor memory ranges, and the type-check results, which now also list Instantiations. Bundle sizes are re-measured for beta.35 and the tRPC and Hono bundlejs links are pinned to the versions the benchmarks use so the table reproduces. The WebSocket oRPC run in the benchmarks repo still reflects beta.26, and the tRPC and Hono runs date from 2026-08-09; the intro now says so instead of claiming a single measurement day. --- apps/content/docs/comparison.mdx | 31 ++++++++++++----------- apps/content/pages/_home/Comparison.astro | 10 ++++---- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/apps/content/docs/comparison.mdx b/apps/content/docs/comparison.mdx index b3c674e1d..0915c08af 100644 --- a/apps/content/docs/comparison.mdx +++ b/apps/content/docs/comparison.mdx @@ -74,17 +74,17 @@ Coming from tRPC? Follow the [migration guide](/docs/migrations/from-trpc), or [ Treat these numbers as reference measurements, not a reason to switch frameworks. All three are fast enough for production. The per-request difference is tiny next to your business logic, database, and network, and results vary across environments and workloads. ::: -All numbers were measured on 2026-08-09 with oRPC 2.0.0-beta.26, tRPC 11.18.0, and Hono 4.13.1, and are reproducible from [middleapi/orpc-benchmarks](https://github.com/middleapi/orpc-benchmarks). Handlers are no-ops with pass-through validation, so the results measure framework overhead only. +All numbers come from [middleapi/orpc-benchmarks](https://github.com/middleapi/orpc-benchmarks) and were measured on the same machine: oRPC 2.0.0-beta.35 on 2026-09-10, and tRPC 11.18.0 and Hono 4.13.1 on 2026-08-09. The oRPC WebSocket run is the one exception and still reflects 2.0.0-beta.26 from 2026-08-09. Handlers are no-ops with pass-through validation, so the results measure framework overhead only. ### Throughput | Scenario | oRPC | tRPC | Hono | | --- | --- | --- | --- | -| RPC over HTTP (req/s avg) | 18,551 | 4,299 | n/a | +| RPC over HTTP (req/s avg) | 18,845 | 4,299 | n/a | | RPC over WebSocket (req/s avg) | 24,126 | 5,054 | n/a | -| OpenAPI (RESTful) over HTTP (req/s avg) | 17,871 | n/a | 16,932 | +| OpenAPI (RESTful) over HTTP (req/s avg) | 18,014 | n/a | 16,932 | -oRPC handles about 4.3x as many requests as tRPC over HTTP and 4.8x over WebSocket. oRPC and Hono are effectively tied on RESTful throughput. +oRPC handles about 4.4x as many requests as tRPC over HTTP and 4.8x over WebSocket. oRPC and Hono are close on RESTful throughput, with oRPC about 6% ahead. ### Clinic Doctor Profiles @@ -92,35 +92,36 @@ Every run also profiles the server with [Clinic.js Doctor](https://clinicjs.org/ | Run | CPU (avg) | Memory (RSS) | Detected issues | Full report | | --- | --- | --- | --- | --- | -| RPC over HTTP · oRPC | ~104% | 71-92 MB | none | [view](https://htmlpreview.github.io/?https://github.com/middleapi/orpc-benchmarks/blob/main/benchmarks/rpc-orpc/.clinic/report.clinic-doctor.html) | +| RPC over HTTP · oRPC | ~104% | 73-91 MB | none | [view](https://htmlpreview.github.io/?https://github.com/middleapi/orpc-benchmarks/blob/main/benchmarks/rpc-orpc/.clinic/report.clinic-doctor.html) | | RPC over HTTP · tRPC | ~113% | 73-247 MB | none | [view](https://htmlpreview.github.io/?https://github.com/middleapi/orpc-benchmarks/blob/main/benchmarks/rpc-trpc/.clinic/report.clinic-doctor.html) | | RPC over WebSocket · oRPC | ~104% | 71-110 MB | none | [view](https://htmlpreview.github.io/?https://github.com/middleapi/orpc-benchmarks/blob/main/benchmarks/ws-orpc/.clinic/report.clinic-doctor.html) | | RPC over WebSocket · tRPC | ~41% | 67-75 MB | cpu: performance | [view](https://htmlpreview.github.io/?https://github.com/middleapi/orpc-benchmarks/blob/main/benchmarks/ws-trpc/.clinic/report.clinic-doctor.html) | -| OpenAPI over HTTP · oRPC | ~104% | 71-92 MB | none | [view](https://htmlpreview.github.io/?https://github.com/middleapi/orpc-benchmarks/blob/main/benchmarks/openapi-orpc/.clinic/report.clinic-doctor.html) | +| OpenAPI over HTTP · oRPC | ~104% | 73-92 MB | none | [view](https://htmlpreview.github.io/?https://github.com/middleapi/orpc-benchmarks/blob/main/benchmarks/openapi-orpc/.clinic/report.clinic-doctor.html) | | OpenAPI over HTTP · Hono | ~103% | 71-95 MB | none | [view](https://htmlpreview.github.io/?https://github.com/middleapi/orpc-benchmarks/blob/main/benchmarks/openapi-hono/.clinic/report.clinic-doctor.html) | -The profiles show where the throughput gap comes from. Over HTTP, oRPC serves over 4x tRPC's requests at similar CPU usage (~104% vs ~113%), so its per-request CPU cost is several times lower, and its event loop stays responsive: 0.04 ms average delay versus tRPC's 0.70 ms. Memory stays flat between 71 and 110 MB in every oRPC run, while tRPC's HTTP run climbs to 247 MB, more than double oRPC's highest reading, a sign of per-request allocation pressure. oRPC and Hono profile nearly identically, matching their tied throughput. +The profiles show where the throughput gap comes from. Over HTTP, oRPC serves over 4x tRPC's requests at similar CPU usage (~104% vs ~113%), so its per-request CPU cost is several times lower, and its event loop stays responsive: 0.04 ms average delay versus tRPC's 0.70 ms. Memory stays flat between 71 and 110 MB in every oRPC run, while tRPC's HTTP run climbs to 247 MB, more than double oRPC's highest reading, a sign of per-request allocation pressure. oRPC and Hono profile nearly identically, in line with their close throughput. tRPC's low WebSocket CPU is not an advantage: the `cpu: performance` issue means the server cannot keep the CPU busy, so throughput is capped elsewhere in the stack. ### Type-Checking Performance -On a large, fully typed project with 3,000 procedures across 1,501 routers, oRPC type-checks about 20% faster than tRPC and uses about 28% less memory: +On a large, fully typed project with 3,000 procedures across 1,501 routers, oRPC type-checks about 32% faster than tRPC, uses about 31% less memory, and needs about 19% fewer type instantiations: | Metric | oRPC | tRPC | | --- | --- | --- | -| Total time | 1.96s | 2.47s | -| Memory used | 487 MB | 677 MB | +| Total time | 1.67s | 2.47s | +| Memory used | 469 MB | 677 MB | +| Instantiations | 2,198,327 | 2,719,560 | -Hono is excluded: its RPC types hit [documented limits](https://hono.dev/docs/guides/rpc#known-issues) at this scale and need workarounds like pre-compiled client types, an issue oRPC avoids by design. +Instantiations count the generic type expansions TypeScript performs during a check, so fewer means less work in CI and in your editor. Hono is excluded: its RPC types hit [documented limits](https://hono.dev/docs/guides/rpc#known-issues) at this scale and need workarounds like pre-compiled client types, an issue oRPC avoids by design. ### Bundle Size -Bundle sizes for a minimal client and server pair, measured the same day. tRPC includes `superjson` to match oRPC's built-in native types, and Hono includes `@hono/node-server` to match the Node.js servers in the other bundles. +Bundle sizes for a minimal client and server pair, measured on 2026-09-10 with the same versions. tRPC includes `superjson` to match oRPC's built-in native types, and Hono includes `@hono/node-server` to match the Node.js servers in the other bundles. | Metric | oRPC | tRPC | Hono | | --- | --- | --- | --- | -| Minified | 45.0 kB | 82.9 kB | 43.3 kB | -| Minified + gzip | 14.1 kB | 25.5 kB | 16.4 kB | +| Minified | 46.4 kB | 83.3 kB | 43.3 kB | +| Minified + gzip | 14.5 kB | 25.6 kB | 16.4 kB | -Measure yourself: [oRPC](https://bundlejs.com/?q=%40orpc%2Fclient%402.0.0-beta.26%2C%40orpc%2Fclient%402.0.0-beta.26%2Ffetch%2C%40orpc%2Fserver%402.0.0-beta.26%2C%40orpc%2Fserver%402.0.0-beta.26%2Fnode&treeshake=%5B%7B+createORPCClient+%7D%5D%2C%5B%7B+RPCLink+%7D%5D%2C%5B%7B+os+%7D%5D%2C%5B%7B+RPCHandler+%7D%5D) · [tRPC](https://bundlejs.com/?q=%40trpc%2Fclient%2C%40trpc%2Fserver%2C%40trpc%2Fserver%2Fadapters%2Fstandalone%2Csuperjson&treeshake=%5B%7B+createTRPCClient%2ChttpLink%2ChttpSubscriptionLink%2CsplitLink+%7D%5D%2C%5B%7B+initTRPC+%7D%5D%2C%5B%7B+createHTTPServer+%7D%5D%2C%5B%7B+default+as+SuperJSON+%7D%5D) · [Hono](https://bundlejs.com/?q=hono%2Chono%2Fclient%2C%40hono%2Fnode-server&treeshake=%5B%7B+Hono+%7D%5D%2C%5B%7B+hc+%7D%5D%2C%5B%7B+serve+%7D%5D) +Measure yourself: [oRPC](https://bundlejs.com/?q=%40orpc%2Fclient%402.0.0-beta.35%2C%40orpc%2Fclient%402.0.0-beta.35%2Ffetch%2C%40orpc%2Fserver%402.0.0-beta.35%2C%40orpc%2Fserver%402.0.0-beta.35%2Fnode&treeshake=%5B%7B+createORPCClient+%7D%5D%2C%5B%7B+RPCLink+%7D%5D%2C%5B%7B+os+%7D%5D%2C%5B%7B+RPCHandler+%7D%5D) · [tRPC](https://bundlejs.com/?q=%40trpc%2Fclient%4011.18.0%2C%40trpc%2Fserver%4011.18.0%2C%40trpc%2Fserver%4011.18.0%2Fadapters%2Fstandalone%2Csuperjson%402.2.6&treeshake=%5B%7B+createTRPCClient%2ChttpLink%2ChttpSubscriptionLink%2CsplitLink+%7D%5D%2C%5B%7B+initTRPC+%7D%5D%2C%5B%7B+createHTTPServer+%7D%5D%2C%5B%7B+default+as+SuperJSON+%7D%5D) · [Hono](https://bundlejs.com/?q=hono%404.13.1%2Chono%404.13.1%2Fclient%2C%40hono%2Fnode-server%402.1.0&treeshake=%5B%7B+Hono+%7D%5D%2C%5B%7B+hc+%7D%5D%2C%5B%7B+serve+%7D%5D) diff --git a/apps/content/pages/_home/Comparison.astro b/apps/content/pages/_home/Comparison.astro index 5d4c18e38..d396a6e10 100644 --- a/apps/content/pages/_home/Comparison.astro +++ b/apps/content/pages/_home/Comparison.astro @@ -57,16 +57,16 @@ const legendOrder = ['full', 'partial', 'none'] as const const numbers = [ { - value: '4.3x', + value: '4.4x', body: 'the RPC throughput of tRPC over HTTP, and 4.8x over WebSocket.', }, { - value: '20%', - body: 'faster type-checking than tRPC across 3,000 procedures, on 28% less memory.', + value: '32%', + body: 'faster type-checking than tRPC across 3,000 procedures, on 31% less memory.', }, { - value: '14.1 kB', - body: 'gzipped for a client and server pair, against 25.5 kB for tRPC.', + value: '14.5 kB', + body: 'gzipped for a client and server pair, against 25.6 kB for tRPC.', }, ] --- From 64dec3b7768d2288b345ae0596049d490fd09f9c Mon Sep 17 00:00:00 2001 From: Dinh Le Date: Thu, 10 Sep 2026 11:24:28 +0700 Subject: [PATCH 2/3] docs: refresh WebSocket run and simplify the Hono type-check note Pick up the ws-orpc beta.35 result so every oRPC run now dates from 2026-09-10, dropping the beta.26 caveat from the intro. Shorten the Hono exclusion under the type-checking table to a general statement and remove the instantiations explainer. --- apps/content/docs/comparison.mdx | 12 ++++++------ apps/content/pages/_home/Comparison.astro | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/content/docs/comparison.mdx b/apps/content/docs/comparison.mdx index 0915c08af..e7efe6351 100644 --- a/apps/content/docs/comparison.mdx +++ b/apps/content/docs/comparison.mdx @@ -74,17 +74,17 @@ Coming from tRPC? Follow the [migration guide](/docs/migrations/from-trpc), or [ Treat these numbers as reference measurements, not a reason to switch frameworks. All three are fast enough for production. The per-request difference is tiny next to your business logic, database, and network, and results vary across environments and workloads. ::: -All numbers come from [middleapi/orpc-benchmarks](https://github.com/middleapi/orpc-benchmarks) and were measured on the same machine: oRPC 2.0.0-beta.35 on 2026-09-10, and tRPC 11.18.0 and Hono 4.13.1 on 2026-08-09. The oRPC WebSocket run is the one exception and still reflects 2.0.0-beta.26 from 2026-08-09. Handlers are no-ops with pass-through validation, so the results measure framework overhead only. +All numbers come from [middleapi/orpc-benchmarks](https://github.com/middleapi/orpc-benchmarks) and were measured on the same machine: oRPC 2.0.0-beta.35 on 2026-09-10, and tRPC 11.18.0 and Hono 4.13.1 on 2026-08-09. Handlers are no-ops with pass-through validation, so the results measure framework overhead only. ### Throughput | Scenario | oRPC | tRPC | Hono | | --- | --- | --- | --- | | RPC over HTTP (req/s avg) | 18,845 | 4,299 | n/a | -| RPC over WebSocket (req/s avg) | 24,126 | 5,054 | n/a | +| RPC over WebSocket (req/s avg) | 23,815 | 5,054 | n/a | | OpenAPI (RESTful) over HTTP (req/s avg) | 18,014 | n/a | 16,932 | -oRPC handles about 4.4x as many requests as tRPC over HTTP and 4.8x over WebSocket. oRPC and Hono are close on RESTful throughput, with oRPC about 6% ahead. +oRPC handles about 4.4x as many requests as tRPC over HTTP and 4.7x over WebSocket. oRPC and Hono are close on RESTful throughput, with oRPC about 6% ahead. ### Clinic Doctor Profiles @@ -94,12 +94,12 @@ Every run also profiles the server with [Clinic.js Doctor](https://clinicjs.org/ | --- | --- | --- | --- | --- | | RPC over HTTP · oRPC | ~104% | 73-91 MB | none | [view](https://htmlpreview.github.io/?https://github.com/middleapi/orpc-benchmarks/blob/main/benchmarks/rpc-orpc/.clinic/report.clinic-doctor.html) | | RPC over HTTP · tRPC | ~113% | 73-247 MB | none | [view](https://htmlpreview.github.io/?https://github.com/middleapi/orpc-benchmarks/blob/main/benchmarks/rpc-trpc/.clinic/report.clinic-doctor.html) | -| RPC over WebSocket · oRPC | ~104% | 71-110 MB | none | [view](https://htmlpreview.github.io/?https://github.com/middleapi/orpc-benchmarks/blob/main/benchmarks/ws-orpc/.clinic/report.clinic-doctor.html) | +| RPC over WebSocket · oRPC | ~104% | 71-109 MB | none | [view](https://htmlpreview.github.io/?https://github.com/middleapi/orpc-benchmarks/blob/main/benchmarks/ws-orpc/.clinic/report.clinic-doctor.html) | | RPC over WebSocket · tRPC | ~41% | 67-75 MB | cpu: performance | [view](https://htmlpreview.github.io/?https://github.com/middleapi/orpc-benchmarks/blob/main/benchmarks/ws-trpc/.clinic/report.clinic-doctor.html) | | OpenAPI over HTTP · oRPC | ~104% | 73-92 MB | none | [view](https://htmlpreview.github.io/?https://github.com/middleapi/orpc-benchmarks/blob/main/benchmarks/openapi-orpc/.clinic/report.clinic-doctor.html) | | OpenAPI over HTTP · Hono | ~103% | 71-95 MB | none | [view](https://htmlpreview.github.io/?https://github.com/middleapi/orpc-benchmarks/blob/main/benchmarks/openapi-hono/.clinic/report.clinic-doctor.html) | -The profiles show where the throughput gap comes from. Over HTTP, oRPC serves over 4x tRPC's requests at similar CPU usage (~104% vs ~113%), so its per-request CPU cost is several times lower, and its event loop stays responsive: 0.04 ms average delay versus tRPC's 0.70 ms. Memory stays flat between 71 and 110 MB in every oRPC run, while tRPC's HTTP run climbs to 247 MB, more than double oRPC's highest reading, a sign of per-request allocation pressure. oRPC and Hono profile nearly identically, in line with their close throughput. +The profiles show where the throughput gap comes from. Over HTTP, oRPC serves over 4x tRPC's requests at similar CPU usage (~104% vs ~113%), so its per-request CPU cost is several times lower, and its event loop stays responsive: 0.04 ms average delay versus tRPC's 0.70 ms. Memory stays flat between 71 and 109 MB in every oRPC run, while tRPC's HTTP run climbs to 247 MB, more than double oRPC's highest reading, a sign of per-request allocation pressure. oRPC and Hono profile nearly identically, in line with their close throughput. tRPC's low WebSocket CPU is not an advantage: the `cpu: performance` issue means the server cannot keep the CPU busy, so throughput is capped elsewhere in the stack. @@ -113,7 +113,7 @@ On a large, fully typed project with 3,000 procedures across 1,501 routers, oRPC | Memory used | 469 MB | 677 MB | | Instantiations | 2,198,327 | 2,719,560 | -Instantiations count the generic type expansions TypeScript performs during a check, so fewer means less work in CI and in your editor. Hono is excluded: its RPC types hit [documented limits](https://hono.dev/docs/guides/rpc#known-issues) at this scale and need workarounds like pre-compiled client types, an issue oRPC avoids by design. +Hono has no column because it does not scale to this size. Its RPC types hit [known limits](https://hono.dev/docs/guides/rpc#known-issues) well before this point and the project becomes effectively unusable, an issue oRPC avoids by design. ### Bundle Size diff --git a/apps/content/pages/_home/Comparison.astro b/apps/content/pages/_home/Comparison.astro index d396a6e10..0bf8de844 100644 --- a/apps/content/pages/_home/Comparison.astro +++ b/apps/content/pages/_home/Comparison.astro @@ -58,7 +58,7 @@ const legendOrder = ['full', 'partial', 'none'] as const const numbers = [ { value: '4.4x', - body: 'the RPC throughput of tRPC over HTTP, and 4.8x over WebSocket.', + body: 'the RPC throughput of tRPC over HTTP, and 4.7x over WebSocket.', }, { value: '32%', From c9fdaa7389966a0b99e2e49c9caf8d3646bcb33b Mon Sep 17 00:00:00 2001 From: Dinh Le Date: Thu, 10 Sep 2026 11:26:12 +0700 Subject: [PATCH 3/3] docs: drop measurement dates from the comparison page --- apps/content/docs/comparison.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/content/docs/comparison.mdx b/apps/content/docs/comparison.mdx index e7efe6351..02eb2417b 100644 --- a/apps/content/docs/comparison.mdx +++ b/apps/content/docs/comparison.mdx @@ -74,7 +74,7 @@ Coming from tRPC? Follow the [migration guide](/docs/migrations/from-trpc), or [ Treat these numbers as reference measurements, not a reason to switch frameworks. All three are fast enough for production. The per-request difference is tiny next to your business logic, database, and network, and results vary across environments and workloads. ::: -All numbers come from [middleapi/orpc-benchmarks](https://github.com/middleapi/orpc-benchmarks) and were measured on the same machine: oRPC 2.0.0-beta.35 on 2026-09-10, and tRPC 11.18.0 and Hono 4.13.1 on 2026-08-09. Handlers are no-ops with pass-through validation, so the results measure framework overhead only. +All numbers come from [middleapi/orpc-benchmarks](https://github.com/middleapi/orpc-benchmarks) and were measured on the same machine with oRPC 2.0.0-beta.35, tRPC 11.18.0, and Hono 4.13.1. Handlers are no-ops with pass-through validation, so the results measure framework overhead only. ### Throughput @@ -117,7 +117,7 @@ Hono has no column because it does not scale to this size. Its RPC types hit [kn ### Bundle Size -Bundle sizes for a minimal client and server pair, measured on 2026-09-10 with the same versions. tRPC includes `superjson` to match oRPC's built-in native types, and Hono includes `@hono/node-server` to match the Node.js servers in the other bundles. +Bundle sizes for a minimal client and server pair, measured with the same versions. tRPC includes `superjson` to match oRPC's built-in native types, and Hono includes `@hono/node-server` to match the Node.js servers in the other bundles. | Metric | oRPC | tRPC | Hono | | --- | --- | --- | --- |