Proa-Labs/proa-benchmarks

Reproducible browser-performance research and evidence for Proa

JavaScript

6

8 commits

updated Oct 1, 2026

See the code

See what people are saying

SourceMessageScoreDate

> This might be a silly question, but why 2 views for html and markdown? No such thing as silly questions! Yes there are cases where it can be inferred from one to the other, but in many cases you may want to be very specific about how you author the markdown view. I'll give you a few examples: 1.…

on Show HN: Proa – A Rust web framework with fast SSR and multi-target rendering

0

Oct 15, 2026

Show HN: Proa – a Rust web framework with fast SSR and multi-target rendering

107

Oct 15, 2026

Proa: A rust web framework for people and agents (r/rust)

Hi I’m Andrew, I’ve been writing Rust professionally for five years, and today I’m excited to announce the release of Proa (https://github.com/Proa-Labs/proa) a new Rust web framework I've been building! Performance: To serve as many people and agents at scale, we’ve tried to keep framework…

0

Oct 13, 2026

README

Proa benchmarks

Proa renders typed Rust components to HTML on the server, streams them, and hydrates fine-grained browser islands. This page shows what one core serves over HTTP, how fast seventeen renderers render those pages, and how to reproduce them.

If you see an issue with the benchmarks or would like to add any, please open an issue!

Rendering the same pages in seventeen renderers

Renderer-only benchmark across three canonical pages: component, table, and product grid.

Dot plot of seventeen renderers across three workloads, on a logarithmic axis of render time relative to Proa

Seventeen renderers, one-core P50 multiples on log scale. Details · Full size · how the figures are built

Serving three pages on one core

Three sample pages, one core each: throughput at saturation, latency at a fixed request rate.

Sustained responses per second, CPU per response, and peak RSS for Proa, React, Marko, and Go html/template serving three canonical pages over HTTP on one core

Three parity-gated pages on loopback HTTP, one core per engine. Details · Full size · how the figures are built

Render time vs memcpy on one core

Legacy one-core mechanism view: workload speed vs Proa memcpy floor.

Render time relative to memcpy across three workloads and eleven showcase pages on one core

Three workloads + allocation context as multiples of a memcpy baseline. Details · Full size · how the figures are built

Streaming the product grid through Suspense

Single-core Suspense streaming with eight async boundaries per request.

Responses completed per second, latency distribution and peak memory for Proa, Marko and React streaming the product grid through Suspense over HTTP on one core

Throughput sweep with queueing markers (P50/P95/P99 + memory) at each rate. Details · Full size · how the figures are built

Canonical latency tails on one core

Single-core P50 and P95 for the same three canonical workloads.

P50 and P95 render-latency spread for seventeen renderers on three workloads, one core

Tail spread with heavy-tail markers on three workloads. Details · Full size · how the figures are built

Proa linked showcase corpus

Proa-only linked pages: five runs each, with render range and size.

Proa linked showcase corpus render times

Application-like page samples and stability notes. Details · Full size · how the figures are built

Cold start to first response

Startup latency from process creation to first byte-identical response.

Median, P95 and slowest time from process spawn to first complete product-grid response for Proa, React, Marko and Go html/template, with RSS after the first response

Median, P95, and worst-start across 15 fresh processes. Details · Full size · how the figures are built

Reproducing a capture

Install the JavaScript dependencies once. You need Node.js 24.20.0 exactly — the canonical runner compares process.version and refuses to run on anything else — with pnpm, the Rust toolchain in rust-toolchain.toml, and Go 1.25. The full scoreboard also needs Ruby 3.2+, a JDK 17+ with Gradle, PHP 8, and Python 3.13+.

pnpm install --frozen-lockfile
pnpm exec playwright install chromium
npm ci --prefix rendering/external/react
npm ci --prefix rendering/external/marko
npm ci --prefix rendering/external/handlebars

Then run a suite. Each command builds its servers, gates every page for parity, and rewrites its evidence page. It refuses to publish a phase whose load generator was the bottleneck.

./rendering/run-all            # scoreboard: build, parity-gate, time, regenerate scoreboard.md
pnpm run bench:page-load       # canonical pages over HTTP, one core each
pnpm run bench:cold-start      # cold start to first response
pnpm run bench:suspense-load   # Suspense streaming over HTTP
pnpm run refresh               # regenerate every evidence page and figure from the captures

Good to know: the committed numbers are dated evidence from one machine, not universal claims. Rerun the relevant suite before publishing a current comparison.

Next steps

License and attribution

This repository is Apache-2.0; see LICENSE. Benchmark adapters incorporate upstream work under its own terms, recorded in rendering/UPSTREAM_LICENSES.md.

React, Marko, Vue, Svelte, Rails, jte, Rocker, Handlebars, Go, Jinja2, PHP, Askama, Sailfish, Leptos, Dioxus, and Topcoat belong to their respective owners. They appear here as the subjects of a benchmark; their inclusion implies no endorsement.

Proa-Labs/proa-benchmarks

Reproducible browser-performance research and evidence for Proa

JavaScript

6

8 commits

updated Oct 1, 2026

See the code

See what people are saying

SourceMessageScoreDate

> This might be a silly question, but why 2 views for html and markdown? No such thing as silly questions! Yes there are cases where it can be inferred from one to the other, but in many cases you may want to be very specific about how you author the markdown view. I'll give you a few examples: 1.…

on Show HN: Proa – A Rust web framework with fast SSR and multi-target rendering

0

Oct 15, 2026

Show HN: Proa – a Rust web framework with fast SSR and multi-target rendering

107

Oct 15, 2026

Proa: A rust web framework for people and agents (r/rust)

Hi I’m Andrew, I’ve been writing Rust professionally for five years, and today I’m excited to announce the release of Proa (https://github.com/Proa-Labs/proa) a new Rust web framework I've been building! Performance: To serve as many people and agents at scale, we’ve tried to keep framework…

0

Oct 13, 2026

README

Proa benchmarks

Proa renders typed Rust components to HTML on the server, streams them, and hydrates fine-grained browser islands. This page shows what one core serves over HTTP, how fast seventeen renderers render those pages, and how to reproduce them.

If you see an issue with the benchmarks or would like to add any, please open an issue!

Rendering the same pages in seventeen renderers

Renderer-only benchmark across three canonical pages: component, table, and product grid.

Dot plot of seventeen renderers across three workloads, on a logarithmic axis of render time relative to Proa

Seventeen renderers, one-core P50 multiples on log scale. Details · Full size · how the figures are built

Serving three pages on one core

Three sample pages, one core each: throughput at saturation, latency at a fixed request rate.

Sustained responses per second, CPU per response, and peak RSS for Proa, React, Marko, and Go html/template serving three canonical pages over HTTP on one core

Three parity-gated pages on loopback HTTP, one core per engine. Details · Full size · how the figures are built

Render time vs memcpy on one core

Legacy one-core mechanism view: workload speed vs Proa memcpy floor.

Render time relative to memcpy across three workloads and eleven showcase pages on one core

Three workloads + allocation context as multiples of a memcpy baseline. Details · Full size · how the figures are built

Streaming the product grid through Suspense

Single-core Suspense streaming with eight async boundaries per request.

Responses completed per second, latency distribution and peak memory for Proa, Marko and React streaming the product grid through Suspense over HTTP on one core

Throughput sweep with queueing markers (P50/P95/P99 + memory) at each rate. Details · Full size · how the figures are built

Canonical latency tails on one core

Single-core P50 and P95 for the same three canonical workloads.

P50 and P95 render-latency spread for seventeen renderers on three workloads, one core

Tail spread with heavy-tail markers on three workloads. Details · Full size · how the figures are built

Proa linked showcase corpus

Proa-only linked pages: five runs each, with render range and size.

Proa linked showcase corpus render times

Application-like page samples and stability notes. Details · Full size · how the figures are built

Cold start to first response

Startup latency from process creation to first byte-identical response.

Median, P95 and slowest time from process spawn to first complete product-grid response for Proa, React, Marko and Go html/template, with RSS after the first response

Median, P95, and worst-start across 15 fresh processes. Details · Full size · how the figures are built

Reproducing a capture

Install the JavaScript dependencies once. You need Node.js 24.20.0 exactly — the canonical runner compares process.version and refuses to run on anything else — with pnpm, the Rust toolchain in rust-toolchain.toml, and Go 1.25. The full scoreboard also needs Ruby 3.2+, a JDK 17+ with Gradle, PHP 8, and Python 3.13+.

pnpm install --frozen-lockfile
pnpm exec playwright install chromium
npm ci --prefix rendering/external/react
npm ci --prefix rendering/external/marko
npm ci --prefix rendering/external/handlebars

Then run a suite. Each command builds its servers, gates every page for parity, and rewrites its evidence page. It refuses to publish a phase whose load generator was the bottleneck.

./rendering/run-all            # scoreboard: build, parity-gate, time, regenerate scoreboard.md
pnpm run bench:page-load       # canonical pages over HTTP, one core each
pnpm run bench:cold-start      # cold start to first response
pnpm run bench:suspense-load   # Suspense streaming over HTTP
pnpm run refresh               # regenerate every evidence page and figure from the captures

Good to know: the committed numbers are dated evidence from one machine, not universal claims. Rerun the relevant suite before publishing a current comparison.

Next steps

License and attribution

This repository is Apache-2.0; see LICENSE. Benchmark adapters incorporate upstream work under its own terms, recorded in rendering/UPSTREAM_LICENSES.md.

React, Marko, Vue, Svelte, Rails, jte, Rocker, Handlebars, Go, Jinja2, PHP, Askama, Sailfish, Leptos, Dioxus, and Topcoat belong to their respective owners. They appear here as the subjects of a benchmark; their inclusion implies no endorsement.