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 +4 -4
- data/CHANGELOG.md +5 -1
- data/Dockerfile +0 -2
- data/README.md +15 -15
- data/docs/raptor-vs-puma.md +1 -1
- data/lib/rackup/handler/raptor.rb +0 -1
- data/lib/raptor/cluster.rb +6 -6
- data/lib/raptor/version.rb +1 -1
- data/sig/generated/raptor/cluster.rbs +6 -4
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0e564259e8919bb36ded41097d9f3930fcf6ad2f2d090cd4bf0a2ef4cbf424b4
|
|
4
|
+
data.tar.gz: 1bf2f2e1077af1c2b61ba4b52bd5b13460bf0f27105a355b5dc01ff05e62b7b8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
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.
|
|
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.
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
221
|
-
| HTTP/2 | IO | 0.97k req/s | 197.97 ms | N/A | N/A | - | - |
|
|
222
|
-
| HTTP/2 | CPU | 6.61k req/s | 31.98 ms | N/A | N/A | - | - | 8.
|
|
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
|
|
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.
|
data/docs/raptor-vs-puma.md
CHANGED
|
@@ -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
|
|
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
|
}
|
data/lib/raptor/cluster.rb
CHANGED
|
@@ -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
|
|
data/lib/raptor/version.rb
CHANGED
|
@@ -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
|
|