Benchmarking
SAPL Node includes two commands for measuring PDP performance: sapl benchmark for embedded evaluation throughput, and sapl loadtest for remote server load testing.
Embedded Benchmark
The benchmark command measures policy evaluation throughput and latency of an embedded PDP using a built-in timing harness. It runs entirely in-process without a server.
sapl benchmark --rbac -o ./results
The --rbac flag uses a built-in RBAC scenario that requires no policy files. Alternatively, point at your own policies:
sapl benchmark --dir ./policies -s '"alice"' -a '"read"' -r '"doc"' -o ./results
Options
| Option | Default | Description |
|---|---|---|
--rbac |
Use built-in RBAC benchmark (no files needed) | |
--dir, --bundle |
~/.sapl/ |
Policy source |
-s, -a, -r |
Subscription components (JSON values) | |
-b, --benchmark |
decideOnceBlocking |
Method: decideOnceBlocking, decideStreamFirst, noOp |
-t, --threads |
1 |
Concurrent benchmark threads |
--warmup-iterations |
3 |
Number of warmup iterations |
--warmup-time |
45 |
Seconds per warmup iteration |
--measurement-iterations |
5 |
Number of measurement iterations |
--measurement-time |
45 |
Seconds per measurement iteration |
--latency |
true |
Run a latency measurement pass after throughput |
-o, --output |
Output directory for Markdown, CSV, and JSON reports | |
--machine-readable |
false |
Output single-line parseable results for scripts |
For rigorous benchmarks with JIT isolation across forked JVMs, convergence checking, and advanced JVM tuning, use the
sapl-benchmark-sapl4module instead. The embeddedsapl benchmarkcommand is designed for quick assessments.
Remote Load Test
The loadtest command measures throughput and per-request latency of a running SAPL Node server. It supports both HTTP/JSON and RSocket/protobuf transports.
HTTP
sapl loadtest --url http://localhost:8443 -s '"alice"' -a '"read"' -r '"doc"'
RSocket
sapl loadtest --rsocket --host localhost --port 7000 -s '"alice"' -a '"read"' -r '"doc"'
Options
| Option | Default | Description |
|---|---|---|
--url |
http://localhost:8443 |
HTTP server URL |
--rsocket |
Use RSocket/protobuf transport instead of HTTP | |
--host |
localhost |
RSocket server host |
--port |
7000 |
RSocket server port |
--socket-path |
Unix domain socket path (alternative to host/port) | |
--concurrency |
64 |
Concurrent in-flight requests (HTTP) |
--connections |
8 |
Number of TCP connections (RSocket) |
--vt-per-connection |
512 |
Virtual threads per RSocket connection |
--rate |
0 |
Target req/s (0 = saturation mode) |
--warmup-seconds |
5 |
Warmup duration |
--measurement-seconds |
10 |
Measurement duration |
-o, --output |
Output directory for reports | |
--label |
Label for the report | |
--machine-readable |
false |
Output single-line parseable results for scripts |
Saturation vs Paced Mode
By default (--rate 0), the load generator sends requests as fast as possible (saturation mode) to find the server’s throughput ceiling. When --rate is set, it sends requests at a fixed rate with coordinated omission correction for accurate latency measurement under controlled load.
RSocket Connection Tuning
RSocket mode distributes load across multiple TCP connections. Each connection runs a configurable number of virtual threads. The total concurrency is --connections multiplied by --vt-per-connection. For example, 8 connections with 512 virtual threads each gives 4096 concurrent in-flight requests.
sapl loadtest --rsocket --connections 8 --vt-per-connection 512 -s '"alice"' -a '"read"' -r '"doc"'
For the full option reference, see the CLI Reference.