Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
2f69dbc
Initial benchmark version
alexeyr Sep 22, 2025
77c2e96
Add production scripts
alexeyr Oct 2, 2025
0f8b7ab
Initial benchmark workflow
alexeyr Oct 3, 2025
b0920c5
Add server warm-up to benchmark
alexeyr Nov 5, 2025
aadb803
Make request timeout a parameter
alexeyr Nov 5, 2025
ee54b61
Update defaults for now
alexeyr Nov 5, 2025
a414491
Fix knip error
alexeyr Nov 5, 2025
3f17910
Enable clustered mode in production
alexeyr Nov 5, 2025
e72c1a2
Add MAX_CONNECTIONS
alexeyr Nov 5, 2025
a0a3cff
Fix max rate K6 scenario
alexeyr Nov 5, 2025
8858eba
Reorder workflow parameters more logically
alexeyr Nov 5, 2025
feafe65
Closer to recommended Fortio options
alexeyr Nov 5, 2025
b22a991
Allow configuring RAILS_MAX/MIN_THREADS in the workflow
alexeyr Nov 5, 2025
e667e99
Move showing benchmark params to bench.sh for simplicity
alexeyr Nov 5, 2025
ea47ebc
Convert the benchmark script to Ruby
alexeyr Nov 7, 2025
5dccbe7
Fix k6 timeout
alexeyr Nov 7, 2025
77e01ae
Replace DURATION_SEC with DURATION
alexeyr Nov 7, 2025
72c16cf
Group all code for a tool into a single block
alexeyr Nov 7, 2025
6446084
Remove duplication in adding summaries
alexeyr Nov 7, 2025
4f30545
Benchmark all routes
alexeyr Nov 8, 2025
dc2c0cd
Fix Fortio failure on server_side_log_throw_raise
alexeyr Nov 8, 2025
0fbb280
Allow specifying routes
alexeyr Nov 8, 2025
c208572
Add pro benchmarks
alexeyr Nov 8, 2025
561a4b5
Update Claude instructions
alexeyr Nov 8, 2025
2035dee
Update prod-assets to include generate_packs
alexeyr Nov 11, 2025
6c3c55b
Disable js_compressor and css_compressor
alexeyr Nov 11, 2025
f93b2f0
Handle empty inputs correctly
alexeyr Nov 11, 2025
da8d33a
Fix app version handling in the benchmark workflow
alexeyr Nov 11, 2025
19bfb9c
Fix starting/stopping servers
alexeyr Nov 11, 2025
696526c
Simplify validate steps
alexeyr Nov 12, 2025
c57688d
Temp config to speed up
alexeyr Nov 12, 2025
d1b4eb3
Optimize tools installation
alexeyr Nov 12, 2025
0748d81
Add logging to server check
alexeyr Nov 12, 2025
fe3de7c
Make installs frozen
alexeyr Nov 12, 2025
504f35c
Allow redirects in server_responding
alexeyr Nov 12, 2025
fb6d679
Try full Pro benchmark
alexeyr Nov 12, 2025
2c615bc
Update Core dummy path
alexeyr Dec 1, 2025
b7a43b4
Switch benchmark.yml to pnpm and new directory structure
alexeyr Dec 2, 2025
1f1dba5
generate_packs is now needed in core as well
alexeyr Dec 4, 2025
d0068c0
Improve route handling
alexeyr Dec 10, 2025
b7fd5cc
Fix killing the server
alexeyr Dec 10, 2025
1f7f1e9
Move stopping the servers after validating/uploading benchmark results
alexeyr Dec 10, 2025
3e0100d
Run benchmark workflow only on PRs with full-ci or benchmark labels
alexeyr Dec 10, 2025
3f4e859
Skip testing routes
alexeyr Dec 12, 2025
ba5e7ab
Add doc
alexeyr Dec 12, 2025
e0dc20b
Fix Vegeta tests
alexeyr Dec 12, 2025
0e9a4ad
Don't follow redirects
alexeyr Dec 12, 2025
ce6ded1
Move benchmark scripts to a non-gitignored directory
alexeyr Dec 12, 2025
2384be4
Separate k6 test file
alexeyr Dec 12, 2025
32f7861
Fix Yalc and pnpm handling in benchmark.yml
alexeyr Dec 12, 2025
9718f81
Fix assets:precompile in Pro dummy
alexeyr Dec 12, 2025
50d2278
Closer config for Core and Pro dummy apps
alexeyr Dec 12, 2025
4cf0c65
Remove SSH access
alexeyr Dec 14, 2025
bd0def8
Add Node renderer benchmarks
alexeyr Dec 13, 2025
b313f93
Use only k6 in Rails benchmarks
alexeyr Dec 13, 2025
2b7ca0c
Add max column
alexeyr Dec 14, 2025
85f9547
Add discardResponseBodies and specify types in the k6 file
alexeyr Dec 14, 2025
43569ad
Ignore vendor/bundle for Prettier
alexeyr Dec 15, 2025
738c7c1
Support both RSC and non-RSC benchmarks for Node renderer
alexeyr Dec 15, 2025
f8b8fc0
Allow running only Pro Rails or Pro Node Renderer benchmarks
alexeyr Dec 15, 2025
f0f2692
Add github-action-benchmark integration for benchmark tracking
alexeyr Dec 15, 2025
4bc64cd
Add changelog
alexeyr Dec 15, 2025
5775fae
Update docs
alexeyr Dec 15, 2025
448ce1c
Fix line endings
alexeyr Dec 15, 2025
3b6c790
Fix benchmark workflow non-fast-forward error
alexeyr Dec 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
540 changes: 540 additions & 0 deletions .github/workflows/benchmark.yml

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ react_on_rails/spec/dummy/**/*.res.js
react_on_rails_pro/spec/dummy/.bsb.lock
react_on_rails_pro/spec/dummy/**/*.res.js

# Performance test results
/bench_results

# Generated by ROR FS-based Registry
generated

Expand Down
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ react_on_rails/spec/dummy/public
**/.yalc/**
**/*generated*
*.res.js
**/vendor

# Prettier doesn't understand ERB syntax in YAML files and can damage templates
*.yml
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ After a release, run `/update-changelog` in Claude Code to analyze commits, writ

- **React Server Components Security Vulnerabilities (CVE-2025-55183, CVE-2025-55184, CVE-2025-67779)**: Upgraded React to v19.0.3 and react-on-rails-rsc to v19.0.4 to fix three critical security vulnerabilities in React Server Components. CVE-2025-55183 (CVSS 5.3) involved source code exposure when server function references were stringified, potentially leaking hardcoded secrets. CVE-2025-55184 and CVE-2025-67779 (both CVSS 7.5) involved denial of service attacks via cyclic promise references that could cause infinite loops and 100% CPU consumption. The fixes implement dual-layer cycle detection with a 1,000-iteration depth limit and override `toString()` methods on server references to return safe placeholders. Addresses [issue 2223](https://github.com/shakacode/react_on_rails/issues/2223). [PR 2233](https://github.com/shakacode/react_on_rails/pull/2233) by [AbanoubGhadban](https://github.com/AbanoubGhadban).

#### Developer (Contributors Only)

- **Benchmarking in CI**: A benchmark workflow will now run on all pushes to master, as well as PRs with `benchmark` or `full-ci` labels. [PR 1868](https://github.com/shakacode/react_on_rails/pull/1868) by [alexeyr-ci2](https://github.com/alexeyr-ci2)

### [16.2.0.beta.20] - 2025-12-12

#### Fixed
Expand Down
2 changes: 2 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ Pre-commit hooks automatically run:
- All linters: `rake lint` (runs ESLint and RuboCop)
- ESLint only: `pnpm run lint` or `rake lint:eslint`
- RuboCop only: `rake lint:rubocop`
- GitHub Action files (workflows, reusable actions, etc.): `actionlint`
- YAML files: `yamllint` (or validate the syntax with Ruby if it isn't installed). Do _not_ try to run RuboCop on `.yml` files.
- **Code Formatting**:
- Format code with Prettier: `rake autofix`
- Check formatting without fixing: `pnpm run format.listDifferent`
Expand Down
69 changes: 69 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,75 @@ Removes the `full-ci` label and returns to standard CI behavior:
- **Force-pushes:** The `/run-skipped-ci` command adds the `full-ci` label to your PR. If you force-push after commenting, the initial workflow run will test the old commit, but subsequent pushes will automatically run full CI because the label persists.
- **Branch operations:** Avoid deleting or force-pushing branches while workflows are running, as this may cause failures.

### Benchmarking

React on Rails includes a performance benchmark workflow that measures RPS (requests per second) and latency for both Core and Pro versions.

#### When Benchmarks Run

- **Automatically on master**: Benchmarks run on every push to master
- **On PRs with labels**: Add the `benchmark` or `full-ci` label to your PR to run benchmarks
- **Manual trigger**: Use `gh workflow run` to run benchmarks with custom parameters (see [https://github.com/cli/cli#installation](https://github.com/cli/cli#installation) if you don't have `gh`):

```bash
# Run with default parameters
gh workflow run benchmark.yml

# Run with custom parameters
gh workflow run benchmark.yml \
-f rate=100 \
-f duration=60s \
-f connections=20 \
-f app_version=core_only
```

#### Regression Detection

When benchmarks run, the [github-action-benchmark](https://github.com/benchmark-action/github-action-benchmark) action compares results against historical data. If performance regresses by more than 50%, the workflow will:

1. **Fail the CI check** with `fail-on-alert: true`
2. **Post a comment on the PR** explaining the regression
3. **Tag reviewers** for attention

This helps catch performance regressions before they reach production.

#### Running Benchmarks Locally

**Prerequisites:** Install [k6](https://k6.io/docs/get-started/installation/) and [Vegeta](https://github.com/tsenart/vegeta#install).

You can also run the server in a separate terminal instead of backgrounding it.

**Core benchmarks:**

```bash
cd react_on_rails/spec/dummy
bin/prod-assets # Build production assets
bin/prod & # Start production server on port 3001
SERVER_PID=$!
cd ../..
ruby benchmarks/bench.rb
kill $SERVER_PID
```

**Pro benchmarks:**

```bash
cd react_on_rails_pro/spec/dummy
bin/prod-assets
bin/prod & # Starts Rails server and node renderer
SERVER_PID=$!
cd ../..
PRO=true ruby benchmarks/bench.rb # Rails benchmarks
ruby benchmarks/bench-node-renderer.rb # Node renderer benchmarks
kill $SERVER_PID
```

**Configuration:** Both scripts support environment variables for customization (rate, duration, connections, etc.). See the script headers in [`benchmarks/bench.rb`](benchmarks/bench.rb) and [`benchmarks/bench-node-renderer.rb`](benchmarks/bench-node-renderer.rb) for available options. For debugging, you may want lower `DURATION` and/or specific `ROUTES`:

```bash
DURATION=5s ROUTES=/ ruby benchmarks/bench.rb
```

### Install Generator

In your Rails app add this gem with a path to your fork.
Expand Down
Loading
Loading