Skip to content

About

Comprehensive performance benchmarks comparing rari (Rust-powered RSC) vs Next.js across build times, rendering speed, TTFB, bundle size, and concurrent load handling.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Repository files navigation

rari

Runtime Accelerated Rendering Infrastructure

npm version License: MIT Discord

rari vs Next.js Benchmark Suite

This benchmark suite provides a comprehensive comparison between rari (Rust-powered React Server Components) and Next.js.

Benchmark Objectives

Performance Metrics

  • Server-side rendering speed - Time to render all components on server
  • Time to First Byte (TTFB) - Server response latency (P50, P95, P99)
  • Streaming delivery - Progressive Suspense chunks on /stream
  • Bundle size comparison - Client-side JavaScript payload
  • Build times - Production build speeds
  • Concurrent request handling - Throughput under load (requests/sec)
  • Memory usage - Runtime memory consumption under load

What's Being Tested

The benchmark suite tests:

  • Homepage (/) — 8 Server Components rendered statically (Counter, TestComponent, ShoppingList, WhatsHot, EnvTestComponent, FetchExample, ServerWithClient, Markdown)
  • Streaming (/stream) — 10 Suspense boundaries with clustered delays for progressive RSC delivery

Quick Start

Prerequisites

  • Node.js 22+
  • pnpm (install with corepack enable)
  • Rust and Cargo
  • just - Command runner (install with cargo install just)

Setup

# One-command setup (installs all dependencies and tools)
just setup

# Or complete initialization (setup + build + compile)
just init

Run Benchmarks

# Build both apps for production
just build

# Run complete benchmark suite
just benchmark-all

# Run specific benchmarks
just buildtest
just benchmark
just loadtest
just streamtest

# Quick tests with oha
just quick-test-rari
just quick-test-nextjs

Test Scenarios

1. Performance Benchmark

Tests server-side rendering performance with sequential requests:

  • Warmup phase - 50 requests to warm up the server
  • Test phase - 20 measured requests
  • Metrics collected - Min, max, avg, P50, P95, P99 response times, response size, error rate

2. Streaming Suspense Benchmark

Standalone test for progressive RSC streaming on /stream (inspired by rari-vs-nextjs):

  • Route - 10 <Suspense> boundaries with delays 100ms×5, 500ms×3, 1000ms×2
  • rari - loading.tsx enables streaming mode
  • Next.js - force-dynamic + Suspense
  • Per-chunk profile - TTFB, first resolved card, last byte, inter-chunk gaps, progressive resolved cards
  • Throughput - lighter load via oha (25 connections, 15s) because Suspense adds async backpressure
  • Primary metrics - TTFB, first content, and throughput (last-byte is dominated by the 1000ms cards)
  • Notes - Requests use Accept-Encoding: identity so compression doesn't merge flushes; "HTTP frames" are client-observed body frames, not React Suspense boundaries
# Full streaming benchmark (profile + throughput)
just streamtest

# Chunk timing only
just streamtest-profile

3. Load Test

Tests concurrent request handling using oha:

  • Duration - 30 seconds (configurable)
  • Concurrent connections - 50 (configurable)
  • Metrics collected - Throughput (req/sec), latency percentiles, error rates, timeouts

4. Build Time Test

Compares production build performance:

  • Build command - pnpm run build for both frameworks
  • Metrics collected - Build duration, bundle size, chunk count, warnings, errors

Metrics Collection

Performance Benchmark Metrics

  • Response times - Min, max, avg, P50, P95, P99 (in milliseconds)
  • Response size - Average payload size in bytes
  • Success rate - Percentage of successful requests
  • Error count - Number of failed requests

Streaming Benchmark Metrics

  • TTFB - Time to first byte / first chunk
  • First content - When the first resolved Suspense card marker (data-bench-stream="resolved") appears
  • Resolved cards - Count of resolved cards in the response (expected: 10)
  • Progressive resolved - Cards resolved by 500ms / 1s / 2s / 5s
  • Last byte - Time to complete the streamed response (delay-dominated)
  • HTTP frames - Client-observed body frames (not Suspense boundaries)
  • Inter-chunk gaps - mean / p50 / p95 / max between frames
  • Throughput - req/s under light concurrent load on /stream

Load Test Metrics

  • Throughput - Requests per second (avg, min, max)
  • Latency - Response time percentiles (P50, P90, P95, P99) in milliseconds
  • Errors - Failed requests and timeouts
  • Duration - Total test duration

Build Metrics

  • Build time - Total production build duration
  • Bundle size - Total size of client-side JavaScript and CSS
  • Chunk count - Number of generated files
  • Warnings/Errors - Build output analysis

Configuration

Both applications are configured to be as equivalent as possible:

Shared Features

  • App Router with file-based routing
  • Homepage route (/) with 8 server components
  • Streaming route (/stream) with identical Suspense trees
  • Server components by default
  • TypeScript throughout
  • Tailwind CSS for styling
  • Identical component implementations

rari App

  • Rust-powered React Server Components runtime
  • Vite-based build system
  • Production server on port 3000

Next.js App

  • Node.js-based React framework
  • Turbopack build system
  • Production server on port 3001

Actual Results

Based on the latest benchmark run (August 10, 2026) (rari v0.15.9):

Build Performance

Metric rari Next.js Improvement
Build Time 1.12s 3.88s 71.2% faster
Client Bundle 286.92 KB (6 files) 572.93 KB (8 files) 49.9% smaller

Performance Benchmark

Metric rari Next.js Improvement
Average Response Time 0.12ms 1.74ms 93.3% faster
P95 Latency 0.12ms 2.44ms 95.1% faster
Response Size 51,152 bytes 32,906 bytes 35.7% smaller

Load Test Performance (30s duration, 50 concurrent connections)

Metric rari Next.js Improvement
Throughput 89,371.33 req/sec 1,682.55 req/sec 5,211.7% higher
Average Latency 0.56ms 29.73ms 98.1% faster
P95 Latency 0.90ms 36.70ms 97.5% faster
Total Requests 2,681,727 50,482 5,211.7% more
Errors 0 0 100% success rate
Timeouts 0 0 100% success rate

Streaming Suspense (/stream)

Metric rari Next.js Ratio
TTFB 1ms 12ms 11.14x
First content 107ms 108ms 1.02x
Last byte 1007ms 1009ms 1.00x
Resolved cards 10 10 —
HTTP frames 12 10 —
Gap p95 500ms 500ms 1.00x
Resolved @500ms 5 5 —
Resolved @1000ms 8 8 —
Throughput (15s/25) 24.99 req/s 24.99 req/s 1.00x

Running Individual Tests

Starting Servers

# Start Rari production server (port 3000)
just start-rari

# Start Next.js production server (port 3001)
just start-nextjs

# Check if servers are running
just check-servers

Performance Testing

# Run performance benchmark (requires servers to be running)
just benchmark

Load Testing

# Run load test (requires servers to be running)
just loadtest

# Quick load tests with custom parameters
just quick-test-rari 30s 100
just quick-test-nextjs 30s 100

Streaming Testing

# Per-chunk profile + throughput on /stream
just streamtest

# Profile only (no oha)
just streamtest-profile

Build Time Testing

# Run build time comparison
just buildtest

Viewing Results

# View latest results
just results

# View specific result types
just results-build
just results-perf
just results-load
just results-stream

Development Commands

# Clean build artifacts
just clean

# Clean and rebuild
just rebuild

# Format, check, and lint
just fmt
just check
just lint

# Compile benchmark tools
just compile

Available Commands

Run just to see all available commands, or just --list for a detailed list.

Common Workflows

First-time setup:

just init

Running benchmarks:

# 1. Build the apps
just build

# 2. Start servers (in separate terminals)
just start-rari
just start-nextjs

# 3. Run benchmarks
just benchmark-all

Quick iteration:

just rebuild
just buildtest
just check-servers

Contributing

When adding new benchmark scenarios:

  1. Ensure parity - Both apps should have equivalent functionality
  2. Update both apps - Add components/routes to both rari and nextjs
  3. Update benchmark tools - Modify the Rust benchmark tools in tools/benchmark/src/
  4. Document changes - Update this README with new test scenarios
  5. Run all tests - Verify with just benchmark-all

License

MIT License - see LICENSE for details.

About

Comprehensive performance benchmarks comparing rari (Rust-powered RSC) vs Next.js across build times, rendering speed, TTFB, bundle size, and concurrent load handling.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages