Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
703e9bb
Initial benchmark version
alexeyr Sep 22, 2025
8fcc3b9
Add production scripts
alexeyr Oct 2, 2025
5517d60
Initial benchmark workflow
alexeyr Oct 3, 2025
7597765
Add server warm-up to benchmark
alexeyr Nov 5, 2025
ee2ddef
Make request timeout a parameter
alexeyr Nov 5, 2025
cec1e64
Update defaults for now
alexeyr Nov 5, 2025
75d460e
Fix knip error
alexeyr Nov 5, 2025
04717a0
Enable clustered mode in production
alexeyr Nov 5, 2025
7f0f606
Add MAX_CONNECTIONS
alexeyr Nov 5, 2025
653f934
Fix max rate K6 scenario
alexeyr Nov 5, 2025
969c9c3
Reorder workflow parameters more logically
alexeyr Nov 5, 2025
ddd6596
Closer to recommended Fortio options
alexeyr Nov 5, 2025
15d3cc6
Allow configuring RAILS_MAX/MIN_THREADS in the workflow
alexeyr Nov 5, 2025
6085161
Move showing benchmark params to bench.sh for simplicity
alexeyr Nov 5, 2025
933c08d
Convert the benchmark script to Ruby
alexeyr Nov 7, 2025
712a429
Fix k6 timeout
alexeyr Nov 7, 2025
778dc53
Replace DURATION_SEC with DURATION
alexeyr Nov 7, 2025
2b46dc0
Group all code for a tool into a single block
alexeyr Nov 7, 2025
00034cc
Remove duplication in adding summaries
alexeyr Nov 7, 2025
fc0a4c1
Benchmark all routes
alexeyr Nov 8, 2025
2540ae7
Fix Fortio failure on server_side_log_throw_raise
alexeyr Nov 8, 2025
bc1a470
Allow specifying routes
alexeyr Nov 8, 2025
a98be1e
Add pro benchmarks
alexeyr Nov 8, 2025
9918783
Update Claude instructions
alexeyr Nov 8, 2025
9187f68
FIXME temp commit
alexeyr Nov 11, 2025
f5995d4
Update prod-assets to include generate_packs
alexeyr Nov 11, 2025
70f620b
Disable js_compressor and css_compressor
alexeyr Nov 11, 2025
0d8f5e1
Remove unused pg gem
alexeyr Nov 11, 2025
d2ea3f3
Handle empty inputs correctly
alexeyr Nov 11, 2025
ceded4d
Fix app version handling in the benchmark workflow
alexeyr Nov 11, 2025
5c58195
Fix starting/stopping servers
alexeyr Nov 11, 2025
7c9bd84
Simplify validate steps
alexeyr Nov 12, 2025
6b43ed9
Temp config to speed up
alexeyr Nov 12, 2025
aacec1f
Optimize tools installation
alexeyr Nov 12, 2025
4c9b5ac
Add logging to server check
alexeyr Nov 12, 2025
2a30d27
Make installs frozen
alexeyr Nov 12, 2025
1d2cec0
Allow redirects in server_responding
alexeyr Nov 12, 2025
fe84f1e
Try full Pro benchmark
alexeyr Nov 12, 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
503 changes: 503 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 @@ -67,6 +67,9 @@ yalc.lock
/spec/dummy/.bsb.lock
/spec/dummy/**/*.res.js

# Performance test results
/bench_results

# Generated by ROR FS-based Registry
generated

Expand Down
2 changes: 2 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ Pre-commit hooks automatically run:
- All linters: `rake lint` (runs ESLint and RuboCop)
- ESLint only: `yarn 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: `yarn start format.listDifferent`
Expand Down
3 changes: 3 additions & 0 deletions knip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ const config: KnipConfig = {
ignoreBinaries: [
// Has to be installed globally
'yalc',
'ruby',
// Used in package.json scripts (devDependency, so unlisted in production mode)
'nps',
// Pro package binaries used in Pro workflows
'playwright',
'e2e-test',
// Local binaries
'bin/.*',
],
ignore: ['react_on_rails_pro/**'],
ignoreDependencies: [
Expand Down
3 changes: 0 additions & 3 deletions react_on_rails_pro/Gemfile.development_dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,9 @@ gem "puma", "~> 6"
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem "jbuilder"

gem "pg"

# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem "turbolinks"
gem "sqlite3", "~> 1.4"
gem "uglifier"
gem "jquery-rails"
gem "sprockets"
gem "sass-rails"
Expand Down
5 changes: 0 additions & 5 deletions react_on_rails_pro/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ GEM
parser (3.3.3.0)
ast (~> 2.4.1)
racc
pg (1.5.6)
pp (0.6.2)
prettyprint
prettyprint (0.2.0)
Expand Down Expand Up @@ -414,8 +413,6 @@ GEM
turbolinks-source (5.2.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
unicode-display_width (2.5.0)
uri (1.0.3)
useragent (0.16.11)
Expand Down Expand Up @@ -468,7 +465,6 @@ DEPENDENCIES
net-http
net-imap
net-smtp
pg
pry (>= 0.14.1)
pry-byebug!
pry-doc
Expand All @@ -493,7 +489,6 @@ DEPENDENCIES
sprockets
sqlite3 (~> 1.4)
turbolinks
uglifier
web-console
webdrivers (= 5.3.0)
webmock
Expand Down
5 changes: 0 additions & 5 deletions react_on_rails_pro/spec/dummy/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,6 @@ GEM
parser (3.3.3.0)
ast (~> 2.4.1)
racc
pg (1.5.6)
pp (0.6.2)
prettyprint
prettyprint (0.2.0)
Expand Down Expand Up @@ -450,8 +449,6 @@ GEM
turbolinks-source (5.2.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
unicode-display_width (2.5.0)
uri (1.0.3)
useragent (0.16.11)
Expand Down Expand Up @@ -515,7 +512,6 @@ DEPENDENCIES
net-http
net-imap
net-smtp
pg
prism-rails
pry (>= 0.14.1)
pry-byebug!
Expand All @@ -542,7 +538,6 @@ DEPENDENCIES
sprockets
sqlite3 (~> 1.4)
turbolinks
uglifier
web-console
webdrivers (= 5.3.0)
webmock
Expand Down
29 changes: 29 additions & 0 deletions react_on_rails_pro/spec/dummy/bin/prod
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env bash

# Run only after ./prod-assets

# Check if assets are precompiled
MANIFEST="public/webpack/production/manifest.json"

if [ ! -d "public/assets" ]; then
echo "ERROR: public/assets not found. Run ./bin/prod-assets first"
exit 1
fi

if [ ! -f "$MANIFEST" ]; then
echo "ERROR: $MANIFEST not found. Run ./bin/prod-assets first"
exit 1
fi

# Simple up-to-date check: warn if source files are newer than manifest.json
if find client config -type f \( -name "*.[jt]s" -o -name "*.[jt]sx" \) -newer "$MANIFEST" 2>/dev/null | grep -q .; then
echo "WARNING: client or config has changes newer than compiled assets"
echo "Consider running ./bin/prod-assets to rebuild"
fi

if [ -f "yarn.lock" ] && [ "yarn.lock" -nt "$MANIFEST" ]; then
echo "WARNING: yarn.lock is newer than compiled assets"
echo "Consider running ./bin/prod-assets to rebuild"
fi

NODE_ENV=production RAILS_ENV=production bundle exec rails server -p 3001
9 changes: 9 additions & 0 deletions react_on_rails_pro/spec/dummy/bin/prod-assets
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

export NODE_ENV=production
export RAILS_ENV=production
if [ "$CI" = "true" ]; then
bundle exec bootsnap precompile --gemfile app/ lib/ config/
fi
bundle exec rails react_on_rails:generate_packs
bundle exec rails assets:precompile
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
config.public_file_server.enabled = true

# Compress JavaScripts and CSS.
config.assets.js_compressor = Uglifier.new(harmony: true)
config.assets.css_compressor = :csso
# JS/CSS compression handled by Webpack/Shakapacker, not needed for Sprockets
# config.assets.js_compressor = Uglifier.new(harmony: true)
# config.assets.css_compressor = :csso

# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = false
Expand Down Expand Up @@ -69,7 +70,7 @@
config.active_support.deprecation = :notify

# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new
config.log_formatter = Logger::Formatter.new

# Use a different logger for distributed setups.
# require 'syslog/logger'
Expand Down
3 changes: 3 additions & 0 deletions spec/dummy/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ GEM
nokogiri (1.18.10)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
nokogiri (1.18.10-x86_64-linux-gnu)
racc (~> 1.4)
ostruct (0.6.3)
package_json (0.1.0)
parallel (1.24.0)
Expand Down Expand Up @@ -408,6 +410,7 @@ GEM

PLATFORMS
ruby
x86_64-linux

DEPENDENCIES
amazing_print
Expand Down
29 changes: 29 additions & 0 deletions spec/dummy/bin/prod
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env bash

# Run only after ./prod-assets

# Check if assets are precompiled
MANIFEST="public/webpack/production/manifest.json"

if [ ! -d "public/assets" ]; then
echo "ERROR: public/assets not found. Run ./bin/prod-assets first"
exit 1
fi

if [ ! -f "$MANIFEST" ]; then
echo "ERROR: $MANIFEST not found. Run ./bin/prod-assets first"
exit 1
fi

# Simple up-to-date check: warn if source files are newer than manifest.json
if find client config -type f \( -name "*.[jt]s" -o -name "*.[jt]sx" \) -newer "$MANIFEST" 2>/dev/null | grep -q .; then
echo "WARNING: client or config has changes newer than compiled assets"
echo "Consider running ./bin/prod-assets to rebuild"
fi

if [ -f "yarn.lock" ] && [ "yarn.lock" -nt "$MANIFEST" ]; then
echo "WARNING: yarn.lock is newer than compiled assets"
echo "Consider running ./bin/prod-assets to rebuild"
fi

NODE_ENV=production RAILS_ENV=production bundle exec rails server -p 3001
9 changes: 9 additions & 0 deletions spec/dummy/bin/prod-assets
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

export NODE_ENV=production
export RAILS_ENV=production
if [ "$CI" = "true" ]; then
bundle exec bootsnap precompile --gemfile app/ lib/ config/
fi
yarn run build:rescript
bundle exec rails assets:precompile
41 changes: 25 additions & 16 deletions spec/dummy/config/puma.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,45 @@
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count

rails_env = ENV.fetch("RAILS_ENV", "development")

# Specifies the `worker_timeout` threshold that Puma will use to wait before
# terminating a worker in development environments.
#
worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"
worker_timeout 3600 if rails_env == "development"

# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
#
port ENV.fetch("PORT", 3000)

# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch("RAILS_ENV", "development")
environment rails_env

# Specifies the `pidfile` that Puma will use.
pidfile ENV.fetch("PIDFILE", "tmp/pids/server.pid")

# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked web server processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
#
# workers ENV.fetch("WEB_CONCURRENCY") { 2 }

# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory.
#
# preload_app!
if rails_env == "production"
# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked web server processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
#
workers ENV.fetch("WEB_CONCURRENCY", 2)

# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory.
#
preload_app!

# Specifies the `worker_shutdown_timeout` threshold that Puma will use to wait before
# terminating a worker.
#
worker_shutdown_timeout 60
end

# Allow puma to be restarted by `bin/rails restart` command.
plugin :tmp_restart
Loading
Loading