raptor 0.16.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 02fe742ea31e44d742de9f0ed5b94cc53901d39e25b054fe0bd4affd14e169c1
4
- data.tar.gz: 4279672bfd532f9bcadfb5ce81d85b8ba4921b8072e302bfc33bf74ce4609224
3
+ metadata.gz: 0e564259e8919bb36ded41097d9f3930fcf6ad2f2d090cd4bf0a2ef4cbf424b4
4
+ data.tar.gz: 1bf2f2e1077af1c2b61ba4b52bd5b13460bf0f27105a355b5dc01ff05e62b7b8
5
5
  SHA512:
6
- metadata.gz: 283c078528cfd9cdfdfb795e4587a60607fa382d09efe1194330d5a9a6c7f319af94bc63a2da62396c7aba8484a0041260fcd70b0d82a5c324c7fd6b9221abc5
7
- data.tar.gz: 9ee16f87805c340d17da270a81131f191b09500cbd622e3bd06bd32acff3f2ec215004e110187de1d01f6815fdcdfdf962c50c521398ce45e469358d3c155dd8
6
+ metadata.gz: 103f96d2f2490ea4bd1f844f29a8980deba5881e52b3c684ec2db963c0b0b0d426d616ce66ff22be93736550583891862502c1216663426249e015e1c68ab29d
7
+ data.tar.gz: e377a59417305334b255cf08be1c8c257971840d244b8b14b461ebbdfb857dc5a8cfbd6d37bee26ab2dc95642601bd1b7640100277c0b401f225fab66bbf8c77
data/CHANGELOG.md CHANGED
@@ -1,10 +1,14 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.16.1] - 2026-08-23
4
+
5
+ - Drop the stale `Ractors=NUM` option from the Rackup handler
6
+
3
7
  ## [0.16.0] - 2026-08-22
4
8
 
5
9
  - Parse HTTP/2 requests in a dedicated ractor pool
6
10
  - Parse the first HTTP/2 frame batch inline on accept
7
- - Nest the `ractors` config under `http1` and `http2`, defaulting both to `round(cores / workers)` clamped to 1..3 for HTTP/1.1 and 1..2 for HTTP/2
11
+ - Nest the `ractors` config under `http1` and `http2`
8
12
 
9
13
  ## [0.15.1] - 2026-08-16
10
14
 
data/Dockerfile CHANGED
@@ -18,8 +18,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
18
18
  && rm -rf /var/lib/apt/lists/*
19
19
 
20
20
  COPY --from=hey-builder /go/bin/hey /usr/local/bin/hey
21
- COPY --from=hey-builder /usr/local/go /usr/local/go
22
- ENV PATH=/usr/local/go/bin:${PATH}
23
21
 
24
22
  ENV BUNDLE_PATH=/workspace/.bundle
25
23
  ENV BUNDLE_APP_CONFIG=/workspace/.bundle
data/README.md CHANGED
@@ -37,7 +37,7 @@ run proc { |_env| [200, { "content-type" => "text/plain" }, ["Hello, World!"]] }
37
37
  ```
38
38
  > bundle exec raptor -w 10 -t 3 hello_world.ru
39
39
  [Raptor 83654|Main|Main] Cluster initializing:
40
- [Raptor 83654|Main|Main] ├─ Version: 0.16.0
40
+ [Raptor 83654|Main|Main] ├─ Version: 0.16.1
41
41
  [Raptor 83654|Main|Main] ├─ Ruby Version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
42
42
  [Raptor 83654|Main|Main] ├─ Environment: development
43
43
  [Raptor 83654|Main|Main] ├─ Master PID: 83654
@@ -201,28 +201,28 @@ Worker 1 (phase 0): pid=91351, requests=1199, busy=1/3, backlog=0, booted, last_
201
201
 
202
202
  ## (Micro) Benchmarks
203
203
 
204
- Raptor 0.16.0 vs Puma 8.0.2 vs PumaPlus 0.1.0 vs Falcon 0.57.0 across two workload profiles. **IO-bound** is a GET
205
- endpoint that interleaves 5-10 short sleeps (total 2.5-15ms) with small CPU work, simulating a read path that makes
206
- several DB or cache calls. **CPU-bound** is a POST endpoint that accepts a small JSON body, interleaves 3-5 chunks of
207
- JSON item building (total 450-1500 items) with sub-100µs sleeps, and returns the built array, simulating a write path
208
- that does most of its work in Ruby with a few near-zero-cost cache hits.
204
+ Raptor 0.16.1 vs Puma 8.0.2 vs Falcon 0.57.0 across two workload profiles. **IO-bound** is a GET endpoint that
205
+ interleaves 5-10 short sleeps (total 2.5-15ms) with small CPU work, simulating a read path that makes several DB or
206
+ cache calls. **CPU-bound** is a POST endpoint that accepts a small JSON body, interleaves 3-5 chunks of JSON item
207
+ building (total 450-1500 items) with sub-100µs sleeps, and returns the built array, simulating a write path that does
208
+ most of its work in Ruby with a few near-zero-cost cache hits.
209
209
 
210
210
  Each cell reports the median throughput and median p95 latency independently across 5 runs, so the two numbers in a row
211
211
  may come from different runs. Every run starts a fresh server process so the samples are independent of each other;
212
212
  state accumulated in a previous run cannot bias the next. Across the whole table, the widest spread
213
213
  ((max - min) / 2 / median) between runs of a single cell was ±24.8% for throughput and ±40.3% for p95.
214
214
 
215
- | Protocol | Workload | Raptor req/s | Raptor p95 | Puma req/s | Puma p95 | vs Puma req/s | vs Puma p95 | PumaPlus req/s | PumaPlus p95 | vs PumaPlus req/s | vs PumaPlus p95 | Falcon req/s | Falcon p95 | vs Falcon req/s | vs Falcon p95 |
216
- | --------------------- | -------- | ------------ | ---------- | ----------- | --------- | ------------- | ------------ | -------------- | ------------ | ----------------- | --------------- | ------------ | ---------- | --------------- | ------------- |
217
- | HTTP/1.1 | IO | 3.21k req/s | 63.20 ms | 1.48k req/s | 131.00 ms | 117.7% higher | 51.8% lower | 1.63k req/s | 84.20 ms | 97.0% higher | 24.9% lower | 12.27k req/s | 14.00 ms | 73.8% lower | 351.4% higher |
218
- | HTTP/1.1 | CPU | 8.29k req/s | 33.30 ms | 8.56k req/s | 21.20 ms | 3.2% lower | 57.1% higher | 8.08k req/s | 19.20 ms | 2.6% higher | 73.4% higher | 6.62k req/s | 27.00 ms | 25.2% higher | 23.3% higher |
219
- | HTTP/1.1 (keep-alive) | IO | 2.43k req/s | 54.40 ms | 1.44k req/s | 110.20 ms | 68.7% higher | 50.6% lower | 1.58k req/s | 87.10 ms | 54.2% higher | 37.5% lower | 6.28k req/s | 27.90 ms | 61.3% lower | 95.0% higher |
220
- | HTTP/1.1 (keep-alive) | CPU | 8.40k req/s | 18.80 ms | 8.49k req/s | 21.90 ms | 1.1% lower | 14.2% lower | 8.36k req/s | 18.40 ms | 0.4% higher | 2.2% higher | 7.09k req/s | 31.50 ms | 18.5% higher | 40.3% lower |
221
- | HTTP/2 | IO | 0.97k req/s | 197.97 ms | N/A | N/A | - | - | 1.52k req/s | 90.13 ms | 36.0% lower | 119.6% higher | 6.59k req/s | 27.21 ms | 85.2% lower | 627.6% higher |
222
- | HTTP/2 | CPU | 6.61k req/s | 31.98 ms | N/A | N/A | - | - | 8.05k req/s | 19.23 ms | 17.9% lower | 66.3% higher | 8.09k req/s | 45.04 ms | 18.3% lower | 29.0% lower |
215
+ | Protocol | Workload | Raptor req/s | Raptor p95 | Puma req/s | Puma p95 | vs Puma req/s | vs Puma p95 | Falcon req/s | Falcon p95 | vs Falcon req/s | vs Falcon p95 |
216
+ | --------------------- | -------- | ------------ | ---------- | ----------- | --------- | ------------- | ------------ | ------------ | ---------- | --------------- | ------------- |
217
+ | HTTP/1.1 | IO | 3.21k req/s | 63.20 ms | 1.48k req/s | 131.00 ms | 117.7% higher | 51.8% lower | 12.27k req/s | 14.00 ms | 73.8% lower | 351.4% higher |
218
+ | HTTP/1.1 | CPU | 8.29k req/s | 33.30 ms | 8.56k req/s | 21.20 ms | 3.2% lower | 57.1% higher | 6.62k req/s | 27.00 ms | 25.2% higher | 23.3% higher |
219
+ | HTTP/1.1 (keep-alive) | IO | 2.43k req/s | 54.40 ms | 1.44k req/s | 110.20 ms | 68.7% higher | 50.6% lower | 6.28k req/s | 27.90 ms | 61.3% lower | 95.0% higher |
220
+ | HTTP/1.1 (keep-alive) | CPU | 8.40k req/s | 18.80 ms | 8.49k req/s | 21.90 ms | 1.1% lower | 14.2% lower | 7.09k req/s | 31.50 ms | 18.5% higher | 40.3% lower |
221
+ | HTTP/2 | IO | 0.97k req/s | 197.97 ms | N/A | N/A | - | - | 6.59k req/s | 27.21 ms | 85.2% lower | 627.6% higher |
222
+ | HTTP/2 | CPU | 6.61k req/s | 31.98 ms | N/A | N/A | - | - | 8.09k req/s | 45.04 ms | 18.3% lower | 29.0% lower |
223
223
 
224
224
  > ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [aarch64-linux]
225
- > 10 worker processes; Raptor, Puma, and PumaPlus run 3 threads per worker, Falcon runs unbounded fibers per worker;
225
+ > 10 worker processes; Raptor and Puma run 3 threads per worker, Falcon runs unbounded fibers per worker;
226
226
  > 120 concurrent HTTP/1.1 client connections; 40 concurrent HTTP/2 client connections × 3 streams each
227
227
 
228
228
  See [bin/benchmark](bin/benchmark) for more details.
@@ -20,7 +20,7 @@ This document focuses on Puma because Puma is the incumbent that any new Ruby we
20
20
 
21
21
  Raptor is a research project. It hasn't run production traffic. The numbers in the README come from a repeatable microbenchmark, not from a real deployment. The benchmark measures only the **server** work: accepting connections, parsing, dispatching, and writing responses. It does not measure your application. In a typical Rails app where most of a request's time goes to ActiveRecord and downstream services, the server accounts for maybe 5 to 15 percent of the total, so a +N% number in this table will show up as a much smaller improvement in production. The gap is real, but it isn't what a Rails app against a real database will report.
22
22
 
23
- The Raptor README carries the [current head-to-head numbers](../README.md#micro-benchmarks) against the latest Puma and Falcon releases, run on the same hardware with the same Rack app on a recent Ruby with YJIT enabled. All servers run one worker process per available CPU; Raptor, Puma, and PumaPlus use three threads per worker, and Falcon uses unbounded fibers per worker. Load generators use four client connections per app thread, so on the 10-core machine that produced the current numbers that's 120 concurrent HTTP/1.1 client connections and 40 h2 connections × 3 streams each.
23
+ The Raptor README carries the [current head-to-head numbers](../README.md#micro-benchmarks) against the latest Puma and Falcon releases, run on the same hardware with the same Rack app on a recent Ruby with YJIT enabled. All servers run one worker process per available CPU; Raptor and Puma use three threads per worker, and Falcon uses unbounded fibers per worker. Load generators use four client connections per app thread, so on the 10-core machine that produced the current numbers that's 120 concurrent HTTP/1.1 client connections and 40 h2 connections × 3 streams each.
24
24
 
25
25
  Two workload profiles are measured. **IO-bound** is a GET endpoint that does 5 to 10 short sleeps interleaved with small CPU work per request, simulating a read path that makes several DB or cache calls throughout its lifetime. **CPU-bound** is a POST endpoint with a small JSON body that builds a JSON response in 3 to 5 chunks interleaved with sub-100µs sleeps, simulating a write path that does most of its work in Ruby with a few near-zero-cost cache hits. The workloads are interleaved rather than a single bulk sleep or single bulk serialise so a fiber-per-connection server like Falcon doesn't look artificially good from one-shot IO, and the CPU-bound workload is heavily CPU-dominated by design (roughly 95% CPU / 5% IO by wall time) so it actually measures CPU work rather than smuggling in enough IO for fibers to multiplex.
26
26
 
@@ -43,7 +43,6 @@ module Rackup
43
43
  "Host=HOST" => "Hostname to listen on (default: #{DEFAULT_OPTIONS[:Host]})",
44
44
  "Port=PORT" => "Port to listen on (default: #{DEFAULT_OPTIONS[:Port]})",
45
45
  "Workers=NUM" => "Number of worker processes (default: available processor count)",
46
- "Ractors=NUM" => "Number of pipeline ractors per worker (default: 1)",
47
46
  "Threads=NUM" => "Number of threads per worker (default: 3)",
48
47
  "Config=PATH" => "Load additional configuration from PATH"
49
48
  }
@@ -46,11 +46,11 @@ module Raptor
46
46
  # `[1, HTTP1_RACTOR_COUNT_CAP]`.
47
47
  #
48
48
  # @param worker_count [Integer] the configured worker count
49
+ # @param cores [Integer] the available processor count
49
50
  # @return [Integer]
50
51
  #
51
- # @rbs (Integer worker_count) -> Integer
52
- def self.default_http1_ractor_count(worker_count)
53
- cores = Integer(Concurrent.available_processor_count)
52
+ # @rbs (Integer worker_count, ?cores: Integer) -> Integer
53
+ def self.default_http1_ractor_count(worker_count, cores: Integer(Concurrent.available_processor_count))
54
54
  (cores.to_f / worker_count).round.clamp(1, HTTP1_RACTOR_COUNT_CAP)
55
55
  end
56
56
 
@@ -60,11 +60,11 @@ module Raptor
60
60
  # `[1, HTTP2_RACTOR_COUNT_CAP]`.
61
61
  #
62
62
  # @param worker_count [Integer] the configured worker count
63
+ # @param cores [Integer] the available processor count
63
64
  # @return [Integer]
64
65
  #
65
- # @rbs (Integer worker_count) -> Integer
66
- def self.default_http2_ractor_count(worker_count)
67
- cores = Integer(Concurrent.available_processor_count)
66
+ # @rbs (Integer worker_count, ?cores: Integer) -> Integer
67
+ def self.default_http2_ractor_count(worker_count, cores: Integer(Concurrent.available_processor_count))
68
68
  (cores.to_f / worker_count).round.clamp(1, HTTP2_RACTOR_COUNT_CAP)
69
69
  end
70
70
 
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Raptor
5
- VERSION = "0.16.0"
5
+ VERSION = "0.16.1"
6
6
  end
@@ -26,10 +26,11 @@ module Raptor
26
26
  # `[1, HTTP1_RACTOR_COUNT_CAP]`.
27
27
  #
28
28
  # @param worker_count [Integer] the configured worker count
29
+ # @param cores [Integer] the available processor count
29
30
  # @return [Integer]
30
31
  #
31
- # @rbs (Integer worker_count) -> Integer
32
- def self.default_http1_ractor_count: (Integer worker_count) -> Integer
32
+ # @rbs (Integer worker_count, ?cores: Integer) -> Integer
33
+ def self.default_http1_ractor_count: (Integer worker_count, ?cores: Integer) -> Integer
33
34
 
34
35
  # Returns the default number of HTTP/2 pipeline ractors per
35
36
  # worker for the given worker count, rounded from the available
@@ -37,10 +38,11 @@ module Raptor
37
38
  # `[1, HTTP2_RACTOR_COUNT_CAP]`.
38
39
  #
39
40
  # @param worker_count [Integer] the configured worker count
41
+ # @param cores [Integer] the available processor count
40
42
  # @return [Integer]
41
43
  #
42
- # @rbs (Integer worker_count) -> Integer
43
- def self.default_http2_ractor_count: (Integer worker_count) -> Integer
44
+ # @rbs (Integer worker_count, ?cores: Integer) -> Integer
45
+ def self.default_http2_ractor_count: (Integer worker_count, ?cores: Integer) -> Integer
44
46
 
45
47
  @server_port: Integer
46
48
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: raptor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0
4
+ version: 0.16.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Young