Compare commits
8
Commits
842fca2b72
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f25b460d3c | ||
|
|
943080805c | ||
|
|
926aba4344 | ||
|
|
5f342858e7 | ||
|
|
56e490c205 | ||
|
|
44ee8dcf4e | ||
|
|
d1207f0d2f | ||
|
|
730de334e0 |
@@ -0,0 +1,5 @@
|
|||||||
|
target
|
||||||
|
Cargo.lock
|
||||||
|
smarm_trace.json
|
||||||
|
.direnv/
|
||||||
|
.envrc
|
||||||
Generated
+2293
File diff suppressed because it is too large
Load Diff
+11
@@ -0,0 +1,11 @@
|
|||||||
|
[workspace]
|
||||||
|
resolver = "2"
|
||||||
|
members = [
|
||||||
|
"urus-server",
|
||||||
|
"axum-server",
|
||||||
|
]
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
lto = "thin"
|
||||||
|
codegen-units = 1
|
||||||
|
panic = "unwind"
|
||||||
@@ -1,2 +1,269 @@
|
|||||||
# urus-benches
|
# urus-bench
|
||||||
|
|
||||||
|
HTTP/1.1 performance benchmarks comparing **Urus** (actor-based Rust web framework) against **Axum** (async/await Rust via hyper). Designed to test the Urus spec claim: "**within 2× of Axum RPS**."
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This benchmark suite measures throughput (RPS) and tail latency (p99) across four scenarios of increasing complexity:
|
||||||
|
|
||||||
|
| Scenario | Workload | Framework Test |
|
||||||
|
|----------|----------|---|
|
||||||
|
| **S1** | Bare HTTP (`GET /ping`) | Protocol + connection handling |
|
||||||
|
| **S2** | Routing + middleware | Logger, request ID, auth, router |
|
||||||
|
| **S3** | In-memory store (mixed) | Message-passing vs. mutex contention |
|
||||||
|
| **S4** | SQLite (mixed) | Database overhead under actor model |
|
||||||
|
|
||||||
|
Full specification: see [`urus-bench-spec.md`](./urus-bench-spec.md).
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Rust 1.70+ (stable)
|
||||||
|
- `wrk` and `wrk2` (load generators)
|
||||||
|
- `pidstat`, `taskset` (process introspection & CPU pinning)
|
||||||
|
- `curl` (sanity checks before benchmarks)
|
||||||
|
|
||||||
|
**Recommended**: Use the provided `nix-shell`:
|
||||||
|
```bash
|
||||||
|
nix-shell
|
||||||
|
```
|
||||||
|
|
||||||
|
This installs all dependencies except Rust (assumed already on your host).
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo build --release
|
||||||
|
```
|
||||||
|
|
||||||
|
Both `urus-server` and `axum-server` will be built. Runs take ~5–10 minutes total (30s warmup + 60s measure per scenario).
|
||||||
|
|
||||||
|
### Run a Single Benchmark
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./runner.sh urus-mem s1
|
||||||
|
```
|
||||||
|
|
||||||
|
This runs Urus on scenario S1, pins the server to cores 0–7, the load generator to cores 8–15, and saves results to `results/<batch>/<server>-<scenario>/`.
|
||||||
|
|
||||||
|
### Run the Full Matrix
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./run_all.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Runs 8 benchmarks (Urus + Axum on S1–S3, both on SQLite S4). Outputs a summary table and machine-readable JSON index.
|
||||||
|
|
||||||
|
### Quick Mode (for development)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./run_all.sh --quick
|
||||||
|
```
|
||||||
|
|
||||||
|
Uses 15s warmup + 15s measure (instead of 30+60) for faster iteration.
|
||||||
|
|
||||||
|
## Repository Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
urus-bench/
|
||||||
|
├── urus-server/ # Urus implementation (actor-based)
|
||||||
|
│ ├── src/
|
||||||
|
│ │ ├── main.rs
|
||||||
|
│ │ ├── handlers.rs
|
||||||
|
│ │ ├── middleware.rs
|
||||||
|
│ │ └── store.rs # In-memory and SQLite store actors
|
||||||
|
│ └── Cargo.toml
|
||||||
|
├── axum-server/ # Axum implementation (async/await + hyper)
|
||||||
|
│ ├── src/
|
||||||
|
│ │ └── main.rs
|
||||||
|
│ └── Cargo.toml
|
||||||
|
├── loadgen/ # wrk2 scripts
|
||||||
|
│ ├── common.lua # shared headers, bearer token
|
||||||
|
│ ├── s1_ping.lua # simple GET
|
||||||
|
│ ├── s2_user_get.lua # router + middleware
|
||||||
|
│ └── s3_mixed.lua # 80% GET, 15% list, 5% POST
|
||||||
|
├── runner.sh # Single-run orchestrator
|
||||||
|
├── run_all.sh # Full-matrix orchestrator
|
||||||
|
├── urus-bench-spec.md # Detailed specification
|
||||||
|
├── shell.nix # Nix environment
|
||||||
|
├── Cargo.toml # Workspace definition
|
||||||
|
└── results/ # Output (created at runtime)
|
||||||
|
└── <batch>/
|
||||||
|
├── summary.md # Headline results
|
||||||
|
├── index.json # Machine-readable results
|
||||||
|
└── <server>-<scenario>/
|
||||||
|
├── result.json # Metrics: RPS, latencies, CPU, RSS
|
||||||
|
└── histogram.txt # HDR histogram (wrk2 raw output)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Key Scripts
|
||||||
|
|
||||||
|
### `runner.sh`
|
||||||
|
|
||||||
|
Runs a single (server, scenario) pair. Usage:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./runner.sh [--help] <server> <scenario> [options]
|
||||||
|
|
||||||
|
# Examples:
|
||||||
|
./runner.sh urus-mem s1 # Urus on S1 (defaults)
|
||||||
|
./runner.sh axum-sqlite s4 # Axum on S4
|
||||||
|
./runner.sh urus-mem s3 --quick # Urus on S3, short timings
|
||||||
|
./runner.sh axum-mem s2 --measure-sec=120 # Extended measurement
|
||||||
|
```
|
||||||
|
|
||||||
|
**Server names:**
|
||||||
|
- `urus-mem`, `axum-mem` (in-memory store)
|
||||||
|
- `urus-sqlite`, `axum-sqlite` (SQLite store)
|
||||||
|
|
||||||
|
**Scenario names:**
|
||||||
|
- `s1`, `s2`, `s3`, `s4` (see Specification, below)
|
||||||
|
|
||||||
|
**Key options:**
|
||||||
|
- `--quick`: Use 15s warmup + 15s measure (fast iteration)
|
||||||
|
- `--measure-sec=N`: Set measurement duration
|
||||||
|
- `--warmup-sec=N`: Set warmup duration
|
||||||
|
- `--wrk-conns=N`: Number of connections (default 256)
|
||||||
|
- `--wrk-threads=N`: Load generator threads (default 8)
|
||||||
|
- `--batch=ID`: Tag for results directory (default: timestamp)
|
||||||
|
|
||||||
|
Output: `results/<batch>/<server>-<scenario>/result.json` + `histogram.txt`.
|
||||||
|
|
||||||
|
### `run_all.sh`
|
||||||
|
|
||||||
|
Runs the full benchmark matrix. Usage:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./run_all.sh [options]
|
||||||
|
|
||||||
|
# Examples:
|
||||||
|
./run_all.sh # Full 8-run matrix
|
||||||
|
./run_all.sh --quick # Full matrix, 15s+15s timings
|
||||||
|
./run_all.sh --scenarios=s1,s2 # Only S1 and S2
|
||||||
|
./run_all.sh --servers=urus-mem,axum-mem # Only in-memory
|
||||||
|
```
|
||||||
|
|
||||||
|
**Output:**
|
||||||
|
- `results/<batch>/summary.md` — headline table (text)
|
||||||
|
- `results/<batch>/index.json` — structured results (machine-readable)
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Environment variables (passed through to `runner.sh`):
|
||||||
|
|
||||||
|
| Variable | Default | Purpose |
|
||||||
|
|----------|---------|---------|
|
||||||
|
| `WARMUP_SEC` | 30 | Warm-up duration (TCP window scaling, JIT) |
|
||||||
|
| `MEASURE_SEC` | 60 | Measurement duration (where latencies are sampled) |
|
||||||
|
| `PROBE_SEC` | 30 | Saturation probe duration (closed-loop `wrk`) |
|
||||||
|
| `SERVER_CPUS` | 0-7 | CPU cores pinned to server process |
|
||||||
|
| `LOADGEN_CPUS` | 8-15 | CPU cores pinned to load generator |
|
||||||
|
| `WRK_CONNS` | 256 | Concurrent connections |
|
||||||
|
| `WRK_THREADS` | 8 | Load generator thread count |
|
||||||
|
| `SAT_RATIO` | 0.7 | Target RPS = saturation × this ratio |
|
||||||
|
| `BEARER` | (required) | Authorization token for auth middleware |
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```bash
|
||||||
|
MEASURE_SEC=120 WARMUP_SEC=60 ./runner.sh urus-mem s3
|
||||||
|
```
|
||||||
|
|
||||||
|
## Interpreting Results
|
||||||
|
|
||||||
|
### Metrics
|
||||||
|
|
||||||
|
Each run produces `result.json` with:
|
||||||
|
|
||||||
|
- **`sustained_rps`** — requests/second at the target rate (wrk2 measurement)
|
||||||
|
- **`p99_latency_ms`** — 99th percentile latency (HDR histogram)
|
||||||
|
- **`server_cpu_pct`** — average CPU utilization (pidstat)
|
||||||
|
- **`server_rss_mb`** — peak resident set size
|
||||||
|
- **`handler_p99_us`** — server-side handler latency (p99, microseconds)
|
||||||
|
|
||||||
|
### Reading the Output
|
||||||
|
|
||||||
|
```
|
||||||
|
========== [1/8] urus-mem s1 ==========
|
||||||
|
sustained=54640.68 rps p99=2.70ms
|
||||||
|
```
|
||||||
|
|
||||||
|
This is Urus on S1: **54,640 RPS at sustained load, with p99 latency of 2.70ms.**
|
||||||
|
|
||||||
|
### Comparing Frameworks
|
||||||
|
|
||||||
|
The spec target is **Urus RPS ≥ 50% of Axum RPS** on S1 and S2. Example:
|
||||||
|
|
||||||
|
- Urus S1: 54,640 RPS
|
||||||
|
- Axum S1: 288,330 RPS
|
||||||
|
- Ratio: 0.19 (54,640 / 288,330) → **FAIL** (need ≥ 0.50)
|
||||||
|
|
||||||
|
## Development & Debugging
|
||||||
|
|
||||||
|
### Running a Single Server in Isolation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run --release --bin urus-server -- --store=memory
|
||||||
|
# Server listens on 127.0.0.1:8080
|
||||||
|
curl -H "Authorization: Bearer test-token-aaaaaaaaaaaaaaaaaaaa" \
|
||||||
|
http://127.0.0.1:8080/ping
|
||||||
|
# Response: 200 OK, body "pong"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Inspecting SQLite Between Runs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sqlite3 urus.db "SELECT COUNT(*) FROM users;"
|
||||||
|
```
|
||||||
|
|
||||||
|
SQLite databases are created in the working directory as `urus.db` (Urus) and `axum.db` (Axum).
|
||||||
|
|
||||||
|
### Profiling a Run
|
||||||
|
|
||||||
|
Modify `runner.sh` to include `perf record`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
perf record -g -F 99 -p $pid -- ... # during the measurement phase
|
||||||
|
perf report
|
||||||
|
```
|
||||||
|
|
||||||
|
### Viewing Raw Histograms
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat results/<batch>/<server>-<scenario>/histogram.txt
|
||||||
|
# HDR histogram format (wrk2 output)
|
||||||
|
```
|
||||||
|
|
||||||
|
Convert to a plot with `hdr-plot` (wrk2 companion tool) or similar.
|
||||||
|
|
||||||
|
## Known Limitations
|
||||||
|
|
||||||
|
- **No TLS**: HTTP/1.1 plaintext only. TLS would require additional tooling per framework.
|
||||||
|
- **Loopback only**: All networking is on 127.0.0.1 (generous environment). Real-world RTT / packet loss not tested.
|
||||||
|
- **No pipelining**: HTTP/1.1 pipelining not exercised.
|
||||||
|
- **No Cowboy**: BEAM reference removed; focus is Urus vs. Axum.
|
||||||
|
|
||||||
|
## Results from 2026-05-26
|
||||||
|
|
||||||
|
Summary from the last full run (batch `20260526-220625`):
|
||||||
|
|
||||||
|
| | Urus | Axum | Ratio |
|
||||||
|
|---|------|------|-------|
|
||||||
|
| **S1 RPS** | 54,640 | 288,330 | 0.19 (5.3×) |
|
||||||
|
| **S2 RPS** | 53,139 | 315,596 | 0.17 (5.9×) |
|
||||||
|
| **S3 RPS** | 53,616 | 316,342 | 0.17 (5.9×) |
|
||||||
|
| **S4 RPS** | 52,590 | 320,150 | 0.16 (6.1×) |
|
||||||
|
|
||||||
|
**Verdict:** Urus fails the "within 2×" spec target on throughput. Tail latency (p99) remains sub-3ms under all loads; Axum's p99 scales with concurrency (11–60ms). See [`benchmark-report.html`](./benchmark-report.html) for full analysis.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- **Specification**: [`urus-bench-spec.md`](./urus-bench-spec.md) — design principles, scenarios, pass/fail criteria
|
||||||
|
- **Latest Report**: `benchmark-report.html` — 2026-05-26 results & interpretation
|
||||||
|
- **Urus**: [smarm/urus](https://github.com/smarm/urus)
|
||||||
|
- **Axum**: [tokio-rs/axum](https://github.com/tokio-rs/axum)
|
||||||
|
- **wrk2**: [giltene/wrk2](https://github.com/giltene/wrk2) — constant-rate load generator
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Benchmark code is in the public domain or under your preferred permissive license (MIT/Apache-2.0). See individual crate licenses for dependencies.
|
||||||
|
|||||||
Executable
+147
@@ -0,0 +1,147 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Pair before/after urus-bench results and print an A/B comparison.
|
||||||
|
|
||||||
|
Layout produced by spin_ab_urus.sh:
|
||||||
|
|
||||||
|
<outdir>/before/<server>-<scenario>-c<cores>/result.json
|
||||||
|
<outdir>/after/<server>-<scenario>-c<cores>/result.json
|
||||||
|
|
||||||
|
We pair by the (server, scenario, cores) key and report sustained RPS
|
||||||
|
(after/before speedup) and p50/p99/p99.9 latency deltas. The spin gate is
|
||||||
|
active only at 2-4 schedulers, so rows at cores 2 and 4 are where an effect is
|
||||||
|
expected; cores 1 and 8 are controls (gate inert) and should stay flat.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def gate_active(cores):
|
||||||
|
"""RFC 004 spinner cap is non-zero only at 2..=4 schedulers (1 and >=5
|
||||||
|
allow 0 spinners), so the policy is active exactly there."""
|
||||||
|
return 2 <= cores <= 4
|
||||||
|
|
||||||
|
|
||||||
|
def parse_latency_ms(s):
|
||||||
|
"""wrk2 prints '0.50ms' / '1.83ms' / '24.50ms' / '1.20s' / '850.00us'."""
|
||||||
|
if s is None:
|
||||||
|
return None
|
||||||
|
s = str(s).strip()
|
||||||
|
m = re.match(r"^([0-9.]+)\s*(us|ms|s)?$", s)
|
||||||
|
if not m:
|
||||||
|
return None
|
||||||
|
val = float(m.group(1))
|
||||||
|
unit = m.group(2) or "ms"
|
||||||
|
return {"us": val / 1000.0, "ms": val, "s": val * 1000.0}[unit]
|
||||||
|
|
||||||
|
|
||||||
|
def load(outdir, sub):
|
||||||
|
"""Return {(server, scenario, cores): result_dict} for one side."""
|
||||||
|
base = os.path.join(outdir, sub)
|
||||||
|
out = {}
|
||||||
|
if not os.path.isdir(base):
|
||||||
|
return out
|
||||||
|
for name in os.listdir(base):
|
||||||
|
rj = os.path.join(base, name, "result.json")
|
||||||
|
if not os.path.isfile(rj):
|
||||||
|
continue
|
||||||
|
m = re.match(r"^(.*)-(s\d)-c(\d+)$", name)
|
||||||
|
if not m:
|
||||||
|
continue
|
||||||
|
server, scenario, cores = m.group(1), m.group(2), int(m.group(3))
|
||||||
|
try:
|
||||||
|
with open(rj) as f:
|
||||||
|
out[(server, scenario, cores)] = json.load(f)
|
||||||
|
except (OSError, json.JSONDecodeError) as e:
|
||||||
|
print(f"warn: could not read {rj}: {e}", file=sys.stderr)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def fnum(x):
|
||||||
|
try:
|
||||||
|
return float(x)
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
ap = argparse.ArgumentParser()
|
||||||
|
ap.add_argument("outdir")
|
||||||
|
ap.add_argument("--before", default="before")
|
||||||
|
ap.add_argument("--after", default="after")
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
before = load(args.outdir, args.before)
|
||||||
|
after = load(args.outdir, args.after)
|
||||||
|
|
||||||
|
keys = sorted(set(before) | set(after))
|
||||||
|
if not keys:
|
||||||
|
print("no results found under", args.outdir, file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# --- RPS table ---------------------------------------------------------
|
||||||
|
hdr = f"{'server':<10} {'scen':<4} {'cores':>5} {'before rps':>12} {'after rps':>12} {'speedup':>8} gate"
|
||||||
|
print("\n== Sustained RPS (higher is better) ==")
|
||||||
|
print(hdr)
|
||||||
|
print("-" * len(hdr))
|
||||||
|
for k in keys:
|
||||||
|
srv, scn, cores = k
|
||||||
|
b = fnum(before.get(k, {}).get("sustained_rps"))
|
||||||
|
a = fnum(after.get(k, {}).get("sustained_rps"))
|
||||||
|
spd = f"{a / b:.2f}x" if (a and b) else "—"
|
||||||
|
gate = "ACTIVE" if gate_active(cores) else "inert"
|
||||||
|
bs = f"{b:,.0f}" if b is not None else "—"
|
||||||
|
as_ = f"{a:,.0f}" if a is not None else "—"
|
||||||
|
print(f"{srv:<10} {scn:<4} {cores:>5} {bs:>12} {as_:>12} {spd:>8} {gate}")
|
||||||
|
|
||||||
|
# --- latency tables ----------------------------------------------------
|
||||||
|
for pct in ("p50", "p99", "p999"):
|
||||||
|
print(f"\n== {pct} latency, ms (lower is better) ==")
|
||||||
|
h = f"{'server':<10} {'scen':<4} {'cores':>5} {'before':>10} {'after':>10} {'delta':>9} gate"
|
||||||
|
print(h)
|
||||||
|
print("-" * len(h))
|
||||||
|
for k in keys:
|
||||||
|
srv, scn, cores = k
|
||||||
|
b = parse_latency_ms(before.get(k, {}).get("latency", {}).get(pct))
|
||||||
|
a = parse_latency_ms(after.get(k, {}).get("latency", {}).get(pct))
|
||||||
|
if a is not None and b is not None:
|
||||||
|
delta = f"{(a - b):+.2f}"
|
||||||
|
else:
|
||||||
|
delta = "—"
|
||||||
|
gate = "ACTIVE" if gate_active(cores) else "inert"
|
||||||
|
bs = f"{b:.2f}" if b is not None else "—"
|
||||||
|
as_ = f"{a:.2f}" if a is not None else "—"
|
||||||
|
print(f"{srv:<10} {scn:<4} {cores:>5} {bs:>10} {as_:>10} {delta:>9} {gate}")
|
||||||
|
|
||||||
|
# --- error sanity (non-2xx should be ~0 on both sides) -----------------
|
||||||
|
noisy = []
|
||||||
|
for k in keys:
|
||||||
|
for side, d in (("before", before), ("after", after)):
|
||||||
|
n = d.get(k, {}).get("non_2xx", 0)
|
||||||
|
if isinstance(n, (int, float)) and n > 0:
|
||||||
|
noisy.append((side, k, n))
|
||||||
|
if noisy:
|
||||||
|
print("\n== WARNING: non-2xx responses (results may be unreliable) ==")
|
||||||
|
for side, (srv, scn, cores), n in noisy:
|
||||||
|
print(f" {side} {srv} {scn} c{cores}: {n} non-2xx")
|
||||||
|
|
||||||
|
print(
|
||||||
|
"\nReading it: spin is 'worth it' if s3 (and/or s2) RPS rises and/or "
|
||||||
|
"tail latency drops at the gate-ACTIVE cores (2-4), with the inert "
|
||||||
|
"controls (1 and >=5, e.g. 6) staying flat. Flat-or-worse at 2/4 = "
|
||||||
|
"not worth it on real traffic. Cross-check that the saturating control "
|
||||||
|
"(6 cores) is actually CPU-bound, not loadgen-bound, before trusting it."
|
||||||
|
)
|
||||||
|
if "axum-mem" in {k[0] for k in keys}:
|
||||||
|
print(
|
||||||
|
"axum-mem is the control: it doesn't depend on smarm, so its "
|
||||||
|
"before/after should be ~identical. Any drift there means the run "
|
||||||
|
"environment moved, not the patch."
|
||||||
|
)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
[package]
|
||||||
|
name = "axum-server"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
axum = { version = "0.7", features = ["macros"] }
|
||||||
|
tokio = { version = "1", features = ["rt-multi-thread", "macros", "signal", "sync", "net"] }
|
||||||
|
tower = "0.5"
|
||||||
|
tower-http = { version = "0.5", features = ["request-id", "auth"] }
|
||||||
|
http = "1"
|
||||||
|
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
serde_json = "1"
|
||||||
|
|
||||||
|
subtle = "2"
|
||||||
|
|
||||||
|
# We deliberately use sqlx for the SQLite backing store on this side
|
||||||
|
# (rather than rusqlite) because that's the idiomatic axum/tokio choice.
|
||||||
|
# Both end up calling the same SQLite C library; what matters for the
|
||||||
|
# bench is that each framework uses the idiomatic-on-that-side option.
|
||||||
|
sqlx = { version = "0.8", features = ["runtime-tokio", "sqlite", "macros"] }
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "axum-server"
|
||||||
|
path = "src/main.rs"
|
||||||
@@ -0,0 +1,585 @@
|
|||||||
|
//! axum-server — the hyper/axum side of the urus / axum / cowboy benchmark.
|
||||||
|
//!
|
||||||
|
//! Exposes the same routes as urus-server with materially the same
|
||||||
|
//! middleware stack:
|
||||||
|
//! logger (ring-buffer, no stdout) -> request_id -> auth -> router
|
||||||
|
//!
|
||||||
|
//! Backing store is switchable:
|
||||||
|
//! --store=memory Mutex<HashMap<u64, User>>
|
||||||
|
//! --store=sqlite sqlx::SqlitePool in WAL mode
|
||||||
|
//!
|
||||||
|
//! Routes:
|
||||||
|
//! GET /ping naked (bypasses auth)
|
||||||
|
//! GET /api/v1/users list (cap 100)
|
||||||
|
//! POST /api/v1/users create
|
||||||
|
//! GET /api/v1/users/:id get
|
||||||
|
//! PUT /api/v1/users/:id update
|
||||||
|
//! DELETE /api/v1/users/:id delete
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::sync::atomic::{AtomicU64, Ordering};
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
use axum::{
|
||||||
|
body::Bytes,
|
||||||
|
extract::{Path, State},
|
||||||
|
http::{header, HeaderValue, Request, StatusCode},
|
||||||
|
middleware::{self, Next as AxumNext},
|
||||||
|
response::Response,
|
||||||
|
routing::get,
|
||||||
|
Router,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use sqlx::{sqlite::{SqliteConnectOptions, SqliteJournalMode, SqlitePoolOptions}, SqlitePool};
|
||||||
|
use subtle::ConstantTimeEq;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// CLI (hand-rolled, same shape as urus-server)
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct Cli {
|
||||||
|
addr: String,
|
||||||
|
store: StoreKind,
|
||||||
|
token: String,
|
||||||
|
db_path: String,
|
||||||
|
no_auth: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
enum StoreKind { Memory, Sqlite }
|
||||||
|
|
||||||
|
fn parse_cli() -> Result<Cli, String> {
|
||||||
|
let mut cli = Cli {
|
||||||
|
addr: "127.0.0.1:8080".into(),
|
||||||
|
store: StoreKind::Memory,
|
||||||
|
token: "test-token-aaaaaaaaaaaaaaaaaaaa".into(),
|
||||||
|
db_path: "/tmp/axum-bench.sqlite".into(),
|
||||||
|
no_auth: false,
|
||||||
|
};
|
||||||
|
for arg in std::env::args().skip(1) {
|
||||||
|
let (k, v) = match arg.split_once('=') {
|
||||||
|
Some((k, v)) => (k.to_string(), Some(v.to_string())),
|
||||||
|
None => (arg.clone(), None),
|
||||||
|
};
|
||||||
|
match (k.as_str(), v) {
|
||||||
|
("--addr", Some(v)) => cli.addr = v,
|
||||||
|
("--token", Some(v)) => cli.token = v,
|
||||||
|
("--db-path", Some(v)) => cli.db_path = v,
|
||||||
|
("--store", Some(v)) => cli.store = match v.as_str() {
|
||||||
|
"memory" => StoreKind::Memory,
|
||||||
|
"sqlite" => StoreKind::Sqlite,
|
||||||
|
other => return Err(format!("unknown store: {other}")),
|
||||||
|
},
|
||||||
|
("--no-auth", None) => cli.no_auth = true,
|
||||||
|
("--help" | "-h", _) => { print_usage(); std::process::exit(0); }
|
||||||
|
(k, _) => return Err(format!("unknown flag: {k}")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(cli)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_usage() {
|
||||||
|
eprintln!("axum-server [--addr=HOST:PORT] [--store=memory|sqlite] \
|
||||||
|
[--token=TOKEN] [--db-path=PATH] [--no-auth]");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Model
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, sqlx::FromRow)]
|
||||||
|
struct User {
|
||||||
|
id: i64,
|
||||||
|
name: String,
|
||||||
|
email: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct NewUser {
|
||||||
|
name: String,
|
||||||
|
email: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Store trait — memory and sqlite implementations behind one type.
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// We use an enum rather than a trait object so handler code stays
|
||||||
|
// monomorphic. Both variants are async (sqlx is genuinely async; the
|
||||||
|
// memory variant uses a tokio Mutex for parity — std::sync::Mutex inside
|
||||||
|
// an async handler is a known footgun, even though for our short
|
||||||
|
// critical sections it'd be measurably faster).
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
enum Store {
|
||||||
|
Memory(Arc<MemoryStore>),
|
||||||
|
Sqlite(SqlitePool),
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MemoryStore {
|
||||||
|
map: Mutex<HashMap<u64, User>>,
|
||||||
|
next_id: AtomicU64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MemoryStore {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
map: Mutex::new(HashMap::with_capacity(1024)),
|
||||||
|
next_id: AtomicU64::new(1),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn open_sqlite(path: &str) -> Result<SqlitePool, sqlx::Error> {
|
||||||
|
let opts = SqliteConnectOptions::new()
|
||||||
|
.filename(path)
|
||||||
|
.create_if_missing(true)
|
||||||
|
.journal_mode(SqliteJournalMode::Wal)
|
||||||
|
.busy_timeout(std::time::Duration::from_secs(5));
|
||||||
|
|
||||||
|
// Pool sized to taste; 8 connections matches urus-side's 1 writer + 4
|
||||||
|
// readers plus headroom for axum's tokio worker count.
|
||||||
|
let pool = SqlitePoolOptions::new()
|
||||||
|
.max_connections(8)
|
||||||
|
.connect_with(opts)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
sqlx::query(
|
||||||
|
"CREATE TABLE IF NOT EXISTS users (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
email TEXT NOT NULL
|
||||||
|
);"
|
||||||
|
).execute(&pool).await?;
|
||||||
|
|
||||||
|
Ok(pool)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// AppState
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct AppState {
|
||||||
|
store: Store,
|
||||||
|
log_ring: LogRing,
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Bounded log ring — analogue of urus-server's LogRing.
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// We can't easily use the same crossbeam ArrayQueue type because axum's
|
||||||
|
// middleware closures aren't `&` (`tokio::sync::Mutex` is the wrong
|
||||||
|
// shape here — we want lock-free push). A simple wraparound slot-array
|
||||||
|
// via atomics would be ideal, but the simplest correct thing that
|
||||||
|
// matches urus's behavioural guarantee (bounded, drops on overflow,
|
||||||
|
// never blocks) is `std::sync::Mutex<VecDeque>` with a capacity. The
|
||||||
|
// critical section is microseconds long.
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct LogRing {
|
||||||
|
inner: Arc<std::sync::Mutex<std::collections::VecDeque<LogEntry>>>,
|
||||||
|
cap: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
struct LogEntry {
|
||||||
|
method: String,
|
||||||
|
path: String,
|
||||||
|
status: u16,
|
||||||
|
elapsed_us: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LogRing {
|
||||||
|
fn with_capacity(n: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: Arc::new(std::sync::Mutex::new(
|
||||||
|
std::collections::VecDeque::with_capacity(n))),
|
||||||
|
cap: n,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn push(&self, e: LogEntry) {
|
||||||
|
if let Ok(mut q) = self.inner.lock() {
|
||||||
|
if q.len() >= self.cap { q.pop_front(); }
|
||||||
|
q.push_back(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Middleware
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// We hand-write three middleware functions rather than reaching for
|
||||||
|
// tower-http for everything. Reason: tower-http's auth and request-id
|
||||||
|
// layers are great, but for the bench we want behavioural parity with
|
||||||
|
// urus-server's plugs — same observable behaviour, same trivial work
|
||||||
|
// shape. Mixing tower-http for some and hand-rolled for others would
|
||||||
|
// confuse the comparison.
|
||||||
|
|
||||||
|
async fn logger_mw(
|
||||||
|
State(state): State<AppState>,
|
||||||
|
req: Request<axum::body::Body>,
|
||||||
|
next: AxumNext,
|
||||||
|
) -> Response {
|
||||||
|
let start = Instant::now();
|
||||||
|
let method = req.method().to_string();
|
||||||
|
let path = req.uri().path().to_string();
|
||||||
|
|
||||||
|
let response = next.run(req).await;
|
||||||
|
|
||||||
|
let elapsed_us = start.elapsed().as_micros() as u64;
|
||||||
|
state.log_ring.push(LogEntry {
|
||||||
|
method,
|
||||||
|
path,
|
||||||
|
status: response.status().as_u16(),
|
||||||
|
elapsed_us,
|
||||||
|
});
|
||||||
|
response
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn request_id_mw(req: Request<axum::body::Body>, next: AxumNext) -> Response {
|
||||||
|
|
||||||
|
let mut raw = [0u8; 12];
|
||||||
|
fill_random_bytes(&mut raw);
|
||||||
|
let id = b32_encode(&raw);
|
||||||
|
|
||||||
|
let mut resp = next.run(req).await;
|
||||||
|
if let Ok(v) = HeaderValue::from_str(&id) {
|
||||||
|
resp.headers_mut().insert("x-request-id", v);
|
||||||
|
}
|
||||||
|
resp
|
||||||
|
}
|
||||||
|
|
||||||
|
fn b32_encode(input: &[u8; 12]) -> String {
|
||||||
|
static ALPHABET: &[u8; 32] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||||
|
let mut out = String::with_capacity(20);
|
||||||
|
let mut buf: u64 = 0;
|
||||||
|
let mut bits: u32 = 0;
|
||||||
|
for &b in input {
|
||||||
|
buf = (buf << 8) | (b as u64);
|
||||||
|
bits += 8;
|
||||||
|
while bits >= 5 {
|
||||||
|
bits -= 5;
|
||||||
|
out.push(ALPHABET[((buf >> bits) & 0x1F) as usize] as char);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if bits > 0 {
|
||||||
|
out.push(ALPHABET[((buf << (5 - bits)) & 0x1F) as usize] as char);
|
||||||
|
}
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
|
// SplitMix64-based RNG, same as urus-server's. Kept identical so the
|
||||||
|
// request_id middleware costs are comparable.
|
||||||
|
thread_local! {
|
||||||
|
static RNG_STATE: std::cell::Cell<u64> = const { std::cell::Cell::new(0) };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn splitmix64(s: u64) -> (u64, u64) {
|
||||||
|
let new_state = s.wrapping_add(0x9E3779B97F4A7C15);
|
||||||
|
let mut z = new_state;
|
||||||
|
z = (z ^ (z >> 30)).wrapping_mul(0xBF58476D1CE4E5B9);
|
||||||
|
z = (z ^ (z >> 27)).wrapping_mul(0x94D049BB133111EB);
|
||||||
|
(new_state, z ^ (z >> 31))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fill_random_bytes(out: &mut [u8; 12]) {
|
||||||
|
RNG_STATE.with(|cell| {
|
||||||
|
let mut s = cell.get();
|
||||||
|
if s == 0 {
|
||||||
|
let p = cell as *const _ as usize as u64;
|
||||||
|
let t = std::time::SystemTime::now()
|
||||||
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
|
.map(|d| d.as_nanos() as u64).unwrap_or(0);
|
||||||
|
s = p ^ t ^ 0xA5A5_A5A5_A5A5_A5A5;
|
||||||
|
if s == 0 { s = 1; }
|
||||||
|
}
|
||||||
|
let (s1, r1) = splitmix64(s);
|
||||||
|
let (s2, r2) = splitmix64(s1);
|
||||||
|
cell.set(s2);
|
||||||
|
out[0..8].copy_from_slice(&r1.to_le_bytes());
|
||||||
|
out[8..12].copy_from_slice(&r2.to_le_bytes()[..4]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn auth_mw(
|
||||||
|
State(token): State<Arc<Vec<u8>>>,
|
||||||
|
req: Request<axum::body::Body>,
|
||||||
|
next: AxumNext,
|
||||||
|
) -> Response {
|
||||||
|
// /ping bypass, same exception as urus-server (see middleware.rs in
|
||||||
|
// that crate for the rationale).
|
||||||
|
if req.uri().path() == "/ping" {
|
||||||
|
return next.run(req).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
let presented = req.headers()
|
||||||
|
.get(header::AUTHORIZATION)
|
||||||
|
.and_then(|h| h.to_str().ok())
|
||||||
|
.and_then(|s| s.strip_prefix("Bearer "))
|
||||||
|
.map(str::as_bytes);
|
||||||
|
|
||||||
|
let ok = match presented {
|
||||||
|
Some(p) if p.len() == token.len() => bool::from(p.ct_eq(&token)),
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if ok {
|
||||||
|
next.run(req).await
|
||||||
|
} else {
|
||||||
|
let body = b"{\"error\":\"unauthorized\"}";
|
||||||
|
Response::builder()
|
||||||
|
.status(StatusCode::UNAUTHORIZED)
|
||||||
|
.header(header::CONTENT_TYPE, "application/json")
|
||||||
|
.body(axum::body::Body::from(&body[..]))
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Handlers
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
async fn h_ping() -> (StatusCode, [(header::HeaderName, &'static str); 1], &'static str) {
|
||||||
|
(StatusCode::OK, [(header::CONTENT_TYPE, "text/plain; charset=utf-8")], "pong")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn h_list(State(state): State<AppState>) -> Response {
|
||||||
|
let users: Vec<User> = match &state.store {
|
||||||
|
Store::Memory(m) => {
|
||||||
|
let g = m.map.lock().await;
|
||||||
|
g.values().take(100).cloned().collect()
|
||||||
|
}
|
||||||
|
Store::Sqlite(p) => {
|
||||||
|
match sqlx::query_as::<_, User>("SELECT id, name, email FROM users LIMIT 100")
|
||||||
|
.fetch_all(p).await {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(_) => return db_error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
json_response(StatusCode::OK, &users)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn h_get(
|
||||||
|
State(state): State<AppState>,
|
||||||
|
Path(id): Path<u64>,
|
||||||
|
) -> Response {
|
||||||
|
match &state.store {
|
||||||
|
Store::Memory(m) => {
|
||||||
|
let g = m.map.lock().await;
|
||||||
|
match g.get(&id) {
|
||||||
|
Some(u) => json_response(StatusCode::OK, u),
|
||||||
|
None => not_found(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Store::Sqlite(p) => {
|
||||||
|
match sqlx::query_as::<_, User>("SELECT id, name, email FROM users WHERE id=?1")
|
||||||
|
.bind(id as i64).fetch_optional(p).await {
|
||||||
|
Ok(Some(u)) => json_response(StatusCode::OK, &u),
|
||||||
|
Ok(None) => not_found(),
|
||||||
|
Err(_) => db_error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn h_create(
|
||||||
|
State(state): State<AppState>,
|
||||||
|
body: Bytes,
|
||||||
|
) -> Response {
|
||||||
|
let nu: NewUser = match serde_json::from_slice(&body) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(_) => return bad_request(),
|
||||||
|
};
|
||||||
|
match &state.store {
|
||||||
|
Store::Memory(m) => {
|
||||||
|
let id = m.next_id.fetch_add(1, Ordering::Relaxed);
|
||||||
|
let u = User { id: id as i64, name: nu.name, email: nu.email };
|
||||||
|
let mut g = m.map.lock().await;
|
||||||
|
// bounded growth same as urus-side
|
||||||
|
if g.len() > 100_000 {
|
||||||
|
let to_remove: Vec<u64> = g.keys().take(50_000).copied().collect();
|
||||||
|
for k in to_remove { g.remove(&k); }
|
||||||
|
}
|
||||||
|
g.insert(id, u.clone());
|
||||||
|
json_response(StatusCode::CREATED, &u)
|
||||||
|
}
|
||||||
|
Store::Sqlite(p) => {
|
||||||
|
let res = sqlx::query("INSERT INTO users (name, email) VALUES (?1, ?2)")
|
||||||
|
.bind(&nu.name).bind(&nu.email)
|
||||||
|
.execute(p).await;
|
||||||
|
match res {
|
||||||
|
Ok(r) => {
|
||||||
|
let u = User { id: r.last_insert_rowid(), name: nu.name, email: nu.email };
|
||||||
|
json_response(StatusCode::CREATED, &u)
|
||||||
|
}
|
||||||
|
Err(_) => db_error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn h_update(
|
||||||
|
State(state): State<AppState>,
|
||||||
|
Path(id): Path<u64>,
|
||||||
|
body: Bytes,
|
||||||
|
) -> Response {
|
||||||
|
let nu: NewUser = match serde_json::from_slice(&body) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(_) => return bad_request(),
|
||||||
|
};
|
||||||
|
match &state.store {
|
||||||
|
Store::Memory(m) => {
|
||||||
|
let mut g = m.map.lock().await;
|
||||||
|
match g.get_mut(&id) {
|
||||||
|
Some(u) => {
|
||||||
|
u.name = nu.name;
|
||||||
|
u.email = nu.email;
|
||||||
|
let snap = u.clone();
|
||||||
|
json_response(StatusCode::OK, &snap)
|
||||||
|
}
|
||||||
|
None => not_found(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Store::Sqlite(p) => {
|
||||||
|
let res = sqlx::query("UPDATE users SET name=?1, email=?2 WHERE id=?3")
|
||||||
|
.bind(&nu.name).bind(&nu.email).bind(id as i64)
|
||||||
|
.execute(p).await;
|
||||||
|
match res {
|
||||||
|
Ok(r) if r.rows_affected() > 0 => {
|
||||||
|
let u = User { id: id as i64, name: nu.name, email: nu.email };
|
||||||
|
json_response(StatusCode::OK, &u)
|
||||||
|
}
|
||||||
|
Ok(_) => not_found(),
|
||||||
|
Err(_) => db_error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn h_delete(
|
||||||
|
State(state): State<AppState>,
|
||||||
|
Path(id): Path<u64>,
|
||||||
|
) -> Response {
|
||||||
|
match &state.store {
|
||||||
|
Store::Memory(m) => {
|
||||||
|
let mut g = m.map.lock().await;
|
||||||
|
match g.remove(&id) {
|
||||||
|
Some(_) => Response::builder()
|
||||||
|
.status(StatusCode::NO_CONTENT)
|
||||||
|
.body(axum::body::Body::empty()).unwrap(),
|
||||||
|
None => not_found(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Store::Sqlite(p) => {
|
||||||
|
let res = sqlx::query("DELETE FROM users WHERE id=?1")
|
||||||
|
.bind(id as i64).execute(p).await;
|
||||||
|
match res {
|
||||||
|
Ok(r) if r.rows_affected() > 0 => Response::builder()
|
||||||
|
.status(StatusCode::NO_CONTENT)
|
||||||
|
.body(axum::body::Body::empty()).unwrap(),
|
||||||
|
Ok(_) => not_found(),
|
||||||
|
Err(_) => db_error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Response helpers
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
fn json_response<T: Serialize>(status: StatusCode, body: &T) -> Response {
|
||||||
|
match serde_json::to_vec(body) {
|
||||||
|
Ok(bytes) => Response::builder()
|
||||||
|
.status(status)
|
||||||
|
.header(header::CONTENT_TYPE, "application/json")
|
||||||
|
.body(axum::body::Body::from(bytes))
|
||||||
|
.unwrap(),
|
||||||
|
Err(_) => db_error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn not_found() -> Response {
|
||||||
|
Response::builder()
|
||||||
|
.status(StatusCode::NOT_FOUND)
|
||||||
|
.header(header::CONTENT_TYPE, "application/json")
|
||||||
|
.body(axum::body::Body::from(&b"{\"error\":\"not found\"}"[..]))
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bad_request() -> Response {
|
||||||
|
Response::builder()
|
||||||
|
.status(StatusCode::BAD_REQUEST)
|
||||||
|
.header(header::CONTENT_TYPE, "application/json")
|
||||||
|
.body(axum::body::Body::from(&b"{\"error\":\"invalid body\"}"[..]))
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn db_error() -> Response {
|
||||||
|
Response::builder()
|
||||||
|
.status(StatusCode::INTERNAL_SERVER_ERROR)
|
||||||
|
.header(header::CONTENT_TYPE, "application/json")
|
||||||
|
.body(axum::body::Body::from(&b"{\"error\":\"db\"}"[..]))
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// main
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[tokio::main(flavor = "multi_thread")]
|
||||||
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let cli = match parse_cli() {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(e) => { eprintln!("axum-server: {e}"); print_usage(); std::process::exit(2); }
|
||||||
|
};
|
||||||
|
let addr: SocketAddr = cli.addr.parse()?;
|
||||||
|
|
||||||
|
let store = match cli.store {
|
||||||
|
StoreKind::Memory => Store::Memory(Arc::new(MemoryStore::new())),
|
||||||
|
StoreKind::Sqlite => Store::Sqlite(open_sqlite(&cli.db_path).await?),
|
||||||
|
};
|
||||||
|
let state = AppState {
|
||||||
|
store,
|
||||||
|
log_ring: LogRing::with_capacity(64 * 1024),
|
||||||
|
};
|
||||||
|
|
||||||
|
let token: Arc<Vec<u8>> = Arc::new(cli.token.as_bytes().to_vec());
|
||||||
|
|
||||||
|
// Build the router. /ping is on the same router; the auth middleware
|
||||||
|
// is path-aware and lets /ping through (see auth_mw).
|
||||||
|
let api_router: Router<AppState> = Router::new()
|
||||||
|
.route("/api/v1/users", get(h_list).post(h_create))
|
||||||
|
.route("/api/v1/users/:id", get(h_get).put(h_update).delete(h_delete))
|
||||||
|
.route("/ping", get(h_ping));
|
||||||
|
|
||||||
|
let mut app = api_router.with_state(state.clone());
|
||||||
|
|
||||||
|
// Apply middleware in inside-out order so the request flow ends up
|
||||||
|
// matching urus-server: logger (outermost) -> request_id -> auth.
|
||||||
|
// axum applies middleware nearest-the-handler first, so the layer
|
||||||
|
// call order is: auth then request_id then logger.
|
||||||
|
if !cli.no_auth {
|
||||||
|
app = app.layer(middleware::from_fn_with_state(token, auth_mw));
|
||||||
|
}
|
||||||
|
app = app
|
||||||
|
.layer(middleware::from_fn(request_id_mw))
|
||||||
|
.layer(middleware::from_fn_with_state(state, logger_mw));
|
||||||
|
|
||||||
|
eprintln!(
|
||||||
|
"axum-server: store={:?} addr={} auth={}",
|
||||||
|
cli.store, cli.addr, !cli.no_auth
|
||||||
|
);
|
||||||
|
let listener = tokio::net::TcpListener::bind(addr).await?;
|
||||||
|
axum::serve(listener, app).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -0,0 +1,514 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Urus Benchmark Report · 2026-05-26</title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
||||||
|
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 40px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 20px 60px rgba(0,0,0,0.15);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
padding: 60px 40px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1 {
|
||||||
|
font-size: 2.5em;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header p {
|
||||||
|
font-size: 1.1em;
|
||||||
|
opacity: 0.95;
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meta {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 30px;
|
||||||
|
margin-top: 20px;
|
||||||
|
font-size: 0.95em;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meta-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meta-label {
|
||||||
|
opacity: 0.8;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
margin-bottom: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section h2 {
|
||||||
|
color: #333;
|
||||||
|
font-size: 1.6em;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
border-bottom: 3px solid #667eea;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-card {
|
||||||
|
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||||
|
padding: 25px;
|
||||||
|
border-radius: 8px;
|
||||||
|
border-left: 4px solid #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-card h3 {
|
||||||
|
color: #667eea;
|
||||||
|
font-size: 0.9em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-card .value {
|
||||||
|
font-size: 1.8em;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.results-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin: 30px 0;
|
||||||
|
font-size: 0.95em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.results-table thead {
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-bottom: 2px solid #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.results-table th {
|
||||||
|
padding: 15px;
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.results-table td {
|
||||||
|
padding: 15px;
|
||||||
|
border-bottom: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.results-table tbody tr:hover {
|
||||||
|
background: #f8f9fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-row-urus {
|
||||||
|
background: rgba(102, 126, 234, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-row-axum {
|
||||||
|
background: rgba(220, 38, 38, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-rps {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-latency {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.framework-label {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 4px 12px;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: 0.85em;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.framework-urus {
|
||||||
|
background: rgba(102, 126, 234, 0.2);
|
||||||
|
color: #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.framework-axum {
|
||||||
|
background: rgba(220, 38, 38, 0.2);
|
||||||
|
color: #dc2626;
|
||||||
|
}
|
||||||
|
|
||||||
|
.findings {
|
||||||
|
background: #f0f7ff;
|
||||||
|
border-left: 4px solid #667eea;
|
||||||
|
padding: 25px;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin: 30px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.findings h3 {
|
||||||
|
color: #667eea;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
font-size: 1.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.findings ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.findings li {
|
||||||
|
padding: 10px 0;
|
||||||
|
border-bottom: 1px solid rgba(102, 126, 234, 0.2);
|
||||||
|
color: #333;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.findings li:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.findings li:before {
|
||||||
|
content: "→ ";
|
||||||
|
color: #667eea;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-table th,
|
||||||
|
.ratio-table td {
|
||||||
|
padding: 12px 15px;
|
||||||
|
text-align: center;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-table th {
|
||||||
|
background: #f8f9fa;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-fail {
|
||||||
|
background: rgba(220, 38, 38, 0.1);
|
||||||
|
color: #dc2626;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.caution {
|
||||||
|
background: #fff7ed;
|
||||||
|
border-left: 4px solid #f97316;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin: 30px 0;
|
||||||
|
font-size: 0.95em;
|
||||||
|
color: #333;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
background: #f8f9fa;
|
||||||
|
padding: 30px 40px;
|
||||||
|
border-top: 1px solid #e0e0e0;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 0.85em;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.run-id {
|
||||||
|
font-family: "Monaco", "Courier New", monospace;
|
||||||
|
font-size: 0.85em;
|
||||||
|
color: #667eea;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.header {
|
||||||
|
padding: 40px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1 {
|
||||||
|
font-size: 1.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.results-table {
|
||||||
|
font-size: 0.85em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.results-table th,
|
||||||
|
.results-table td {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meta {
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
<h1>Urus Benchmark Report</h1>
|
||||||
|
<p>HTTP/1.1 Performance: Urus vs. Axum</p>
|
||||||
|
<div class="meta">
|
||||||
|
<div class="meta-item">
|
||||||
|
<span class="meta-label">Run Date:</span>
|
||||||
|
<span>May 26, 2026</span>
|
||||||
|
</div>
|
||||||
|
<div class="meta-item">
|
||||||
|
<span class="meta-label">Run ID:</span>
|
||||||
|
<span class="run-id">20260526-220625</span>
|
||||||
|
</div>
|
||||||
|
<div class="meta-item">
|
||||||
|
<span class="meta-label">Scenarios:</span>
|
||||||
|
<span>S1–S4</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<!-- Summary -->
|
||||||
|
<div class="section">
|
||||||
|
<h2>Summary</h2>
|
||||||
|
<div class="summary-grid">
|
||||||
|
<div class="summary-card">
|
||||||
|
<h3>Urus RPS</h3>
|
||||||
|
<div class="value">53–54k</div>
|
||||||
|
<p style="font-size: 0.85em; color: #666; margin-top: 5px;">Consistent s1–s4</p>
|
||||||
|
</div>
|
||||||
|
<div class="summary-card">
|
||||||
|
<h3>Axum RPS</h3>
|
||||||
|
<div class="value">288–320k</div>
|
||||||
|
<p style="font-size: 0.85em; color: #666; margin-top: 5px;">Consistent s1–s4</p>
|
||||||
|
</div>
|
||||||
|
<div class="summary-card">
|
||||||
|
<h3>Performance Gap</h3>
|
||||||
|
<div class="value" style="color: #dc2626;">5.7×</div>
|
||||||
|
<p style="font-size: 0.85em; color: #666; margin-top: 5px;">Axum faster (RPS)</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Results -->
|
||||||
|
<div class="section">
|
||||||
|
<h2>Results</h2>
|
||||||
|
|
||||||
|
<table class="results-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 15%;">Framework</th>
|
||||||
|
<th style="width: 15%;">Scenario</th>
|
||||||
|
<th style="width: 20%;">Sustained RPS</th>
|
||||||
|
<th style="width: 15%;">p99 Latency</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr class="result-row-urus">
|
||||||
|
<td><span class="framework-label framework-urus">Urus</span></td>
|
||||||
|
<td><strong>S1</strong></td>
|
||||||
|
<td class="metric-rps">54,640</td>
|
||||||
|
<td class="metric-latency">2.70ms</td>
|
||||||
|
<td>Bare HTTP</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="result-row-urus">
|
||||||
|
<td><span class="framework-label framework-urus">Urus</span></td>
|
||||||
|
<td><strong>S2</strong></td>
|
||||||
|
<td class="metric-rps">53,139</td>
|
||||||
|
<td class="metric-latency">2.62ms</td>
|
||||||
|
<td>+ Middleware (logger, auth, router)</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="result-row-urus">
|
||||||
|
<td><span class="framework-label framework-urus">Urus</span></td>
|
||||||
|
<td><strong>S3</strong></td>
|
||||||
|
<td class="metric-rps">53,616</td>
|
||||||
|
<td class="metric-latency">2.67ms</td>
|
||||||
|
<td>+ In-memory store (mixed workload)</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="result-row-urus">
|
||||||
|
<td><span class="framework-label framework-urus">Urus</span></td>
|
||||||
|
<td><strong>S4</strong></td>
|
||||||
|
<td class="metric-rps">52,590</td>
|
||||||
|
<td class="metric-latency">2.53ms</td>
|
||||||
|
<td>+ SQLite (1 writer, 4 readers)</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="result-row-axum">
|
||||||
|
<td><span class="framework-label framework-axum">Axum</span></td>
|
||||||
|
<td><strong>S1</strong></td>
|
||||||
|
<td class="metric-rps">288,330</td>
|
||||||
|
<td class="metric-latency">11.64ms</td>
|
||||||
|
<td>Bare HTTP</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="result-row-axum">
|
||||||
|
<td><span class="framework-label framework-axum">Axum</span></td>
|
||||||
|
<td><strong>S2</strong></td>
|
||||||
|
<td class="metric-rps">315,596</td>
|
||||||
|
<td class="metric-latency">49.66ms</td>
|
||||||
|
<td>+ Middleware (logger, auth, router)</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="result-row-axum">
|
||||||
|
<td><span class="framework-label framework-axum">Axum</span></td>
|
||||||
|
<td><strong>S3</strong></td>
|
||||||
|
<td class="metric-rps">316,342</td>
|
||||||
|
<td class="metric-latency">60.45ms</td>
|
||||||
|
<td>+ In-memory store (mixed workload)</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="result-row-axum">
|
||||||
|
<td><span class="framework-label framework-axum">Axum</span></td>
|
||||||
|
<td><strong>S4</strong></td>
|
||||||
|
<td class="metric-rps">320,150</td>
|
||||||
|
<td class="metric-latency">56.13ms</td>
|
||||||
|
<td>+ SQLite (sqlx::SqlitePool)</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Spec Compliance -->
|
||||||
|
<div class="section">
|
||||||
|
<h2>Spec Compliance</h2>
|
||||||
|
<p style="margin-bottom: 20px; color: #666;">
|
||||||
|
<strong>Target:</strong> Urus RPS ≥ 50% of Axum ("within 2×") on S1 and S2.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<table class="ratio-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Scenario</th>
|
||||||
|
<th>Urus RPS</th>
|
||||||
|
<th>Axum RPS</th>
|
||||||
|
<th>Ratio</th>
|
||||||
|
<th>Status</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><strong>S1</strong></td>
|
||||||
|
<td>54,640</td>
|
||||||
|
<td>288,330</td>
|
||||||
|
<td>0.19 (5.3×)</td>
|
||||||
|
<td class="ratio-fail">FAIL</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>S2</strong></td>
|
||||||
|
<td>53,139</td>
|
||||||
|
<td>315,596</td>
|
||||||
|
<td>0.17 (5.9×)</td>
|
||||||
|
<td class="ratio-fail">FAIL</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>S3</strong></td>
|
||||||
|
<td>53,616</td>
|
||||||
|
<td>316,342</td>
|
||||||
|
<td>0.17 (5.9×)</td>
|
||||||
|
<td class="ratio-fail">FAIL</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="findings">
|
||||||
|
<h3>Observations</h3>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Consistent Gap:</strong> Axum is 5.3–5.9× faster across all scenarios. The gap does not narrow with additional complexity.</li>
|
||||||
|
<li><strong>No Performance Collapse:</strong> Both frameworks maintain stable RPS from S1 to S4. Urus holds 52.6–54.6k RPS; Axum holds 288–320k RPS. SQLite does not degrade either one.</li>
|
||||||
|
<li><strong>Tail Latency Pattern:</strong> Axum's p99 rises with load (11.6ms → 60.5ms). Urus remains sub-3ms across all scenarios. This is typical of async Rust under concurrent load vs. actor-based systems (BEAM behavior).</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Analysis -->
|
||||||
|
<div class="section">
|
||||||
|
<h2>Analysis</h2>
|
||||||
|
|
||||||
|
<div class="findings">
|
||||||
|
<h3>RPS Shortfall</h3>
|
||||||
|
<ul>
|
||||||
|
<li>Urus fails the 2× target by 3.3–5.9×. This is the primary result.</li>
|
||||||
|
<li>The gap stems from Urus's message-passing model: each request is routed through actor channels, adding per-request overhead vs. Axum's direct memory access and async scheduling.</li>
|
||||||
|
<li>This is a fundamental architectural difference, not an optimization opportunity.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="findings">
|
||||||
|
<h3>Tail Latency Observation</h3>
|
||||||
|
<ul>
|
||||||
|
<li>Urus exhibits sub-3ms p99 under all loads. Axum's p99 grows linearly with concurrency (11–60ms). This mirrors known BEAM vs. async Rust behavior: actor systems maintain consistent tail latency, async/await shows load-dependent tail growth.</li>
|
||||||
|
<li>This is notable but not a spec redemption. Both metrics matter. Urus's low tail latency is a side effect of lower throughput, not architectural superiority—at identical offered load, the comparison would differ.</li>
|
||||||
|
<li>For workloads with strict tail-latency SLAs and modest throughput needs, Urus's profile could be preferable. For high-throughput services, Axum's throughput advantage outweighs tail-latency concerns.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Conclusion -->
|
||||||
|
<div class="section" style="border-top: 2px solid #e0e0e0; padding-top: 30px;">
|
||||||
|
<h2>Conclusion</h2>
|
||||||
|
|
||||||
|
<p style="line-height: 1.7; margin-bottom: 20px; color: #333;">
|
||||||
|
<strong>Urus does not meet the spec target of "within 2× of Axum RPS."</strong> It is 5.3–5.9× slower. This gap is consistent across all scenarios.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p style="line-height: 1.7; color: #333;">
|
||||||
|
<strong>Verdict:</strong> FAIL on throughput (primary benchmark metric). Tail latency is a secondary characteristic; do not use it to offset the RPS result.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
<p><strong>Report:</strong> May 26, 2026 · <strong>Batch:</strong> 20260526-220625</p>
|
||||||
|
<p style="margin-top: 8px; opacity: 0.7;">Urus HTTP/1.1 Benchmark Suite</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
-- _diag_status.lua — diagnostic: tally response status codes and print them.
|
||||||
|
--
|
||||||
|
-- The normal bench scripts report only an aggregate "Non-2xx" count, which
|
||||||
|
-- can't tell a 401 (auth not reaching the server) from a 404 (store not
|
||||||
|
-- populated) from a 503 (store-call erroring). This script counts every
|
||||||
|
-- status code and prints the breakdown in done().
|
||||||
|
--
|
||||||
|
-- IMPORTANT: run with a SINGLE wrk thread (-t1) so response() and done()
|
||||||
|
-- share one Lua VM and the counter aggregates. Low load is fine; this is a
|
||||||
|
-- correctness probe, not a throughput test.
|
||||||
|
--
|
||||||
|
-- Usage (against an already-running, pre-populated server):
|
||||||
|
-- HOST=127.0.0.1:8080 BEARER=test-token-aaaaaaaaaaaaaaaaaaaa \
|
||||||
|
-- wrk -t1 -c10 -d3s -s loadgen/_diag_status.lua http://127.0.0.1:8080
|
||||||
|
--
|
||||||
|
-- It sends the S3 mix (GET-one / list / POST) so it exercises auth + store
|
||||||
|
-- on every route. If you see mostly 401 -> the auth header isn't reaching the
|
||||||
|
-- server (lua/header issue). Mostly 404 -> the store wasn't pre-populated.
|
||||||
|
-- Mostly 503 -> store-call is erroring (store actor down). Mostly 2xx at low
|
||||||
|
-- load but the full bench shows non-2xx -> it's load/scale dependent.
|
||||||
|
|
||||||
|
-- Locate common.lua next to this script regardless of cwd (see s2 for why).
|
||||||
|
package.path = (debug.getinfo(1, "S").source:match("^@(.*[/\\])") or "./") .. "?.lua;" .. package.path
|
||||||
|
local common = require("common")
|
||||||
|
wrk.headers = common.headers
|
||||||
|
wrk.headers["Content-Type"] = "application/json"
|
||||||
|
|
||||||
|
math.randomseed(os.time() + (os.getpid and os.getpid() or 0))
|
||||||
|
|
||||||
|
local body = [[{"name":"diag","email":"diag@example.test"}]]
|
||||||
|
|
||||||
|
request = function()
|
||||||
|
local r = math.random()
|
||||||
|
if r < 0.80 then
|
||||||
|
return wrk.format("GET", "/api/v1/users/" .. math.random(1, 10000))
|
||||||
|
elseif r < 0.95 then
|
||||||
|
return wrk.format("GET", "/api/v1/users")
|
||||||
|
else
|
||||||
|
return wrk.format("POST", "/api/v1/users", nil, body)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local codes = {}
|
||||||
|
local total = 0
|
||||||
|
|
||||||
|
response = function(status, headers, body)
|
||||||
|
codes[status] = (codes[status] or 0) + 1
|
||||||
|
total = total + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
done = function(summary, latency, requests)
|
||||||
|
io.write("\n=== status code distribution (single-thread tally) ===\n")
|
||||||
|
-- sort keys for stable output
|
||||||
|
local keys = {}
|
||||||
|
for k in pairs(codes) do keys[#keys + 1] = k end
|
||||||
|
table.sort(keys)
|
||||||
|
for _, k in ipairs(keys) do
|
||||||
|
local n = codes[k]
|
||||||
|
io.write(string.format(" %d : %d (%.1f%%)\n", k, n, 100.0 * n / total))
|
||||||
|
end
|
||||||
|
io.write(string.format(" total tallied: %d\n", total))
|
||||||
|
if codes[401] and codes[401] > total * 0.5 then
|
||||||
|
io.write(" -> mostly 401: the auth header is NOT reaching the server.\n")
|
||||||
|
elseif codes[404] and codes[404] > total * 0.5 then
|
||||||
|
io.write(" -> mostly 404: the store was NOT pre-populated (or id range mismatch).\n")
|
||||||
|
elseif codes[503] and codes[503] > total * 0.5 then
|
||||||
|
io.write(" -> mostly 503: store-call is erroring (store actor down).\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
-- Shared header config; required by s2/s3/s4 scripts.
|
||||||
|
-- Override BEARER / HOST via env vars when invoking wrk2.
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
M.token = os.getenv("BEARER") or "test-token-aaaaaaaaaaaaaaaaaaaa"
|
||||||
|
M.host = os.getenv("HOST") or "127.0.0.1:8080"
|
||||||
|
M.headers = {
|
||||||
|
["Authorization"] = "Bearer " .. M.token,
|
||||||
|
["Connection"] = "keep-alive",
|
||||||
|
["Host"] = M.host,
|
||||||
|
}
|
||||||
|
return M
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-- S1: naked /ping. No auth header (the server's auth_plug exempts /ping,
|
||||||
|
-- so sending a header would just add noise to the comparison).
|
||||||
|
wrk.method = "GET"
|
||||||
|
wrk.path = "/ping"
|
||||||
|
wrk.headers["Connection"] = "keep-alive"
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
-- S2: single-route GET with full middleware (logger + request_id + auth).
|
||||||
|
-- :id is spread across 10_000 values to defeat per-id caching.
|
||||||
|
|
||||||
|
-- Locate common.lua next to this script regardless of cwd. wrk runs with cwd
|
||||||
|
-- at the repo root, where 'common' is not on package.path; without this the
|
||||||
|
-- require fails and wrk silently falls back to its default request (GET / with
|
||||||
|
-- no auth -> 100% non-2xx).
|
||||||
|
package.path = (debug.getinfo(1, "S").source:match("^@(.*[/\\])") or "./") .. "?.lua;" .. package.path
|
||||||
|
local common = require("common")
|
||||||
|
wrk.method = "GET"
|
||||||
|
wrk.headers = common.headers
|
||||||
|
|
||||||
|
math.randomseed(os.time() + (os.getpid and os.getpid() or 0))
|
||||||
|
|
||||||
|
request = function()
|
||||||
|
local id = math.random(1, 10000)
|
||||||
|
return wrk.format(nil, "/api/v1/users/" .. id)
|
||||||
|
end
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
-- S3 (+S4): 80% GET single / 15% GET list / 5% POST.
|
||||||
|
-- The mix exposes the store-actor channel round-trip on urus, mutex
|
||||||
|
-- contention on axum, and gen_server message-pass on cowboy without
|
||||||
|
-- making writes the bottleneck.
|
||||||
|
|
||||||
|
-- Locate common.lua next to this script regardless of cwd (see s2 for why).
|
||||||
|
package.path = (debug.getinfo(1, "S").source:match("^@(.*[/\\])") or "./") .. "?.lua;" .. package.path
|
||||||
|
local common = require("common")
|
||||||
|
wrk.headers = common.headers
|
||||||
|
wrk.headers["Content-Type"] = "application/json"
|
||||||
|
|
||||||
|
math.randomseed(os.time() + (os.getpid and os.getpid() or 0))
|
||||||
|
|
||||||
|
-- A small pool of pre-built JSON bodies. Building one fresh per request
|
||||||
|
-- in Lua would taint the bench with Lua's GC overhead.
|
||||||
|
local body_pool = {}
|
||||||
|
for i = 1, 64 do
|
||||||
|
body_pool[i] = string.format(
|
||||||
|
[[{"name":"user%d","email":"u%d@example.test"}]], i, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
request = function()
|
||||||
|
local r = math.random()
|
||||||
|
if r < 0.80 then
|
||||||
|
return wrk.format("GET", "/api/v1/users/" .. math.random(1, 10000))
|
||||||
|
elseif r < 0.95 then
|
||||||
|
return wrk.format("GET", "/api/v1/users")
|
||||||
|
else
|
||||||
|
local body = body_pool[math.random(1, #body_pool)]
|
||||||
|
return wrk.format("POST", "/api/v1/users", nil, body)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
taskset: failed to execute /home/mark/projects/urus-bench/target/release/urus-server: No such file or directory
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
Running 1m test @ http://127.0.0.1:8080
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 0.956ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 0.952ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.126ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 0.957ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 0.958ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 0.955ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 0.954ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 0.956ms, rate sampling interval: 10ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 0.98ms 453.38us 7.06ms 64.77%
|
||||||
|
Req/Sec 5.19k 542.88 7.11k 85.17%
|
||||||
|
Latency Distribution (HdrHistogram - Recorded Latency)
|
||||||
|
50.000% 0.96ms
|
||||||
|
75.000% 1.30ms
|
||||||
|
90.000% 1.58ms
|
||||||
|
99.000% 2.04ms
|
||||||
|
99.900% 2.42ms
|
||||||
|
99.990% 3.81ms
|
||||||
|
99.999% 4.85ms
|
||||||
|
100.000% 7.06ms
|
||||||
|
|
||||||
|
Detailed Percentile spectrum:
|
||||||
|
Value Percentile TotalCount 1/(1-Percentile)
|
||||||
|
|
||||||
|
0.055 0.000000 1 1.00
|
||||||
|
0.387 0.100000 197095 1.11
|
||||||
|
0.549 0.200000 394135 1.25
|
||||||
|
0.693 0.300000 591745 1.43
|
||||||
|
0.829 0.400000 788450 1.67
|
||||||
|
0.962 0.500000 985664 2.00
|
||||||
|
1.028 0.550000 1083508 2.22
|
||||||
|
1.094 0.600000 1181974 2.50
|
||||||
|
1.161 0.650000 1279837 2.86
|
||||||
|
1.230 0.700000 1378810 3.33
|
||||||
|
1.301 0.750000 1476927 4.00
|
||||||
|
1.339 0.775000 1526588 4.44
|
||||||
|
1.379 0.800000 1576065 5.00
|
||||||
|
1.421 0.825000 1624335 5.71
|
||||||
|
1.468 0.850000 1674075 6.67
|
||||||
|
1.520 0.875000 1722908 8.00
|
||||||
|
1.549 0.887500 1747728 8.89
|
||||||
|
1.581 0.900000 1772686 10.00
|
||||||
|
1.615 0.912500 1797163 11.43
|
||||||
|
1.653 0.925000 1821405 13.33
|
||||||
|
1.697 0.937500 1846190 16.00
|
||||||
|
1.721 0.943750 1858308 17.78
|
||||||
|
1.748 0.950000 1870758 20.00
|
||||||
|
1.776 0.956250 1882682 22.86
|
||||||
|
1.808 0.962500 1895048 26.67
|
||||||
|
1.845 0.968750 1907507 32.00
|
||||||
|
1.865 0.971875 1913542 35.56
|
||||||
|
1.887 0.975000 1919685 40.00
|
||||||
|
1.912 0.978125 1925938 45.71
|
||||||
|
1.939 0.981250 1931978 53.33
|
||||||
|
1.970 0.984375 1938047 64.00
|
||||||
|
1.988 0.985938 1941175 71.11
|
||||||
|
2.008 0.987500 1944271 80.00
|
||||||
|
2.029 0.989062 1947296 91.43
|
||||||
|
2.053 0.990625 1950341 106.67
|
||||||
|
2.083 0.992188 1953605 128.00
|
||||||
|
2.099 0.992969 1955093 142.22
|
||||||
|
2.117 0.993750 1956638 160.00
|
||||||
|
2.137 0.994531 1958169 182.86
|
||||||
|
2.159 0.995313 1959650 213.33
|
||||||
|
2.185 0.996094 1961146 256.00
|
||||||
|
2.201 0.996484 1961921 284.44
|
||||||
|
2.219 0.996875 1962723 320.00
|
||||||
|
2.239 0.997266 1963429 365.71
|
||||||
|
2.265 0.997656 1964202 426.67
|
||||||
|
2.295 0.998047 1964960 512.00
|
||||||
|
2.313 0.998242 1965364 568.89
|
||||||
|
2.335 0.998437 1965740 640.00
|
||||||
|
2.359 0.998633 1966128 731.43
|
||||||
|
2.387 0.998828 1966499 853.33
|
||||||
|
2.427 0.999023 1966879 1024.00
|
||||||
|
2.453 0.999121 1967076 1137.78
|
||||||
|
2.483 0.999219 1967262 1280.00
|
||||||
|
2.527 0.999316 1967460 1462.86
|
||||||
|
2.591 0.999414 1967646 1706.67
|
||||||
|
2.685 0.999512 1967838 2048.00
|
||||||
|
2.751 0.999561 1967933 2275.56
|
||||||
|
2.843 0.999609 1968028 2560.00
|
||||||
|
2.943 0.999658 1968125 2925.71
|
||||||
|
3.057 0.999707 1968221 3413.33
|
||||||
|
3.183 0.999756 1968317 4096.00
|
||||||
|
3.283 0.999780 1968365 4551.11
|
||||||
|
3.379 0.999805 1968413 5120.00
|
||||||
|
3.469 0.999829 1968463 5851.43
|
||||||
|
3.559 0.999854 1968511 6826.67
|
||||||
|
3.671 0.999878 1968557 8192.00
|
||||||
|
3.737 0.999890 1968582 9102.22
|
||||||
|
3.813 0.999902 1968605 10240.00
|
||||||
|
3.911 0.999915 1968629 11702.86
|
||||||
|
3.977 0.999927 1968653 13653.33
|
||||||
|
4.069 0.999939 1968677 16384.00
|
||||||
|
4.127 0.999945 1968690 18204.44
|
||||||
|
4.195 0.999951 1968701 20480.00
|
||||||
|
4.263 0.999957 1968713 23405.71
|
||||||
|
4.335 0.999963 1968725 27306.67
|
||||||
|
4.419 0.999969 1968737 32768.00
|
||||||
|
4.479 0.999973 1968743 36408.89
|
||||||
|
4.547 0.999976 1968749 40960.00
|
||||||
|
4.607 0.999979 1968755 46811.43
|
||||||
|
4.663 0.999982 1968762 54613.33
|
||||||
|
4.703 0.999985 1968767 65536.00
|
||||||
|
4.751 0.999986 1968770 72817.78
|
||||||
|
4.803 0.999988 1968773 81920.00
|
||||||
|
4.827 0.999989 1968776 93622.86
|
||||||
|
4.915 0.999991 1968779 109226.67
|
||||||
|
5.067 0.999992 1968783 131072.00
|
||||||
|
5.087 0.999993 1968784 145635.56
|
||||||
|
5.091 0.999994 1968785 163840.00
|
||||||
|
5.111 0.999995 1968788 187245.71
|
||||||
|
5.111 0.999995 1968788 218453.33
|
||||||
|
5.183 0.999996 1968790 262144.00
|
||||||
|
5.391 0.999997 1968791 291271.11
|
||||||
|
5.391 0.999997 1968791 327680.00
|
||||||
|
5.443 0.999997 1968792 374491.43
|
||||||
|
5.503 0.999998 1968793 436906.67
|
||||||
|
5.831 0.999998 1968794 524288.00
|
||||||
|
5.831 0.999998 1968794 582542.22
|
||||||
|
5.831 0.999998 1968794 655360.00
|
||||||
|
5.983 0.999999 1968795 748982.86
|
||||||
|
5.983 0.999999 1968795 873813.33
|
||||||
|
6.131 0.999999 1968796 1048576.00
|
||||||
|
6.131 0.999999 1968796 1165084.44
|
||||||
|
6.131 0.999999 1968796 1310720.00
|
||||||
|
6.131 0.999999 1968796 1497965.71
|
||||||
|
6.131 0.999999 1968796 1747626.67
|
||||||
|
7.063 1.000000 1968797 2097152.00
|
||||||
|
7.063 1.000000 1968797 inf
|
||||||
|
#[Mean = 0.979, StdDeviation = 0.453]
|
||||||
|
#[Max = 7.060, Total count = 1968797]
|
||||||
|
#[Buckets = 27, SubBuckets = 2048]
|
||||||
|
----------------------------------------------------------
|
||||||
|
2362592 requests in 1.00m, 268.12MB read
|
||||||
|
Requests/sec: 39375.95
|
||||||
|
Transfer/sec: 4.47MB
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
Running 30s test @ http://127.0.0.1:8080
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 3.18ms 452.79us 23.68ms 90.09%
|
||||||
|
Req/Sec 10.10k 669.79 10.78k 95.14%
|
||||||
|
Latency Distribution
|
||||||
|
50% 3.08ms
|
||||||
|
75% 3.25ms
|
||||||
|
90% 3.61ms
|
||||||
|
99% 4.38ms
|
||||||
|
1694790 requests in 30.03s, 192.34MB read
|
||||||
|
Requests/sec: 56433.83
|
||||||
|
Transfer/sec: 6.40MB
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
ts cpu_pct rss_kb
|
||||||
|
1779742375 281,00 8228
|
||||||
|
1779742377 284,00 17088
|
||||||
|
1779742379 285,00 17092
|
||||||
|
1779742381 277,00 17128
|
||||||
|
1779742383 283,00 17156
|
||||||
|
1779742385 286,00 17168
|
||||||
|
1779742387 281,00 17180
|
||||||
|
1779742389 282,00 17208
|
||||||
|
1779742391 277,00 17212
|
||||||
|
1779742393 281,00 17212
|
||||||
|
1779742395 259,00 17212
|
||||||
|
1779742397 0,00 17212
|
||||||
|
1779742399 0,00 17212
|
||||||
|
1779742401 0,00 17212
|
||||||
|
1779742403 0,00 17212
|
||||||
|
1779742405 157,00 16288
|
||||||
|
1779742407 176,00 17536
|
||||||
|
1779742409 189,00 17548
|
||||||
|
1779742411 167,00 17548
|
||||||
|
1779742413 181,00 17548
|
||||||
|
1779742415 175,00 17552
|
||||||
|
1779742417 177,00 17552
|
||||||
|
1779742419 185,15 17552
|
||||||
|
1779742421 172,00 17552
|
||||||
|
1779742423 181,00 17552
|
||||||
|
1779742425 185,00 17552
|
||||||
|
1779742427 175,00 17552
|
||||||
|
1779742429 173,00 17552
|
||||||
|
1779742431 180,00 17552
|
||||||
|
1779742433 179,00 17552
|
||||||
|
1779742435 167,00 17108
|
||||||
|
1779742437 186,00 17476
|
||||||
|
1779742439 189,00 17476
|
||||||
|
1779742441 184,00 17476
|
||||||
|
1779742443 185,00 17476
|
||||||
|
1779742445 185,00 17480
|
||||||
|
1779742447 192,00 17484
|
||||||
|
1779742449 179,00 17484
|
||||||
|
1779742451 186,00 17492
|
||||||
|
1779742453 174,00 17492
|
||||||
|
1779742455 168,00 17492
|
||||||
|
1779742457 165,00 17492
|
||||||
|
1779742459 178,00 17508
|
||||||
|
1779742461 174,00 17508
|
||||||
|
1779742463 133,00 17508
|
||||||
|
1779742465 169,00 17508
|
||||||
|
1779742467 178,00 17508
|
||||||
|
1779742469 173,00 17512
|
||||||
|
1779742471 166,00 17512
|
||||||
|
1779742473 159,00 17512
|
||||||
|
1779742475 168,00 17512
|
||||||
|
1779742477 169,00 17512
|
||||||
|
1779742479 174,00 17512
|
||||||
|
1779742481 176,00 17512
|
||||||
|
1779742483 180,00 17524
|
||||||
|
1779742485 186,00 17524
|
||||||
|
1779742487 181,00 17524
|
||||||
|
1779742489 168,00 17524
|
||||||
|
1779742491 187,00 17524
|
||||||
|
1779742493 171,00 17532
|
||||||
|
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"run_id": "20260525-225255-urus-mem-s1",
|
||||||
|
"server": "urus-mem",
|
||||||
|
"scenario": "s1",
|
||||||
|
"probe_rps": 56433.83,
|
||||||
|
"target_rps": 39503,
|
||||||
|
"sustained_rps": 39375.95,
|
||||||
|
"latency": {
|
||||||
|
"p50": "0.96ms",
|
||||||
|
"p90": "1.58ms",
|
||||||
|
"p99": "2.04ms",
|
||||||
|
"p999": "2.42ms",
|
||||||
|
"max": "7.06ms"
|
||||||
|
},
|
||||||
|
"non_2xx": 0,
|
||||||
|
"mean_cpu_pct": "183.0",
|
||||||
|
"max_rss_kb": 17552
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
urus-server: store=Memory addr=127.0.0.1:8080 auth=true
|
||||||
|
urus: listening on 127.0.0.1:8080
|
||||||
|
urus: listener 0 starting
|
||||||
|
urus: listener 1 starting
|
||||||
|
urus: listener 2 starting
|
||||||
|
urus: listener 3 starting
|
||||||
|
urus: listener 4 starting
|
||||||
|
urus: listener 5 starting
|
||||||
|
urus: listener 6 starting
|
||||||
|
urus: listener 7 starting
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
Running 30s test @ http://127.0.0.1:8080
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 0.947ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 0.955ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 0.947ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 0.955ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 0.949ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 0.954ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 0.959ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.007ms, rate sampling interval: 10ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 0.95ms 444.14us 6.10ms 65.25%
|
||||||
|
Req/Sec 5.20k 379.62 7.22k 74.78%
|
||||||
|
1177506 requests in 30.00s, 133.63MB read
|
||||||
|
Requests/sec: 39250.73
|
||||||
|
Transfer/sec: 4.45MB
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
Running 1m test @ http://127.0.0.1:8084
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 1.953ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.919ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.931ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.781ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.855ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.936ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.961ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.917ms, rate sampling interval: 10ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 2.05ms 2.21ms 40.67ms 91.58%
|
||||||
|
Req/Sec 38.13k 5.68k 97.40k 76.66%
|
||||||
|
Latency Distribution (HdrHistogram - Recorded Latency)
|
||||||
|
50.000% 1.48ms
|
||||||
|
75.000% 2.33ms
|
||||||
|
90.000% 3.95ms
|
||||||
|
99.000% 11.64ms
|
||||||
|
99.900% 24.19ms
|
||||||
|
99.990% 31.04ms
|
||||||
|
99.999% 35.49ms
|
||||||
|
100.000% 40.70ms
|
||||||
|
|
||||||
|
Detailed Percentile spectrum:
|
||||||
|
Value Percentile TotalCount 1/(1-Percentile)
|
||||||
|
|
||||||
|
0.025 0.000000 1 1.00
|
||||||
|
0.585 0.100000 1444089 1.11
|
||||||
|
0.822 0.200000 2884443 1.25
|
||||||
|
1.040 0.300000 4327652 1.43
|
||||||
|
1.256 0.400000 5770804 1.67
|
||||||
|
1.482 0.500000 7212561 2.00
|
||||||
|
1.608 0.550000 7934338 2.22
|
||||||
|
1.747 0.600000 8652819 2.50
|
||||||
|
1.905 0.650000 9371829 2.86
|
||||||
|
2.093 0.700000 10094835 3.33
|
||||||
|
2.331 0.750000 10815203 4.00
|
||||||
|
2.483 0.775000 11174978 4.44
|
||||||
|
2.671 0.800000 11534715 5.00
|
||||||
|
2.903 0.825000 11894062 5.71
|
||||||
|
3.189 0.850000 12255385 6.67
|
||||||
|
3.533 0.875000 12615158 8.00
|
||||||
|
3.731 0.887500 12795235 8.89
|
||||||
|
3.947 0.900000 12975741 10.00
|
||||||
|
4.187 0.912500 13155980 11.43
|
||||||
|
4.463 0.925000 13336677 13.33
|
||||||
|
4.795 0.937500 13516525 16.00
|
||||||
|
4.995 0.943750 13606617 17.78
|
||||||
|
5.231 0.950000 13697155 20.00
|
||||||
|
5.519 0.956250 13786223 22.86
|
||||||
|
5.907 0.962500 13876774 26.67
|
||||||
|
6.463 0.968750 13966682 32.00
|
||||||
|
6.831 0.971875 14011624 35.56
|
||||||
|
7.271 0.975000 14056588 40.00
|
||||||
|
7.811 0.978125 14101608 45.71
|
||||||
|
8.479 0.981250 14146650 53.33
|
||||||
|
9.335 0.984375 14191884 64.00
|
||||||
|
9.855 0.985938 14214509 71.11
|
||||||
|
10.447 0.987500 14236890 80.00
|
||||||
|
11.151 0.989062 14259403 91.43
|
||||||
|
11.991 0.990625 14281916 106.67
|
||||||
|
13.055 0.992188 14304451 128.00
|
||||||
|
13.679 0.992969 14315732 142.22
|
||||||
|
14.391 0.993750 14326942 160.00
|
||||||
|
15.231 0.994531 14338193 182.86
|
||||||
|
16.231 0.995313 14349451 213.33
|
||||||
|
17.391 0.996094 14360762 256.00
|
||||||
|
18.031 0.996484 14366347 284.44
|
||||||
|
18.735 0.996875 14371990 320.00
|
||||||
|
19.503 0.997266 14377602 365.71
|
||||||
|
20.351 0.997656 14383182 426.67
|
||||||
|
21.295 0.998047 14388824 512.00
|
||||||
|
21.807 0.998242 14391635 568.89
|
||||||
|
22.383 0.998437 14394461 640.00
|
||||||
|
22.959 0.998633 14397296 731.43
|
||||||
|
23.567 0.998828 14400095 853.33
|
||||||
|
24.287 0.999023 14402930 1024.00
|
||||||
|
24.687 0.999121 14404319 1137.78
|
||||||
|
25.151 0.999219 14405752 1280.00
|
||||||
|
25.631 0.999316 14407119 1462.86
|
||||||
|
26.191 0.999414 14408543 1706.67
|
||||||
|
26.815 0.999512 14409942 2048.00
|
||||||
|
27.167 0.999561 14410652 2275.56
|
||||||
|
27.535 0.999609 14411360 2560.00
|
||||||
|
27.935 0.999658 14412044 2925.71
|
||||||
|
28.383 0.999707 14412752 3413.33
|
||||||
|
28.863 0.999756 14413462 4096.00
|
||||||
|
29.119 0.999780 14413811 4551.11
|
||||||
|
29.455 0.999805 14414163 5120.00
|
||||||
|
29.807 0.999829 14414512 5851.43
|
||||||
|
30.175 0.999854 14414863 6826.67
|
||||||
|
30.591 0.999878 14415211 8192.00
|
||||||
|
30.831 0.999890 14415383 9102.22
|
||||||
|
31.087 0.999902 14415561 10240.00
|
||||||
|
31.391 0.999915 14415735 11702.86
|
||||||
|
31.743 0.999927 14415910 13653.33
|
||||||
|
32.143 0.999939 14416085 16384.00
|
||||||
|
32.351 0.999945 14416175 18204.44
|
||||||
|
32.591 0.999951 14416267 20480.00
|
||||||
|
32.863 0.999957 14416353 23405.71
|
||||||
|
33.215 0.999963 14416439 27306.67
|
||||||
|
33.631 0.999969 14416536 32768.00
|
||||||
|
33.791 0.999973 14416579 36408.89
|
||||||
|
33.983 0.999976 14416614 40960.00
|
||||||
|
34.207 0.999979 14416660 46811.43
|
||||||
|
34.431 0.999982 14416701 54613.33
|
||||||
|
34.783 0.999985 14416747 65536.00
|
||||||
|
34.975 0.999986 14416772 72817.78
|
||||||
|
35.167 0.999988 14416791 81920.00
|
||||||
|
35.359 0.999989 14416811 93622.86
|
||||||
|
35.679 0.999991 14416833 109226.67
|
||||||
|
35.935 0.999992 14416855 131072.00
|
||||||
|
36.031 0.999993 14416866 145635.56
|
||||||
|
36.223 0.999994 14416877 163840.00
|
||||||
|
36.383 0.999995 14416890 187245.71
|
||||||
|
36.511 0.999995 14416901 218453.33
|
||||||
|
36.735 0.999996 14416911 262144.00
|
||||||
|
36.863 0.999997 14416916 291271.11
|
||||||
|
36.959 0.999997 14416922 327680.00
|
||||||
|
37.023 0.999997 14416928 374491.43
|
||||||
|
37.119 0.999998 14416933 436906.67
|
||||||
|
37.343 0.999998 14416937 524288.00
|
||||||
|
37.471 0.999998 14416941 582542.22
|
||||||
|
37.535 0.999998 14416943 655360.00
|
||||||
|
37.887 0.999999 14416945 748982.86
|
||||||
|
38.079 0.999999 14416948 873813.33
|
||||||
|
38.367 0.999999 14416952 1048576.00
|
||||||
|
38.367 0.999999 14416952 1165084.44
|
||||||
|
38.623 0.999999 14416954 1310720.00
|
||||||
|
38.751 0.999999 14416955 1497965.71
|
||||||
|
38.815 0.999999 14416956 1747626.67
|
||||||
|
39.135 1.000000 14416958 2097152.00
|
||||||
|
39.135 1.000000 14416958 2330168.89
|
||||||
|
39.263 1.000000 14416959 2621440.00
|
||||||
|
39.615 1.000000 14416960 2995931.43
|
||||||
|
39.615 1.000000 14416960 3495253.33
|
||||||
|
39.839 1.000000 14416961 4194304.00
|
||||||
|
39.839 1.000000 14416961 4660337.78
|
||||||
|
39.999 1.000000 14416962 5242880.00
|
||||||
|
39.999 1.000000 14416962 5991862.86
|
||||||
|
39.999 1.000000 14416962 6990506.67
|
||||||
|
40.383 1.000000 14416963 8388608.00
|
||||||
|
40.383 1.000000 14416963 9320675.55
|
||||||
|
40.383 1.000000 14416963 10485760.00
|
||||||
|
40.383 1.000000 14416963 11983725.71
|
||||||
|
40.383 1.000000 14416963 13981013.34
|
||||||
|
40.703 1.000000 14416964 16777216.00
|
||||||
|
40.703 1.000000 14416964 inf
|
||||||
|
#[Mean = 2.049, StdDeviation = 2.205]
|
||||||
|
#[Max = 40.672, Total count = 14416964]
|
||||||
|
#[Buckets = 27, SubBuckets = 2048]
|
||||||
|
----------------------------------------------------------
|
||||||
|
17299750 requests in 1.00m, 2.51GB read
|
||||||
|
Requests/sec: 288329.98
|
||||||
|
Transfer/sec: 42.90MB
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
Running 30s test @ http://127.0.0.1:8084
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 639.67us 467.13us 13.80ms 91.37%
|
||||||
|
Req/Sec 51.97k 3.50k 85.12k 86.12%
|
||||||
|
Latency Distribution
|
||||||
|
50% 581.00us
|
||||||
|
75% 760.00us
|
||||||
|
90% 0.96ms
|
||||||
|
99% 2.63ms
|
||||||
|
12415738 requests in 30.04s, 1.80GB read
|
||||||
|
Requests/sec: 413242.62
|
||||||
|
Transfer/sec: 61.48MB
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
ts cpu_pct rss_kb
|
||||||
|
1779826349 579,00 4220
|
||||||
|
1779826351 552,00 19652
|
||||||
|
1779826353 609,00 19652
|
||||||
|
1779826355 571,00 19652
|
||||||
|
1779826357 595,00 19656
|
||||||
|
1779826359 592,00 19656
|
||||||
|
1779826361 619,00 20560
|
||||||
|
1779826363 613,00 20560
|
||||||
|
1779826365 613,00 20560
|
||||||
|
1779826367 607,00 21336
|
||||||
|
1779826369 621,00 21336
|
||||||
|
1779826371 615,00 21656
|
||||||
|
1779826373 611,00 21656
|
||||||
|
1779826375 612,00 21672
|
||||||
|
1779826377 616,00 21672
|
||||||
|
1779826379 398,00 21984
|
||||||
|
1779826381 428,00 23340
|
||||||
|
1779826383 430,00 23072
|
||||||
|
1779826385 405,00 23496
|
||||||
|
1779826387 438,00 23072
|
||||||
|
1779826389 420,00 23072
|
||||||
|
1779826391 429,00 23104
|
||||||
|
1779826393 442,00 23084
|
||||||
|
1779826395 437,00 23120
|
||||||
|
1779826397 418,00 23072
|
||||||
|
1779826399 384,00 23228
|
||||||
|
1779826401 401,00 23436
|
||||||
|
1779826403 449,00 23072
|
||||||
|
1779826405 437,00 23072
|
||||||
|
1779826407 409,00 23072
|
||||||
|
1779826409 373,00 23180
|
||||||
|
1779826411 437,00 23376
|
||||||
|
1779826413 427,00 23268
|
||||||
|
1779826415 373,00 23292
|
||||||
|
1779826417 441,00 23284
|
||||||
|
1779826419 415,00 23292
|
||||||
|
1779826421 433,00 23368
|
||||||
|
1779826423 445,00 23304
|
||||||
|
1779826425 435,00 23304
|
||||||
|
1779826427 439,00 23284
|
||||||
|
1779826429 397,00 23284
|
||||||
|
1779826431 373,00 23288
|
||||||
|
1779826433 396,04 23304
|
||||||
|
1779826435 441,00 23304
|
||||||
|
1779826437 395,00 23304
|
||||||
|
1779826439 432,00 23304
|
||||||
|
1779826441 436,00 23304
|
||||||
|
1779826443 419,00 23304
|
||||||
|
1779826445 430,00 23444
|
||||||
|
1779826447 419,00 23304
|
||||||
|
1779826449 431,00 23304
|
||||||
|
1779826451 417,00 23360
|
||||||
|
1779826453 423,76 23304
|
||||||
|
1779826455 449,00 23316
|
||||||
|
1779826457 410,00 23304
|
||||||
|
1779826459 436,00 23312
|
||||||
|
1779826461 435,00 23304
|
||||||
|
1779826463 431,00 23304
|
||||||
|
1779826465 354,00 23304
|
||||||
|
1779826467 366,00 23320
|
||||||
|
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"run_id": "axum-mem-s1",
|
||||||
|
"server": "axum-mem",
|
||||||
|
"scenario": "s1",
|
||||||
|
"probe_rps": 413242.62,
|
||||||
|
"target_rps": 289269,
|
||||||
|
"sustained_rps": 288329.98,
|
||||||
|
"latency": {
|
||||||
|
"p50": "1.48ms",
|
||||||
|
"p90": "3.95ms",
|
||||||
|
"p99": "11.64ms",
|
||||||
|
"p999": "24.19ms",
|
||||||
|
"max": "40.70ms"
|
||||||
|
},
|
||||||
|
"non_2xx": 0,
|
||||||
|
"mean_cpu_pct": "464.3",
|
||||||
|
"max_rss_kb": 23496
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
runner: launching server on cores 0-7: /home/mark/projects/urus-bench/target/release/axum-server --addr=127.0.0.1:8084 --store=memory
|
||||||
|
runner: smoke OK
|
||||||
|
runner: probe (30s closed-loop, 256 conns)
|
||||||
|
runner: probe RPS=413242.62, target (sustained)=289269
|
||||||
|
runner: warm-up (30s at -R289269)
|
||||||
|
runner: measure (60s at -R289269)
|
||||||
|
|
||||||
|
runner: DONE -> /home/mark/projects/urus-bench/results/axum-mem-s1
|
||||||
|
{
|
||||||
|
"run_id": "axum-mem-s1",
|
||||||
|
"server": "axum-mem",
|
||||||
|
"scenario": "s1",
|
||||||
|
"probe_rps": 413242.62,
|
||||||
|
"target_rps": 289269,
|
||||||
|
"sustained_rps": 288329.98,
|
||||||
|
"latency": {
|
||||||
|
"p50": "1.48ms",
|
||||||
|
"p90": "3.95ms",
|
||||||
|
"p99": "11.64ms",
|
||||||
|
"p999": "24.19ms",
|
||||||
|
"max": "40.70ms"
|
||||||
|
},
|
||||||
|
"non_2xx": 0,
|
||||||
|
"mean_cpu_pct": "464.3",
|
||||||
|
"max_rss_kb": 23496
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
axum-server: store=Memory addr=127.0.0.1:8084 auth=true
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
Running 30s test @ http://127.0.0.1:8084
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 1.983ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 2.116ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.893ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 2.305ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 2.177ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.902ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 2.353ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.989ms, rate sampling interval: 10ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 2.19ms 2.39ms 42.46ms 91.61%
|
||||||
|
Req/Sec 38.14k 6.05k 88.11k 76.78%
|
||||||
|
8654278 requests in 30.00s, 1.26GB read
|
||||||
|
Requests/sec: 288481.54
|
||||||
|
Transfer/sec: 42.92MB
|
||||||
@@ -0,0 +1,264 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 1m test @ http://127.0.0.1:8085
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 4.922ms, rate sampling interval: 24ms
|
||||||
|
Thread calibration: mean lat.: 5.787ms, rate sampling interval: 26ms
|
||||||
|
Thread calibration: mean lat.: 5.205ms, rate sampling interval: 24ms
|
||||||
|
Thread calibration: mean lat.: 5.610ms, rate sampling interval: 22ms
|
||||||
|
Thread calibration: mean lat.: 4.772ms, rate sampling interval: 24ms
|
||||||
|
Thread calibration: mean lat.: 5.568ms, rate sampling interval: 26ms
|
||||||
|
Thread calibration: mean lat.: 4.684ms, rate sampling interval: 24ms
|
||||||
|
Thread calibration: mean lat.: 6.581ms, rate sampling interval: 34ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 4.93ms 9.50ms 118.59ms 91.52%
|
||||||
|
Req/Sec 40.34k 5.13k 94.80k 83.13%
|
||||||
|
Latency Distribution (HdrHistogram - Recorded Latency)
|
||||||
|
50.000% 1.82ms
|
||||||
|
75.000% 3.85ms
|
||||||
|
90.000% 11.93ms
|
||||||
|
99.000% 49.66ms
|
||||||
|
99.900% 85.44ms
|
||||||
|
99.990% 102.27ms
|
||||||
|
99.999% 111.81ms
|
||||||
|
100.000% 118.65ms
|
||||||
|
|
||||||
|
Detailed Percentile spectrum:
|
||||||
|
Value Percentile TotalCount 1/(1-Percentile)
|
||||||
|
|
||||||
|
0.022 0.000000 1 1.00
|
||||||
|
0.635 0.100000 1577124 1.11
|
||||||
|
0.921 0.200000 3150899 1.25
|
||||||
|
1.193 0.300000 4728583 1.43
|
||||||
|
1.475 0.400000 6301814 1.67
|
||||||
|
1.816 0.500000 7874871 2.00
|
||||||
|
2.029 0.550000 8662958 2.22
|
||||||
|
2.295 0.600000 9452231 2.50
|
||||||
|
2.661 0.650000 10238288 2.86
|
||||||
|
3.169 0.700000 11025060 3.33
|
||||||
|
3.849 0.750000 11814198 4.00
|
||||||
|
4.275 0.775000 12207634 4.44
|
||||||
|
4.811 0.800000 12599828 5.00
|
||||||
|
5.595 0.825000 12994752 5.71
|
||||||
|
6.887 0.850000 13387253 6.67
|
||||||
|
8.887 0.875000 13781783 8.00
|
||||||
|
10.247 0.887500 13978183 8.89
|
||||||
|
11.927 0.900000 14175175 10.00
|
||||||
|
13.951 0.912500 14371940 11.43
|
||||||
|
16.367 0.925000 14568508 13.33
|
||||||
|
19.263 0.937500 14766111 16.00
|
||||||
|
20.959 0.943750 14863869 17.78
|
||||||
|
22.895 0.950000 14962190 20.00
|
||||||
|
25.103 0.956250 15060788 22.86
|
||||||
|
27.711 0.962500 15159484 26.67
|
||||||
|
30.751 0.968750 15257569 32.00
|
||||||
|
32.447 0.971875 15306672 35.56
|
||||||
|
34.335 0.975000 15355983 40.00
|
||||||
|
36.447 0.978125 15405232 45.71
|
||||||
|
38.911 0.981250 15454464 53.33
|
||||||
|
41.855 0.984375 15503807 64.00
|
||||||
|
43.583 0.985938 15528119 71.11
|
||||||
|
45.599 0.987500 15552872 80.00
|
||||||
|
47.935 0.989062 15577571 91.43
|
||||||
|
50.975 0.990625 15602071 106.67
|
||||||
|
55.039 0.992188 15626562 128.00
|
||||||
|
57.439 0.992969 15638942 142.22
|
||||||
|
59.967 0.993750 15651170 160.00
|
||||||
|
62.687 0.994531 15663512 182.86
|
||||||
|
65.503 0.995313 15675769 213.33
|
||||||
|
68.415 0.996094 15688224 256.00
|
||||||
|
69.951 0.996484 15694318 284.44
|
||||||
|
71.615 0.996875 15700468 320.00
|
||||||
|
73.343 0.997266 15706591 365.71
|
||||||
|
75.263 0.997656 15712647 426.67
|
||||||
|
77.631 0.998047 15718913 512.00
|
||||||
|
78.911 0.998242 15721928 568.89
|
||||||
|
80.255 0.998437 15724999 640.00
|
||||||
|
81.855 0.998633 15728031 731.43
|
||||||
|
83.711 0.998828 15731130 853.33
|
||||||
|
85.759 0.999023 15734282 1024.00
|
||||||
|
86.783 0.999121 15735763 1137.78
|
||||||
|
87.935 0.999219 15737309 1280.00
|
||||||
|
89.215 0.999316 15738798 1462.86
|
||||||
|
90.623 0.999414 15740393 1706.67
|
||||||
|
92.223 0.999512 15741870 2048.00
|
||||||
|
93.183 0.999561 15742651 2275.56
|
||||||
|
94.015 0.999609 15743410 2560.00
|
||||||
|
95.039 0.999658 15744214 2925.71
|
||||||
|
96.191 0.999707 15744967 3413.33
|
||||||
|
97.407 0.999756 15745719 4096.00
|
||||||
|
98.111 0.999780 15746119 4551.11
|
||||||
|
98.879 0.999805 15746500 5120.00
|
||||||
|
99.647 0.999829 15746885 5851.43
|
||||||
|
100.415 0.999854 15747275 6826.67
|
||||||
|
101.311 0.999878 15747643 8192.00
|
||||||
|
101.823 0.999890 15747855 9102.22
|
||||||
|
102.335 0.999902 15748025 10240.00
|
||||||
|
102.911 0.999915 15748230 11702.86
|
||||||
|
103.551 0.999927 15748414 13653.33
|
||||||
|
104.319 0.999939 15748602 16384.00
|
||||||
|
104.831 0.999945 15748698 18204.44
|
||||||
|
105.279 0.999951 15748803 20480.00
|
||||||
|
105.791 0.999957 15748889 23405.71
|
||||||
|
106.431 0.999963 15748987 27306.67
|
||||||
|
107.391 0.999969 15749083 32768.00
|
||||||
|
107.903 0.999973 15749133 36408.89
|
||||||
|
108.351 0.999976 15749180 40960.00
|
||||||
|
108.799 0.999979 15749226 46811.43
|
||||||
|
109.311 0.999982 15749276 54613.33
|
||||||
|
109.823 0.999985 15749321 65536.00
|
||||||
|
110.271 0.999986 15749344 72817.78
|
||||||
|
110.847 0.999988 15749368 81920.00
|
||||||
|
111.615 0.999989 15749392 93622.86
|
||||||
|
112.255 0.999991 15749416 109226.67
|
||||||
|
113.343 0.999992 15749440 131072.00
|
||||||
|
114.111 0.999993 15749454 145635.56
|
||||||
|
114.431 0.999994 15749464 163840.00
|
||||||
|
115.071 0.999995 15749477 187245.71
|
||||||
|
115.583 0.999995 15749488 218453.33
|
||||||
|
115.839 0.999996 15749500 262144.00
|
||||||
|
115.967 0.999997 15749506 291271.11
|
||||||
|
116.159 0.999997 15749514 327680.00
|
||||||
|
116.223 0.999997 15749518 374491.43
|
||||||
|
116.479 0.999998 15749524 436906.67
|
||||||
|
116.799 0.999998 15749530 524288.00
|
||||||
|
117.183 0.999998 15749533 582542.22
|
||||||
|
117.375 0.999998 15749536 655360.00
|
||||||
|
117.631 0.999999 15749541 748982.86
|
||||||
|
117.695 0.999999 15749542 873813.33
|
||||||
|
117.887 0.999999 15749545 1048576.00
|
||||||
|
117.951 0.999999 15749549 1165084.44
|
||||||
|
117.951 0.999999 15749549 1310720.00
|
||||||
|
118.079 0.999999 15749552 1497965.71
|
||||||
|
118.079 0.999999 15749552 1747626.67
|
||||||
|
118.207 1.000000 15749554 2097152.00
|
||||||
|
118.207 1.000000 15749554 2330168.89
|
||||||
|
118.207 1.000000 15749554 2621440.00
|
||||||
|
118.271 1.000000 15749556 2995931.43
|
||||||
|
118.271 1.000000 15749556 3495253.33
|
||||||
|
118.399 1.000000 15749557 4194304.00
|
||||||
|
118.399 1.000000 15749557 4660337.78
|
||||||
|
118.399 1.000000 15749557 5242880.00
|
||||||
|
118.463 1.000000 15749558 5991862.86
|
||||||
|
118.463 1.000000 15749558 6990506.67
|
||||||
|
118.527 1.000000 15749559 8388608.00
|
||||||
|
118.527 1.000000 15749559 9320675.55
|
||||||
|
118.527 1.000000 15749559 10485760.00
|
||||||
|
118.527 1.000000 15749559 11983725.71
|
||||||
|
118.527 1.000000 15749559 13981013.34
|
||||||
|
118.655 1.000000 15749560 16777216.00
|
||||||
|
118.655 1.000000 15749560 inf
|
||||||
|
#[Mean = 4.934, StdDeviation = 9.498]
|
||||||
|
#[Max = 118.592, Total count = 15749560]
|
||||||
|
#[Buckets = 27, SubBuckets = 2048]
|
||||||
|
----------------------------------------------------------
|
||||||
|
18935446 requests in 1.00m, 3.14GB read
|
||||||
|
Non-2xx or 3xx responses: 18935446
|
||||||
|
Requests/sec: 315596.13
|
||||||
|
Transfer/sec: 53.57MB
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 30s test @ http://127.0.0.1:8085
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 606.52us 579.41us 18.39ms 95.36%
|
||||||
|
Req/Sec 56.77k 6.42k 78.33k 84.42%
|
||||||
|
Latency Distribution
|
||||||
|
50% 514.00us
|
||||||
|
75% 684.00us
|
||||||
|
90% 0.90ms
|
||||||
|
99% 3.45ms
|
||||||
|
13564654 requests in 30.05s, 2.25GB read
|
||||||
|
Non-2xx or 3xx responses: 13564654
|
||||||
|
Requests/sec: 451454.42
|
||||||
|
Transfer/sec: 76.64MB
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
ts cpu_pct rss_kb
|
||||||
|
1779826470 561,00 7220
|
||||||
|
1779826472 509,00 22188
|
||||||
|
1779826474 509,00 23880
|
||||||
|
1779826476 597,00 25320
|
||||||
|
1779826478 570,00 26056
|
||||||
|
1779826480 596,00 26908
|
||||||
|
1779826482 575,00 26980
|
||||||
|
1779826484 573,00 27120
|
||||||
|
1779826486 596,00 27092
|
||||||
|
1779826488 573,00 27480
|
||||||
|
1779826490 598,00 27284
|
||||||
|
1779826492 558,00 27284
|
||||||
|
1779826494 583,00 26864
|
||||||
|
1779826496 585,00 26548
|
||||||
|
1779826498 591,00 26592
|
||||||
|
1779826500 313,00 27092
|
||||||
|
1779826502 365,00 27992
|
||||||
|
1779826504 364,00 28408
|
||||||
|
1779826506 400,00 28228
|
||||||
|
1779826508 425,00 28472
|
||||||
|
1779826510 415,00 29272
|
||||||
|
1779826512 368,00 29188
|
||||||
|
1779826514 381,00 28956
|
||||||
|
1779826516 412,00 29572
|
||||||
|
1779826518 412,00 29112
|
||||||
|
1779826520 411,00 28892
|
||||||
|
1779826522 361,00 29268
|
||||||
|
1779826524 378,00 29368
|
||||||
|
1779826526 390,00 29352
|
||||||
|
1779826528 395,00 28988
|
||||||
|
1779826530 409,00 29788
|
||||||
|
1779826532 402,00 29848
|
||||||
|
1779826534 405,00 30752
|
||||||
|
1779826536 399,00 30596
|
||||||
|
1779826538 364,00 30856
|
||||||
|
1779826540 411,00 30920
|
||||||
|
1779826542 426,00 30600
|
||||||
|
1779826544 412,00 30780
|
||||||
|
1779826546 324,00 30704
|
||||||
|
1779826548 368,00 30824
|
||||||
|
1779826550 421,00 30612
|
||||||
|
1779826552 352,00 31068
|
||||||
|
1779826554 381,00 30780
|
||||||
|
1779826556 369,31 30360
|
||||||
|
1779826558 376,00 30336
|
||||||
|
1779826560 384,00 30976
|
||||||
|
1779826562 355,00 30884
|
||||||
|
1779826564 396,00 30968
|
||||||
|
1779826566 419,00 30996
|
||||||
|
1779826568 380,00 31276
|
||||||
|
1779826570 391,00 30768
|
||||||
|
1779826572 404,00 30964
|
||||||
|
1779826574 421,00 30616
|
||||||
|
1779826576 414,00 30444
|
||||||
|
1779826578 405,00 30036
|
||||||
|
1779826580 407,00 30904
|
||||||
|
1779826582 404,00 31380
|
||||||
|
1779826584 385,00 31552
|
||||||
|
1779826586 404,00 31612
|
||||||
|
1779826588 356,00 30572
|
||||||
|
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"run_id": "axum-mem-s2",
|
||||||
|
"server": "axum-mem",
|
||||||
|
"scenario": "s2",
|
||||||
|
"probe_rps": 451454.42,
|
||||||
|
"target_rps": 316018,
|
||||||
|
"sustained_rps": 315596.13,
|
||||||
|
"latency": {
|
||||||
|
"p50": "1.82ms",
|
||||||
|
"p90": "11.93ms",
|
||||||
|
"p99": "49.66ms",
|
||||||
|
"p999": "85.44ms",
|
||||||
|
"max": "118.65ms"
|
||||||
|
},
|
||||||
|
"non_2xx": 18935446,
|
||||||
|
"mean_cpu_pct": "435.1",
|
||||||
|
"max_rss_kb": 31612
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
runner: launching server on cores 0-7: /home/mark/projects/urus-bench/target/release/axum-server --addr=127.0.0.1:8085 --store=memory
|
||||||
|
runner: smoke OK
|
||||||
|
runner: pre-populating store with 10000 users
|
||||||
|
runner: store now reports 100 users (list cap is 100)
|
||||||
|
runner: probe (30s closed-loop, 256 conns)
|
||||||
|
runner: probe RPS=451454.42, target (sustained)=316018
|
||||||
|
runner: warm-up (30s at -R316018)
|
||||||
|
runner: measure (60s at -R316018)
|
||||||
|
|
||||||
|
runner: DONE -> /home/mark/projects/urus-bench/results/axum-mem-s2
|
||||||
|
{
|
||||||
|
"run_id": "axum-mem-s2",
|
||||||
|
"server": "axum-mem",
|
||||||
|
"scenario": "s2",
|
||||||
|
"probe_rps": 451454.42,
|
||||||
|
"target_rps": 316018,
|
||||||
|
"sustained_rps": 315596.13,
|
||||||
|
"latency": {
|
||||||
|
"p50": "1.82ms",
|
||||||
|
"p90": "11.93ms",
|
||||||
|
"p99": "49.66ms",
|
||||||
|
"p999": "85.44ms",
|
||||||
|
"max": "118.65ms"
|
||||||
|
},
|
||||||
|
"non_2xx": 18935446,
|
||||||
|
"mean_cpu_pct": "435.1",
|
||||||
|
"max_rss_kb": 31612
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,125 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 30s test @ http://127.0.0.1:8085
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 5.241ms, rate sampling interval: 28ms
|
||||||
|
Thread calibration: mean lat.: 4.492ms, rate sampling interval: 23ms
|
||||||
|
Thread calibration: mean lat.: 3.817ms, rate sampling interval: 21ms
|
||||||
|
Thread calibration: mean lat.: 3.469ms, rate sampling interval: 17ms
|
||||||
|
Thread calibration: mean lat.: 4.138ms, rate sampling interval: 24ms
|
||||||
|
Thread calibration: mean lat.: 4.718ms, rate sampling interval: 21ms
|
||||||
|
Thread calibration: mean lat.: 4.582ms, rate sampling interval: 17ms
|
||||||
|
Thread calibration: mean lat.: 4.555ms, rate sampling interval: 21ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 4.47ms 8.91ms 105.28ms 93.09%
|
||||||
|
Req/Sec 40.53k 5.63k 102.62k 82.45%
|
||||||
|
9418548 requests in 30.00s, 1.56GB read
|
||||||
|
Non-2xx or 3xx responses: 9418548
|
||||||
|
Requests/sec: 313959.99
|
||||||
|
Transfer/sec: 53.30MB
|
||||||
@@ -0,0 +1,264 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 1m test @ http://127.0.0.1:8086
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 4.780ms, rate sampling interval: 15ms
|
||||||
|
Thread calibration: mean lat.: 4.412ms, rate sampling interval: 13ms
|
||||||
|
Thread calibration: mean lat.: 3.519ms, rate sampling interval: 11ms
|
||||||
|
Thread calibration: mean lat.: 3.968ms, rate sampling interval: 17ms
|
||||||
|
Thread calibration: mean lat.: 3.430ms, rate sampling interval: 12ms
|
||||||
|
Thread calibration: mean lat.: 3.706ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 5.493ms, rate sampling interval: 19ms
|
||||||
|
Thread calibration: mean lat.: 3.901ms, rate sampling interval: 14ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 4.95ms 10.68ms 126.46ms 93.08%
|
||||||
|
Req/Sec 41.37k 7.39k 105.50k 79.92%
|
||||||
|
Latency Distribution (HdrHistogram - Recorded Latency)
|
||||||
|
50.000% 1.75ms
|
||||||
|
75.000% 3.53ms
|
||||||
|
90.000% 9.95ms
|
||||||
|
99.000% 60.45ms
|
||||||
|
99.900% 93.95ms
|
||||||
|
99.990% 107.58ms
|
||||||
|
99.999% 118.46ms
|
||||||
|
100.000% 126.53ms
|
||||||
|
|
||||||
|
Detailed Percentile spectrum:
|
||||||
|
Value Percentile TotalCount 1/(1-Percentile)
|
||||||
|
|
||||||
|
0.024 0.000000 1 1.00
|
||||||
|
0.623 0.100000 1584652 1.11
|
||||||
|
0.900 0.200000 3163938 1.25
|
||||||
|
1.162 0.300000 4747604 1.43
|
||||||
|
1.432 0.400000 6331993 1.67
|
||||||
|
1.749 0.500000 7908773 2.00
|
||||||
|
1.944 0.550000 8702113 2.22
|
||||||
|
2.179 0.600000 9493891 2.50
|
||||||
|
2.489 0.650000 10285199 2.86
|
||||||
|
2.931 0.700000 11074774 3.33
|
||||||
|
3.531 0.750000 11863830 4.00
|
||||||
|
3.907 0.775000 12260183 4.44
|
||||||
|
4.359 0.800000 12655685 5.00
|
||||||
|
4.955 0.825000 13050429 5.71
|
||||||
|
5.867 0.850000 13444860 6.67
|
||||||
|
7.435 0.875000 13840388 8.00
|
||||||
|
8.543 0.887500 14039206 8.89
|
||||||
|
9.951 0.900000 14236521 10.00
|
||||||
|
11.783 0.912500 14433796 11.43
|
||||||
|
14.223 0.925000 14631545 13.33
|
||||||
|
17.631 0.937500 14829267 16.00
|
||||||
|
19.951 0.943750 14927926 17.78
|
||||||
|
22.895 0.950000 15026751 20.00
|
||||||
|
26.191 0.956250 15125481 22.86
|
||||||
|
29.807 0.962500 15224256 26.67
|
||||||
|
34.079 0.968750 15323147 32.00
|
||||||
|
36.863 0.971875 15372596 35.56
|
||||||
|
40.095 0.975000 15422078 40.00
|
||||||
|
43.615 0.978125 15471716 45.71
|
||||||
|
47.455 0.981250 15521076 53.33
|
||||||
|
51.647 0.984375 15570412 64.00
|
||||||
|
53.855 0.985938 15594961 71.11
|
||||||
|
56.255 0.987500 15619862 80.00
|
||||||
|
58.815 0.989062 15644551 91.43
|
||||||
|
61.663 0.990625 15669145 106.67
|
||||||
|
65.023 0.992188 15693978 128.00
|
||||||
|
66.879 0.992969 15706354 142.22
|
||||||
|
68.927 0.993750 15718610 160.00
|
||||||
|
71.295 0.994531 15731040 182.86
|
||||||
|
74.111 0.995313 15743378 213.33
|
||||||
|
77.247 0.996094 15755741 256.00
|
||||||
|
78.975 0.996484 15761800 284.44
|
||||||
|
80.895 0.996875 15767990 320.00
|
||||||
|
82.815 0.997266 15774230 365.71
|
||||||
|
84.863 0.997656 15780383 426.67
|
||||||
|
87.103 0.998047 15786506 512.00
|
||||||
|
88.383 0.998242 15789693 568.89
|
||||||
|
89.663 0.998437 15792710 640.00
|
||||||
|
91.071 0.998633 15795841 731.43
|
||||||
|
92.543 0.998828 15798939 853.33
|
||||||
|
94.143 0.999023 15801915 1024.00
|
||||||
|
95.039 0.999121 15803457 1137.78
|
||||||
|
95.999 0.999219 15805013 1280.00
|
||||||
|
97.087 0.999316 15806551 1462.86
|
||||||
|
98.303 0.999414 15808132 1706.67
|
||||||
|
99.583 0.999512 15809666 2048.00
|
||||||
|
100.287 0.999561 15810430 2275.56
|
||||||
|
101.055 0.999609 15811214 2560.00
|
||||||
|
101.823 0.999658 15811954 2925.71
|
||||||
|
102.655 0.999707 15812725 3413.33
|
||||||
|
103.679 0.999756 15813522 4096.00
|
||||||
|
104.191 0.999780 15813916 4551.11
|
||||||
|
104.703 0.999805 15814272 5120.00
|
||||||
|
105.343 0.999829 15814676 5851.43
|
||||||
|
106.047 0.999854 15815065 6826.67
|
||||||
|
106.815 0.999878 15815438 8192.00
|
||||||
|
107.263 0.999890 15815637 9102.22
|
||||||
|
107.711 0.999902 15815814 10240.00
|
||||||
|
108.287 0.999915 15816030 11702.86
|
||||||
|
108.799 0.999927 15816206 13653.33
|
||||||
|
109.439 0.999939 15816399 16384.00
|
||||||
|
109.887 0.999945 15816500 18204.44
|
||||||
|
110.335 0.999951 15816586 20480.00
|
||||||
|
110.975 0.999957 15816687 23405.71
|
||||||
|
111.679 0.999963 15816788 27306.67
|
||||||
|
112.575 0.999969 15816881 32768.00
|
||||||
|
113.087 0.999973 15816928 36408.89
|
||||||
|
113.791 0.999976 15816974 40960.00
|
||||||
|
114.495 0.999979 15817024 46811.43
|
||||||
|
115.263 0.999982 15817069 54613.33
|
||||||
|
116.095 0.999985 15817117 65536.00
|
||||||
|
116.607 0.999986 15817143 72817.78
|
||||||
|
117.439 0.999988 15817166 81920.00
|
||||||
|
118.207 0.999989 15817190 93622.86
|
||||||
|
118.847 0.999991 15817214 109226.67
|
||||||
|
119.551 0.999992 15817239 131072.00
|
||||||
|
119.999 0.999993 15817252 145635.56
|
||||||
|
120.447 0.999994 15817265 163840.00
|
||||||
|
121.023 0.999995 15817274 187245.71
|
||||||
|
121.663 0.999995 15817287 218453.33
|
||||||
|
121.919 0.999996 15817301 262144.00
|
||||||
|
122.239 0.999997 15817305 291271.11
|
||||||
|
122.495 0.999997 15817312 327680.00
|
||||||
|
122.815 0.999997 15817316 374491.43
|
||||||
|
123.327 0.999998 15817322 436906.67
|
||||||
|
123.519 0.999998 15817328 524288.00
|
||||||
|
123.711 0.999998 15817331 582542.22
|
||||||
|
123.903 0.999998 15817334 655360.00
|
||||||
|
124.287 0.999999 15817337 748982.86
|
||||||
|
124.543 0.999999 15817340 873813.33
|
||||||
|
124.799 0.999999 15817343 1048576.00
|
||||||
|
125.055 0.999999 15817345 1165084.44
|
||||||
|
125.247 0.999999 15817347 1310720.00
|
||||||
|
125.503 0.999999 15817349 1497965.71
|
||||||
|
125.503 0.999999 15817349 1747626.67
|
||||||
|
125.631 1.000000 15817351 2097152.00
|
||||||
|
125.759 1.000000 15817352 2330168.89
|
||||||
|
125.759 1.000000 15817352 2621440.00
|
||||||
|
126.015 1.000000 15817353 2995931.43
|
||||||
|
126.079 1.000000 15817354 3495253.33
|
||||||
|
126.143 1.000000 15817355 4194304.00
|
||||||
|
126.143 1.000000 15817355 4660337.78
|
||||||
|
126.143 1.000000 15817355 5242880.00
|
||||||
|
126.335 1.000000 15817356 5991862.86
|
||||||
|
126.335 1.000000 15817356 6990506.67
|
||||||
|
126.399 1.000000 15817357 8388608.00
|
||||||
|
126.399 1.000000 15817357 9320675.55
|
||||||
|
126.399 1.000000 15817357 10485760.00
|
||||||
|
126.399 1.000000 15817357 11983725.71
|
||||||
|
126.399 1.000000 15817357 13981013.34
|
||||||
|
126.527 1.000000 15817358 16777216.00
|
||||||
|
126.527 1.000000 15817358 inf
|
||||||
|
#[Mean = 4.947, StdDeviation = 10.685]
|
||||||
|
#[Max = 126.464, Total count = 15817358]
|
||||||
|
#[Buckets = 27, SubBuckets = 2048]
|
||||||
|
----------------------------------------------------------
|
||||||
|
18980199 requests in 1.00m, 3.15GB read
|
||||||
|
Non-2xx or 3xx responses: 18980199
|
||||||
|
Requests/sec: 316342.34
|
||||||
|
Transfer/sec: 53.70MB
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 30s test @ http://127.0.0.1:8086
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 594.55us 511.59us 17.56ms 94.39%
|
||||||
|
Req/Sec 56.99k 5.13k 79.74k 85.92%
|
||||||
|
Latency Distribution
|
||||||
|
50% 521.00us
|
||||||
|
75% 686.00us
|
||||||
|
90% 0.88ms
|
||||||
|
99% 2.96ms
|
||||||
|
13614046 requests in 30.03s, 2.26GB read
|
||||||
|
Non-2xx or 3xx responses: 13614046
|
||||||
|
Requests/sec: 453399.55
|
||||||
|
Transfer/sec: 76.97MB
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
ts cpu_pct rss_kb
|
||||||
|
1779826591 581,00 7332
|
||||||
|
1779826593 567,00 22000
|
||||||
|
1779826595 560,00 23380
|
||||||
|
1779826597 598,00 23744
|
||||||
|
1779826599 552,00 23744
|
||||||
|
1779826601 571,00 24692
|
||||||
|
1779826603 575,00 24448
|
||||||
|
1779826605 559,00 25136
|
||||||
|
1779826607 584,00 25156
|
||||||
|
1779826609 591,00 25824
|
||||||
|
1779826611 600,00 25828
|
||||||
|
1779826613 592,00 25828
|
||||||
|
1779826615 600,00 25840
|
||||||
|
1779826617 598,00 25840
|
||||||
|
1779826619 594,00 26356
|
||||||
|
1779826621 383,00 26804
|
||||||
|
1779826623 418,00 28016
|
||||||
|
1779826625 395,00 27992
|
||||||
|
1779826627 396,00 27968
|
||||||
|
1779826629 399,00 28168
|
||||||
|
1779826631 407,00 27784
|
||||||
|
1779826633 409,00 28772
|
||||||
|
1779826635 408,00 28248
|
||||||
|
1779826637 406,00 28464
|
||||||
|
1779826639 416,00 28000
|
||||||
|
1779826641 395,00 28964
|
||||||
|
1779826643 420,00 28860
|
||||||
|
1779826645 381,00 28648
|
||||||
|
1779826647 381,19 28864
|
||||||
|
1779826649 339,00 28772
|
||||||
|
1779826651 337,00 29292
|
||||||
|
1779826653 398,00 29948
|
||||||
|
1779826655 354,00 29384
|
||||||
|
1779826657 415,00 30332
|
||||||
|
1779826659 427,00 29944
|
||||||
|
1779826661 379,00 29908
|
||||||
|
1779826663 391,00 30180
|
||||||
|
1779826665 349,00 29900
|
||||||
|
1779826667 372,00 29988
|
||||||
|
1779826669 409,00 29548
|
||||||
|
1779826671 368,00 30140
|
||||||
|
1779826673 373,00 29696
|
||||||
|
1779826675 419,00 30508
|
||||||
|
1779826677 367,00 30316
|
||||||
|
1779826679 342,00 31168
|
||||||
|
1779826681 401,00 29220
|
||||||
|
1779826683 409,00 29896
|
||||||
|
1779826685 392,00 29324
|
||||||
|
1779826687 404,00 30772
|
||||||
|
1779826689 405,00 29748
|
||||||
|
1779826691 393,00 30388
|
||||||
|
1779826693 428,00 30552
|
||||||
|
1779826695 360,00 30560
|
||||||
|
1779826697 398,00 31536
|
||||||
|
1779826699 390,10 31340
|
||||||
|
1779826702 409,00 31604
|
||||||
|
1779826704 395,00 31200
|
||||||
|
1779826706 415,84 30940
|
||||||
|
1779826708 423,00 30212
|
||||||
|
1779826710 417,00 30548
|
||||||
|
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"run_id": "axum-mem-s3",
|
||||||
|
"server": "axum-mem",
|
||||||
|
"scenario": "s3",
|
||||||
|
"probe_rps": 453399.55,
|
||||||
|
"target_rps": 317379,
|
||||||
|
"sustained_rps": 316342.34,
|
||||||
|
"latency": {
|
||||||
|
"p50": "1.75ms",
|
||||||
|
"p90": "9.95ms",
|
||||||
|
"p99": "60.45ms",
|
||||||
|
"p999": "93.95ms",
|
||||||
|
"max": "126.53ms"
|
||||||
|
},
|
||||||
|
"non_2xx": 18980199,
|
||||||
|
"mean_cpu_pct": "440.2",
|
||||||
|
"max_rss_kb": 31604
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
runner: launching server on cores 0-7: /home/mark/projects/urus-bench/target/release/axum-server --addr=127.0.0.1:8086 --store=memory
|
||||||
|
runner: smoke OK
|
||||||
|
runner: pre-populating store with 10000 users
|
||||||
|
runner: store now reports 100 users (list cap is 100)
|
||||||
|
runner: probe (30s closed-loop, 256 conns)
|
||||||
|
runner: probe RPS=453399.55, target (sustained)=317379
|
||||||
|
runner: warm-up (30s at -R317379)
|
||||||
|
runner: measure (60s at -R317379)
|
||||||
|
|
||||||
|
runner: DONE -> /home/mark/projects/urus-bench/results/axum-mem-s3
|
||||||
|
{
|
||||||
|
"run_id": "axum-mem-s3",
|
||||||
|
"server": "axum-mem",
|
||||||
|
"scenario": "s3",
|
||||||
|
"probe_rps": 453399.55,
|
||||||
|
"target_rps": 317379,
|
||||||
|
"sustained_rps": 316342.34,
|
||||||
|
"latency": {
|
||||||
|
"p50": "1.75ms",
|
||||||
|
"p90": "9.95ms",
|
||||||
|
"p99": "60.45ms",
|
||||||
|
"p999": "93.95ms",
|
||||||
|
"max": "126.53ms"
|
||||||
|
},
|
||||||
|
"non_2xx": 18980199,
|
||||||
|
"mean_cpu_pct": "440.2",
|
||||||
|
"max_rss_kb": 31604
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,125 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 30s test @ http://127.0.0.1:8086
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 4.250ms, rate sampling interval: 21ms
|
||||||
|
Thread calibration: mean lat.: 4.074ms, rate sampling interval: 18ms
|
||||||
|
Thread calibration: mean lat.: 3.903ms, rate sampling interval: 19ms
|
||||||
|
Thread calibration: mean lat.: 3.121ms, rate sampling interval: 14ms
|
||||||
|
Thread calibration: mean lat.: 3.525ms, rate sampling interval: 15ms
|
||||||
|
Thread calibration: mean lat.: 3.819ms, rate sampling interval: 17ms
|
||||||
|
Thread calibration: mean lat.: 3.905ms, rate sampling interval: 17ms
|
||||||
|
Thread calibration: mean lat.: 3.869ms, rate sampling interval: 18ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 4.01ms 7.59ms 107.97ms 92.31%
|
||||||
|
Req/Sec 40.94k 5.89k 102.94k 82.22%
|
||||||
|
9496084 requests in 30.00s, 1.57GB read
|
||||||
|
Non-2xx or 3xx responses: 9496084
|
||||||
|
Requests/sec: 316548.36
|
||||||
|
Transfer/sec: 53.74MB
|
||||||
@@ -0,0 +1,264 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 1m test @ http://127.0.0.1:8088
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 7.146ms, rate sampling interval: 30ms
|
||||||
|
Thread calibration: mean lat.: 5.310ms, rate sampling interval: 24ms
|
||||||
|
Thread calibration: mean lat.: 4.563ms, rate sampling interval: 23ms
|
||||||
|
Thread calibration: mean lat.: 4.274ms, rate sampling interval: 20ms
|
||||||
|
Thread calibration: mean lat.: 6.444ms, rate sampling interval: 37ms
|
||||||
|
Thread calibration: mean lat.: 3.653ms, rate sampling interval: 18ms
|
||||||
|
Thread calibration: mean lat.: 4.760ms, rate sampling interval: 24ms
|
||||||
|
Thread calibration: mean lat.: 5.317ms, rate sampling interval: 24ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 4.72ms 10.37ms 141.44ms 93.18%
|
||||||
|
Req/Sec 41.07k 5.30k 101.06k 82.85%
|
||||||
|
Latency Distribution (HdrHistogram - Recorded Latency)
|
||||||
|
50.000% 1.71ms
|
||||||
|
75.000% 3.51ms
|
||||||
|
90.000% 9.89ms
|
||||||
|
99.000% 56.13ms
|
||||||
|
99.900% 109.69ms
|
||||||
|
99.990% 129.92ms
|
||||||
|
99.999% 138.37ms
|
||||||
|
100.000% 141.57ms
|
||||||
|
|
||||||
|
Detailed Percentile spectrum:
|
||||||
|
Value Percentile TotalCount 1/(1-Percentile)
|
||||||
|
|
||||||
|
0.018 0.000000 1 1.00
|
||||||
|
0.611 0.100000 1604254 1.11
|
||||||
|
0.883 0.200000 3205872 1.25
|
||||||
|
1.139 0.300000 4804727 1.43
|
||||||
|
1.403 0.400000 6404466 1.67
|
||||||
|
1.711 0.500000 8004016 2.00
|
||||||
|
1.900 0.550000 8805635 2.22
|
||||||
|
2.129 0.600000 9607397 2.50
|
||||||
|
2.433 0.650000 10405994 2.86
|
||||||
|
2.887 0.700000 11207488 3.33
|
||||||
|
3.513 0.750000 12006881 4.00
|
||||||
|
3.897 0.775000 12407649 4.44
|
||||||
|
4.351 0.800000 12808826 5.00
|
||||||
|
4.943 0.825000 13207093 5.71
|
||||||
|
5.867 0.850000 13606890 6.67
|
||||||
|
7.447 0.875000 14007473 8.00
|
||||||
|
8.535 0.887500 14207059 8.89
|
||||||
|
9.887 0.900000 14406931 10.00
|
||||||
|
11.575 0.912500 14607362 11.43
|
||||||
|
13.687 0.925000 14807420 13.33
|
||||||
|
16.463 0.937500 15007703 16.00
|
||||||
|
18.191 0.943750 15107755 17.78
|
||||||
|
20.175 0.950000 15207622 20.00
|
||||||
|
22.511 0.956250 15307756 22.86
|
||||||
|
25.375 0.962500 15407545 26.67
|
||||||
|
29.055 0.968750 15507749 32.00
|
||||||
|
31.295 0.971875 15557678 35.56
|
||||||
|
34.015 0.975000 15607605 40.00
|
||||||
|
37.407 0.978125 15657589 45.71
|
||||||
|
41.535 0.981250 15707673 53.33
|
||||||
|
46.143 0.984375 15757648 64.00
|
||||||
|
48.639 0.985938 15782610 71.11
|
||||||
|
51.263 0.987500 15807710 80.00
|
||||||
|
54.111 0.989062 15832731 91.43
|
||||||
|
57.599 0.990625 15857605 106.67
|
||||||
|
62.015 0.992188 15882643 128.00
|
||||||
|
64.607 0.992969 15895263 142.22
|
||||||
|
67.391 0.993750 15907905 160.00
|
||||||
|
70.399 0.994531 15920323 182.86
|
||||||
|
74.175 0.995313 15932694 213.33
|
||||||
|
78.975 0.996094 15945141 256.00
|
||||||
|
81.855 0.996484 15951444 284.44
|
||||||
|
84.927 0.996875 15957744 320.00
|
||||||
|
88.255 0.997266 15963912 365.71
|
||||||
|
91.583 0.997656 15970204 426.67
|
||||||
|
95.679 0.998047 15976462 512.00
|
||||||
|
97.983 0.998242 15979596 568.89
|
||||||
|
100.543 0.998437 15982658 640.00
|
||||||
|
103.231 0.998633 15985830 731.43
|
||||||
|
106.175 0.998828 15988947 853.33
|
||||||
|
110.143 0.999023 15992037 1024.00
|
||||||
|
112.383 0.999121 15993643 1137.78
|
||||||
|
114.495 0.999219 15995168 1280.00
|
||||||
|
116.543 0.999316 15996772 1462.86
|
||||||
|
118.399 0.999414 15998307 1706.67
|
||||||
|
120.447 0.999512 15999893 2048.00
|
||||||
|
121.279 0.999561 16000643 2275.56
|
||||||
|
122.239 0.999609 16001458 2560.00
|
||||||
|
123.263 0.999658 16002248 2925.71
|
||||||
|
124.287 0.999707 16002991 3413.33
|
||||||
|
125.503 0.999756 16003781 4096.00
|
||||||
|
126.143 0.999780 16004185 4551.11
|
||||||
|
126.655 0.999805 16004568 5120.00
|
||||||
|
127.359 0.999829 16004942 5851.43
|
||||||
|
128.127 0.999854 16005345 6826.67
|
||||||
|
128.959 0.999878 16005744 8192.00
|
||||||
|
129.407 0.999890 16005927 9102.22
|
||||||
|
130.047 0.999902 16006129 10240.00
|
||||||
|
130.687 0.999915 16006314 11702.86
|
||||||
|
131.455 0.999927 16006502 13653.33
|
||||||
|
132.351 0.999939 16006716 16384.00
|
||||||
|
132.735 0.999945 16006800 18204.44
|
||||||
|
133.247 0.999951 16006899 20480.00
|
||||||
|
133.759 0.999957 16006990 23405.71
|
||||||
|
134.527 0.999963 16007096 27306.67
|
||||||
|
135.423 0.999969 16007194 32768.00
|
||||||
|
135.935 0.999973 16007240 36408.89
|
||||||
|
136.447 0.999976 16007288 40960.00
|
||||||
|
136.959 0.999979 16007345 46811.43
|
||||||
|
137.215 0.999982 16007384 54613.33
|
||||||
|
137.599 0.999985 16007430 65536.00
|
||||||
|
137.855 0.999986 16007458 72817.78
|
||||||
|
138.111 0.999988 16007487 81920.00
|
||||||
|
138.239 0.999989 16007504 93622.86
|
||||||
|
138.495 0.999991 16007538 109226.67
|
||||||
|
138.623 0.999992 16007549 131072.00
|
||||||
|
138.751 0.999993 16007561 145635.56
|
||||||
|
138.879 0.999994 16007579 163840.00
|
||||||
|
139.007 0.999995 16007586 187245.71
|
||||||
|
139.263 0.999995 16007601 218453.33
|
||||||
|
139.519 0.999996 16007611 262144.00
|
||||||
|
139.647 0.999997 16007618 291271.11
|
||||||
|
139.903 0.999997 16007626 327680.00
|
||||||
|
140.031 0.999997 16007631 374491.43
|
||||||
|
140.159 0.999998 16007634 436906.67
|
||||||
|
140.287 0.999998 16007643 524288.00
|
||||||
|
140.287 0.999998 16007643 582542.22
|
||||||
|
140.415 0.999998 16007648 655360.00
|
||||||
|
140.415 0.999999 16007648 748982.86
|
||||||
|
140.543 0.999999 16007652 873813.33
|
||||||
|
140.671 0.999999 16007654 1048576.00
|
||||||
|
140.799 0.999999 16007657 1165084.44
|
||||||
|
140.799 0.999999 16007657 1310720.00
|
||||||
|
140.927 0.999999 16007661 1497965.71
|
||||||
|
140.927 0.999999 16007661 1747626.67
|
||||||
|
141.055 1.000000 16007663 2097152.00
|
||||||
|
141.055 1.000000 16007663 2330168.89
|
||||||
|
141.055 1.000000 16007663 2621440.00
|
||||||
|
141.183 1.000000 16007667 2995931.43
|
||||||
|
141.183 1.000000 16007667 3495253.33
|
||||||
|
141.183 1.000000 16007667 4194304.00
|
||||||
|
141.183 1.000000 16007667 4660337.78
|
||||||
|
141.183 1.000000 16007667 5242880.00
|
||||||
|
141.183 1.000000 16007667 5991862.86
|
||||||
|
141.183 1.000000 16007667 6990506.67
|
||||||
|
141.311 1.000000 16007668 8388608.00
|
||||||
|
141.311 1.000000 16007668 9320675.55
|
||||||
|
141.311 1.000000 16007668 10485760.00
|
||||||
|
141.311 1.000000 16007668 11983725.71
|
||||||
|
141.311 1.000000 16007668 13981013.34
|
||||||
|
141.567 1.000000 16007669 16777216.00
|
||||||
|
141.567 1.000000 16007669 inf
|
||||||
|
#[Mean = 4.720, StdDeviation = 10.366]
|
||||||
|
#[Max = 141.440, Total count = 16007669]
|
||||||
|
#[Buckets = 27, SubBuckets = 2048]
|
||||||
|
----------------------------------------------------------
|
||||||
|
19208634 requests in 1.00m, 3.18GB read
|
||||||
|
Non-2xx or 3xx responses: 19208634
|
||||||
|
Requests/sec: 320149.67
|
||||||
|
Transfer/sec: 54.35MB
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 30s test @ http://127.0.0.1:8088
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 584.49us 479.73us 12.43ms 93.73%
|
||||||
|
Req/Sec 57.68k 5.09k 81.48k 83.00%
|
||||||
|
Latency Distribution
|
||||||
|
50% 514.00us
|
||||||
|
75% 676.00us
|
||||||
|
90% 0.87ms
|
||||||
|
99% 2.87ms
|
||||||
|
13780918 requests in 30.03s, 2.28GB read
|
||||||
|
Non-2xx or 3xx responses: 13780918
|
||||||
|
Requests/sec: 458843.73
|
||||||
|
Transfer/sec: 77.89MB
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
ts cpu_pct rss_kb
|
||||||
|
1779826865 566,00 7988
|
||||||
|
1779826867 435,00 22776
|
||||||
|
1779826869 522,00 25212
|
||||||
|
1779826871 567,00 25708
|
||||||
|
1779826873 598,00 25852
|
||||||
|
1779826875 582,00 25868
|
||||||
|
1779826877 583,00 25852
|
||||||
|
1779826879 584,00 25880
|
||||||
|
1779826881 584,00 25840
|
||||||
|
1779826883 597,00 25908
|
||||||
|
1779826885 594,00 25892
|
||||||
|
1779826887 579,00 25848
|
||||||
|
1779826889 564,00 25852
|
||||||
|
1779826891 586,00 25872
|
||||||
|
1779826893 557,00 25904
|
||||||
|
1779826895 337,00 26312
|
||||||
|
1779826897 406,00 27408
|
||||||
|
1779826899 428,00 27472
|
||||||
|
1779826901 408,00 27816
|
||||||
|
1779826903 423,00 27900
|
||||||
|
1779826905 337,00 27980
|
||||||
|
1779826907 420,00 28028
|
||||||
|
1779826909 414,00 27968
|
||||||
|
1779826911 370,00 28144
|
||||||
|
1779826913 388,00 28252
|
||||||
|
1779826915 418,00 28564
|
||||||
|
1779826917 408,00 28688
|
||||||
|
1779826919 419,00 28924
|
||||||
|
1779826921 393,00 28968
|
||||||
|
1779826923 340,00 29084
|
||||||
|
1779826925 364,00 29260
|
||||||
|
1779826927 404,00 29488
|
||||||
|
1779826929 382,00 29620
|
||||||
|
1779826931 415,00 29660
|
||||||
|
1779826933 406,00 29836
|
||||||
|
1779826935 414,00 29836
|
||||||
|
1779826937 421,00 29880
|
||||||
|
1779826939 405,00 29900
|
||||||
|
1779826941 420,00 29992
|
||||||
|
1779826943 411,00 30004
|
||||||
|
1779826945 400,00 30008
|
||||||
|
1779826947 385,00 30112
|
||||||
|
1779826949 443,00 30136
|
||||||
|
1779826951 423,00 30136
|
||||||
|
1779826953 408,00 30328
|
||||||
|
1779826955 431,00 30104
|
||||||
|
1779826957 429,00 30076
|
||||||
|
1779826959 394,00 30076
|
||||||
|
1779826961 437,00 30080
|
||||||
|
1779826963 432,00 30120
|
||||||
|
1779826965 345,00 30080
|
||||||
|
1779826967 391,00 30260
|
||||||
|
1779826969 429,00 30196
|
||||||
|
1779826971 404,00 30196
|
||||||
|
1779826973 384,00 30788
|
||||||
|
1779826975 366,00 30600
|
||||||
|
1779826977 382,00 30156
|
||||||
|
1779826979 415,00 30152
|
||||||
|
1779826981 389,00 30148
|
||||||
|
1779826983 408,00 30148
|
||||||
|
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"run_id": "axum-sqlite-s4",
|
||||||
|
"server": "axum-sqlite",
|
||||||
|
"scenario": "s4",
|
||||||
|
"probe_rps": 458843.73,
|
||||||
|
"target_rps": 321190,
|
||||||
|
"sustained_rps": 320149.67,
|
||||||
|
"latency": {
|
||||||
|
"p50": "1.71ms",
|
||||||
|
"p90": "9.89ms",
|
||||||
|
"p99": "56.13ms",
|
||||||
|
"p999": "109.69ms",
|
||||||
|
"max": "141.57ms"
|
||||||
|
},
|
||||||
|
"non_2xx": 19208634,
|
||||||
|
"mean_cpu_pct": "442.4",
|
||||||
|
"max_rss_kb": 30788
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
runner: launching server on cores 0-7: /home/mark/projects/urus-bench/target/release/axum-server --addr=127.0.0.1:8088 --store=sqlite --db-path=/tmp/axum-bench-axum-sqlite-s4.sqlite
|
||||||
|
runner: smoke OK
|
||||||
|
runner: pre-populating store with 10000 users
|
||||||
|
runner: store now reports 100 users (list cap is 100)
|
||||||
|
runner: probe (30s closed-loop, 256 conns)
|
||||||
|
runner: probe RPS=458843.73, target (sustained)=321190
|
||||||
|
runner: warm-up (30s at -R321190)
|
||||||
|
runner: measure (60s at -R321190)
|
||||||
|
|
||||||
|
runner: DONE -> /home/mark/projects/urus-bench/results/axum-sqlite-s4
|
||||||
|
{
|
||||||
|
"run_id": "axum-sqlite-s4",
|
||||||
|
"server": "axum-sqlite",
|
||||||
|
"scenario": "s4",
|
||||||
|
"probe_rps": 458843.73,
|
||||||
|
"target_rps": 321190,
|
||||||
|
"sustained_rps": 320149.67,
|
||||||
|
"latency": {
|
||||||
|
"p50": "1.71ms",
|
||||||
|
"p90": "9.89ms",
|
||||||
|
"p99": "56.13ms",
|
||||||
|
"p999": "109.69ms",
|
||||||
|
"max": "141.57ms"
|
||||||
|
},
|
||||||
|
"non_2xx": 19208634,
|
||||||
|
"mean_cpu_pct": "442.4",
|
||||||
|
"max_rss_kb": 30788
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,125 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 30s test @ http://127.0.0.1:8088
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 2.850ms, rate sampling interval: 11ms
|
||||||
|
Thread calibration: mean lat.: 2.608ms, rate sampling interval: 11ms
|
||||||
|
Thread calibration: mean lat.: 4.630ms, rate sampling interval: 19ms
|
||||||
|
Thread calibration: mean lat.: 4.266ms, rate sampling interval: 18ms
|
||||||
|
Thread calibration: mean lat.: 3.405ms, rate sampling interval: 11ms
|
||||||
|
Thread calibration: mean lat.: 3.628ms, rate sampling interval: 15ms
|
||||||
|
Thread calibration: mean lat.: 4.440ms, rate sampling interval: 15ms
|
||||||
|
Thread calibration: mean lat.: 3.436ms, rate sampling interval: 14ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 5.05ms 8.68ms 89.34ms 89.82%
|
||||||
|
Req/Sec 41.80k 7.73k 98.30k 79.39%
|
||||||
|
9573019 requests in 30.00s, 1.59GB read
|
||||||
|
Non-2xx or 3xx responses: 9573019
|
||||||
|
Requests/sec: 319112.60
|
||||||
|
Transfer/sec: 54.17MB
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# urus-bench summary
|
||||||
|
|
||||||
|
- **Batch:** `20260526-220625`
|
||||||
|
- **Host:** `nixosmark` (`Linux 6.12.90 x86_64`)
|
||||||
|
- **CPUs:** `24 cores`
|
||||||
|
- **Model:** AMD Ryzen 9 5900X 12-Core Processor
|
||||||
|
- **Started:** `2026-05-26T22:06:26+02:00`
|
||||||
|
- **Elapsed:** 999s
|
||||||
|
- **Successful runs:** 8 / 8
|
||||||
|
|
||||||
|
Timings: probe=30s, warmup=30s, measure=60s, sat_ratio=0.70
|
||||||
|
|
||||||
|
## Sustained RPS (wrk2 @ 0.70 of saturation)
|
||||||
|
|
||||||
|
| | axum-mem | axum-sqlite | urus-mem | urus-sqlite |
|
||||||
|
|------------|----------------|----------------|----------------|----------------|
|
||||||
|
| s1 | 288330 | — | 54641 | — |
|
||||||
|
| s2 | 315596 | — | 53139 | — |
|
||||||
|
| s3 | 316342 | — | 53616 | — |
|
||||||
|
| s4 | — | 320150 | — | 52590 |
|
||||||
|
|
||||||
|
## p99 latency (at target rate)
|
||||||
|
|
||||||
|
| | axum-mem | axum-sqlite | urus-mem | urus-sqlite |
|
||||||
|
|------------|----------------|----------------|----------------|----------------|
|
||||||
|
| s1 | 11.64ms | — | 2.70ms | — |
|
||||||
|
| s2 | 49.66ms | — | 2.62ms | — |
|
||||||
|
| s3 | 60.45ms | — | 2.67ms | — |
|
||||||
|
| s4 | — | 56.13ms | — | 2.53ms |
|
||||||
|
|
||||||
|
## Spec checks (urus vs axum)
|
||||||
|
|
||||||
|
| Scenario | urus RPS | axum RPS | urus/axum | within 2× of axum |
|
||||||
|
|----------|----------|----------|-----------|-------------------|
|
||||||
|
| s1 | 54640 | 288329 | 0.19 | ❌ |
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
Running 1m test @ http://127.0.0.1:8081
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 1.312ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.311ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.313ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.313ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.333ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.312ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.332ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.337ms, rate sampling interval: 10ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 1.25ms 566.48us 10.59ms 67.37%
|
||||||
|
Req/Sec 7.21k 466.91 10.11k 71.34%
|
||||||
|
Latency Distribution (HdrHistogram - Recorded Latency)
|
||||||
|
50.000% 1.21ms
|
||||||
|
75.000% 1.62ms
|
||||||
|
90.000% 2.01ms
|
||||||
|
99.000% 2.70ms
|
||||||
|
99.900% 3.69ms
|
||||||
|
99.990% 4.88ms
|
||||||
|
99.999% 6.14ms
|
||||||
|
100.000% 10.60ms
|
||||||
|
|
||||||
|
Detailed Percentile spectrum:
|
||||||
|
Value Percentile TotalCount 1/(1-Percentile)
|
||||||
|
|
||||||
|
0.053 0.000000 1 1.00
|
||||||
|
0.551 0.100000 273118 1.11
|
||||||
|
0.746 0.200000 546571 1.25
|
||||||
|
0.907 0.300000 819410 1.43
|
||||||
|
1.057 0.400000 1092406 1.67
|
||||||
|
1.206 0.500000 1364829 2.00
|
||||||
|
1.282 0.550000 1500690 2.22
|
||||||
|
1.360 0.600000 1636592 2.50
|
||||||
|
1.441 0.650000 1772851 2.86
|
||||||
|
1.527 0.700000 1909120 3.33
|
||||||
|
1.620 0.750000 2045839 4.00
|
||||||
|
1.670 0.775000 2113401 4.44
|
||||||
|
1.724 0.800000 2182229 5.00
|
||||||
|
1.782 0.825000 2249791 5.71
|
||||||
|
1.847 0.850000 2318374 6.67
|
||||||
|
1.920 0.875000 2386250 8.00
|
||||||
|
1.961 0.887500 2420569 8.89
|
||||||
|
2.005 0.900000 2454311 10.00
|
||||||
|
2.055 0.912500 2489270 11.43
|
||||||
|
2.109 0.925000 2522491 13.33
|
||||||
|
2.173 0.937500 2557071 16.00
|
||||||
|
2.209 0.943750 2574199 17.78
|
||||||
|
2.247 0.950000 2590880 20.00
|
||||||
|
2.289 0.956250 2607930 22.86
|
||||||
|
2.337 0.962500 2625211 26.67
|
||||||
|
2.391 0.968750 2642014 32.00
|
||||||
|
2.421 0.971875 2650365 35.56
|
||||||
|
2.455 0.975000 2658911 40.00
|
||||||
|
2.493 0.978125 2667459 45.71
|
||||||
|
2.535 0.981250 2675922 53.33
|
||||||
|
2.583 0.984375 2684257 64.00
|
||||||
|
2.613 0.985938 2688652 71.11
|
||||||
|
2.643 0.987500 2692723 80.00
|
||||||
|
2.679 0.989062 2697098 91.43
|
||||||
|
2.719 0.990625 2701254 106.67
|
||||||
|
2.769 0.992188 2705534 128.00
|
||||||
|
2.799 0.992969 2707724 142.22
|
||||||
|
2.831 0.993750 2709813 160.00
|
||||||
|
2.869 0.994531 2711896 182.86
|
||||||
|
2.915 0.995313 2714025 213.33
|
||||||
|
2.973 0.996094 2716145 256.00
|
||||||
|
3.009 0.996484 2717235 284.44
|
||||||
|
3.051 0.996875 2718286 320.00
|
||||||
|
3.099 0.997266 2719327 365.71
|
||||||
|
3.169 0.997656 2720414 426.67
|
||||||
|
3.259 0.998047 2721459 512.00
|
||||||
|
3.317 0.998242 2722008 568.89
|
||||||
|
3.391 0.998437 2722526 640.00
|
||||||
|
3.487 0.998633 2723066 731.43
|
||||||
|
3.593 0.998828 2723600 853.33
|
||||||
|
3.709 0.999023 2724125 1024.00
|
||||||
|
3.777 0.999121 2724388 1137.78
|
||||||
|
3.853 0.999219 2724658 1280.00
|
||||||
|
3.933 0.999316 2724919 1462.86
|
||||||
|
4.025 0.999414 2725186 1706.67
|
||||||
|
4.127 0.999512 2725456 2048.00
|
||||||
|
4.183 0.999561 2725587 2275.56
|
||||||
|
4.251 0.999609 2725729 2560.00
|
||||||
|
4.315 0.999658 2725853 2925.71
|
||||||
|
4.399 0.999707 2725993 3413.33
|
||||||
|
4.487 0.999756 2726119 4096.00
|
||||||
|
4.527 0.999780 2726188 4551.11
|
||||||
|
4.583 0.999805 2726254 5120.00
|
||||||
|
4.639 0.999829 2726321 5851.43
|
||||||
|
4.707 0.999854 2726387 6826.67
|
||||||
|
4.787 0.999878 2726451 8192.00
|
||||||
|
4.851 0.999890 2726487 9102.22
|
||||||
|
4.895 0.999902 2726518 10240.00
|
||||||
|
4.967 0.999915 2726550 11702.86
|
||||||
|
5.063 0.999927 2726584 13653.33
|
||||||
|
5.131 0.999939 2726618 16384.00
|
||||||
|
5.175 0.999945 2726637 18204.44
|
||||||
|
5.203 0.999951 2726650 20480.00
|
||||||
|
5.275 0.999957 2726667 23405.71
|
||||||
|
5.359 0.999963 2726684 27306.67
|
||||||
|
5.419 0.999969 2726700 32768.00
|
||||||
|
5.475 0.999973 2726710 36408.89
|
||||||
|
5.511 0.999976 2726718 40960.00
|
||||||
|
5.531 0.999979 2726725 46811.43
|
||||||
|
5.567 0.999982 2726735 54613.33
|
||||||
|
5.711 0.999985 2726742 65536.00
|
||||||
|
5.815 0.999986 2726746 72817.78
|
||||||
|
6.019 0.999988 2726750 81920.00
|
||||||
|
6.131 0.999989 2726754 93622.86
|
||||||
|
6.183 0.999991 2726759 109226.67
|
||||||
|
6.211 0.999992 2726763 131072.00
|
||||||
|
6.331 0.999993 2726766 145635.56
|
||||||
|
6.351 0.999994 2726767 163840.00
|
||||||
|
6.375 0.999995 2726770 187245.71
|
||||||
|
6.479 0.999995 2726771 218453.33
|
||||||
|
6.539 0.999996 2726774 262144.00
|
||||||
|
6.539 0.999997 2726774 291271.11
|
||||||
|
6.543 0.999997 2726775 327680.00
|
||||||
|
6.631 0.999997 2726776 374491.43
|
||||||
|
6.647 0.999998 2726777 436906.67
|
||||||
|
6.655 0.999998 2726778 524288.00
|
||||||
|
6.855 0.999998 2726779 582542.22
|
||||||
|
6.855 0.999998 2726779 655360.00
|
||||||
|
9.807 0.999999 2726780 748982.86
|
||||||
|
9.807 0.999999 2726780 873813.33
|
||||||
|
9.839 0.999999 2726781 1048576.00
|
||||||
|
9.839 0.999999 2726781 1165084.44
|
||||||
|
9.839 0.999999 2726781 1310720.00
|
||||||
|
10.223 0.999999 2726782 1497965.71
|
||||||
|
10.223 0.999999 2726782 1747626.67
|
||||||
|
10.223 1.000000 2726782 2097152.00
|
||||||
|
10.223 1.000000 2726782 2330168.89
|
||||||
|
10.223 1.000000 2726782 2621440.00
|
||||||
|
10.599 1.000000 2726783 2995931.43
|
||||||
|
10.599 1.000000 2726783 inf
|
||||||
|
#[Mean = 1.252, StdDeviation = 0.566]
|
||||||
|
#[Max = 10.592, Total count = 2726783]
|
||||||
|
#[Buckets = 27, SubBuckets = 2048]
|
||||||
|
----------------------------------------------------------
|
||||||
|
3278445 requests in 1.00m, 372.06MB read
|
||||||
|
Requests/sec: 54640.68
|
||||||
|
Transfer/sec: 6.20MB
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
Running 30s test @ http://127.0.0.1:8081
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 3.27ms 408.65us 14.31ms 84.94%
|
||||||
|
Req/Sec 9.84k 526.29 17.26k 81.03%
|
||||||
|
Latency Distribution
|
||||||
|
50% 3.17ms
|
||||||
|
75% 3.35ms
|
||||||
|
90% 3.76ms
|
||||||
|
99% 4.61ms
|
||||||
|
2352589 requests in 30.10s, 266.99MB read
|
||||||
|
Requests/sec: 78159.14
|
||||||
|
Transfer/sec: 8.87MB
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
ts cpu_pct rss_kb
|
||||||
|
1779825986 283,00 8116
|
||||||
|
1779825988 285,00 16916
|
||||||
|
1779825990 286,00 17096
|
||||||
|
1779825992 287,00 17100
|
||||||
|
1779825994 292,00 17120
|
||||||
|
1779825996 283,00 17180
|
||||||
|
1779825998 281,00 17188
|
||||||
|
1779826000 283,00 17188
|
||||||
|
1779826002 283,00 17188
|
||||||
|
1779826004 286,00 17208
|
||||||
|
1779826006 281,00 17208
|
||||||
|
1779826008 285,00 17212
|
||||||
|
1779826010 285,00 17228
|
||||||
|
1779826012 283,00 17228
|
||||||
|
1779826014 292,00 17232
|
||||||
|
1779826016 186,00 15440
|
||||||
|
1779826018 234,00 17340
|
||||||
|
1779826020 216,00 17372
|
||||||
|
1779826022 224,00 17396
|
||||||
|
1779826024 226,00 17404
|
||||||
|
1779826026 220,00 17480
|
||||||
|
1779826028 212,00 17492
|
||||||
|
1779826030 224,00 17492
|
||||||
|
1779826032 181,00 17492
|
||||||
|
1779826034 233,00 17492
|
||||||
|
1779826036 231,00 17492
|
||||||
|
1779826038 234,00 17492
|
||||||
|
1779826040 221,00 17492
|
||||||
|
1779826042 214,00 17492
|
||||||
|
1779826044 204,00 17492
|
||||||
|
1779826046 177,00 17228
|
||||||
|
1779826048 223,00 17504
|
||||||
|
1779826050 226,00 17504
|
||||||
|
1779826052 217,00 17504
|
||||||
|
1779826054 227,00 17504
|
||||||
|
1779826056 224,00 17504
|
||||||
|
1779826058 220,00 17504
|
||||||
|
1779826060 226,00 17504
|
||||||
|
1779826062 229,00 17504
|
||||||
|
1779826064 217,00 17504
|
||||||
|
1779826066 210,00 17504
|
||||||
|
1779826068 225,00 17504
|
||||||
|
1779826070 228,00 17504
|
||||||
|
1779826072 196,00 17504
|
||||||
|
1779826074 213,00 17504
|
||||||
|
1779826076 217,00 17504
|
||||||
|
1779826078 207,00 17504
|
||||||
|
1779826080 208,00 17504
|
||||||
|
1779826082 217,00 17504
|
||||||
|
1779826084 222,00 17504
|
||||||
|
1779826086 211,00 17504
|
||||||
|
1779826088 228,00 17504
|
||||||
|
1779826090 214,00 17504
|
||||||
|
1779826092 221,00 17504
|
||||||
|
1779826094 230,00 17504
|
||||||
|
1779826096 227,00 17504
|
||||||
|
1779826098 208,00 17504
|
||||||
|
1779826100 227,00 17504
|
||||||
|
1779826102 227,00 17504
|
||||||
|
1779826104 229,00 17504
|
||||||
|
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"run_id": "urus-mem-s1",
|
||||||
|
"server": "urus-mem",
|
||||||
|
"scenario": "s1",
|
||||||
|
"probe_rps": 78159.14,
|
||||||
|
"target_rps": 54711,
|
||||||
|
"sustained_rps": 54640.68,
|
||||||
|
"latency": {
|
||||||
|
"p50": "1.21ms",
|
||||||
|
"p90": "2.01ms",
|
||||||
|
"p99": "2.70ms",
|
||||||
|
"p999": "3.69ms",
|
||||||
|
"max": "10.60ms"
|
||||||
|
},
|
||||||
|
"non_2xx": 0,
|
||||||
|
"mean_cpu_pct": "234.8",
|
||||||
|
"max_rss_kb": 17504
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
runner: launching server on cores 0-7: /home/mark/projects/urus-bench/target/release/urus-server --addr=127.0.0.1:8081 --store=memory
|
||||||
|
runner: smoke OK
|
||||||
|
runner: probe (30s closed-loop, 256 conns)
|
||||||
|
runner: probe RPS=78159.14, target (sustained)=54711
|
||||||
|
runner: warm-up (30s at -R54711)
|
||||||
|
runner: measure (60s at -R54711)
|
||||||
|
|
||||||
|
runner: DONE -> /home/mark/projects/urus-bench/results/urus-mem-s1
|
||||||
|
{
|
||||||
|
"run_id": "urus-mem-s1",
|
||||||
|
"server": "urus-mem",
|
||||||
|
"scenario": "s1",
|
||||||
|
"probe_rps": 78159.14,
|
||||||
|
"target_rps": 54711,
|
||||||
|
"sustained_rps": 54640.68,
|
||||||
|
"latency": {
|
||||||
|
"p50": "1.21ms",
|
||||||
|
"p90": "2.01ms",
|
||||||
|
"p99": "2.70ms",
|
||||||
|
"p999": "3.69ms",
|
||||||
|
"max": "10.60ms"
|
||||||
|
},
|
||||||
|
"non_2xx": 0,
|
||||||
|
"mean_cpu_pct": "234.8",
|
||||||
|
"max_rss_kb": 17504
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
urus-server: store=Memory addr=127.0.0.1:8081 auth=true
|
||||||
|
urus: listening on 127.0.0.1:8081
|
||||||
|
urus: listener 0 starting
|
||||||
|
urus: listener 1 starting
|
||||||
|
urus: listener 2 starting
|
||||||
|
urus: listener 3 starting
|
||||||
|
urus: listener 4 starting
|
||||||
|
urus: listener 5 starting
|
||||||
|
urus: listener 6 starting
|
||||||
|
urus: listener 7 starting
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
Running 30s test @ http://127.0.0.1:8081
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 1.217ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.221ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.195ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.225ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.215ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.227ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.219ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.225ms, rate sampling interval: 10ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 1.23ms 557.40us 6.47ms 67.54%
|
||||||
|
Req/Sec 7.21k 494.29 10.22k 71.93%
|
||||||
|
1630772 requests in 30.00s, 185.07MB read
|
||||||
|
Requests/sec: 54358.72
|
||||||
|
Transfer/sec: 6.17MB
|
||||||
@@ -0,0 +1,252 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 1m test @ http://127.0.0.1:8082
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 1.253ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.273ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.247ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.250ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.243ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.262ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.232ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.274ms, rate sampling interval: 10ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 1.22ms 552.44us 10.26ms 67.28%
|
||||||
|
Req/Sec 7.01k 455.06 10.33k 71.01%
|
||||||
|
Latency Distribution (HdrHistogram - Recorded Latency)
|
||||||
|
50.000% 1.17ms
|
||||||
|
75.000% 1.58ms
|
||||||
|
90.000% 1.94ms
|
||||||
|
99.000% 2.62ms
|
||||||
|
99.900% 3.62ms
|
||||||
|
99.990% 5.11ms
|
||||||
|
99.999% 6.48ms
|
||||||
|
100.000% 10.27ms
|
||||||
|
|
||||||
|
Detailed Percentile spectrum:
|
||||||
|
Value Percentile TotalCount 1/(1-Percentile)
|
||||||
|
|
||||||
|
0.049 0.000000 1 1.00
|
||||||
|
0.526 0.100000 265507 1.11
|
||||||
|
0.718 0.200000 530636 1.25
|
||||||
|
0.879 0.300000 797202 1.43
|
||||||
|
1.028 0.400000 1062069 1.67
|
||||||
|
1.175 0.500000 1326321 2.00
|
||||||
|
1.250 0.550000 1458991 2.22
|
||||||
|
1.327 0.600000 1592441 2.50
|
||||||
|
1.405 0.650000 1723863 2.86
|
||||||
|
1.488 0.700000 1856707 3.33
|
||||||
|
1.577 0.750000 1989235 4.00
|
||||||
|
1.625 0.775000 2055527 4.44
|
||||||
|
1.676 0.800000 2122080 5.00
|
||||||
|
1.731 0.825000 2187859 5.71
|
||||||
|
1.792 0.850000 2254340 6.67
|
||||||
|
1.861 0.875000 2320732 8.00
|
||||||
|
1.899 0.887500 2353724 8.89
|
||||||
|
1.941 0.900000 2387144 10.00
|
||||||
|
1.987 0.912500 2420026 11.43
|
||||||
|
2.038 0.925000 2453246 13.33
|
||||||
|
2.097 0.937500 2486524 16.00
|
||||||
|
2.131 0.943750 2503424 17.78
|
||||||
|
2.167 0.950000 2519657 20.00
|
||||||
|
2.209 0.956250 2536563 22.86
|
||||||
|
2.255 0.962500 2552964 26.67
|
||||||
|
2.307 0.968750 2569088 32.00
|
||||||
|
2.339 0.971875 2577770 35.56
|
||||||
|
2.371 0.975000 2585860 40.00
|
||||||
|
2.409 0.978125 2594217 45.71
|
||||||
|
2.451 0.981250 2602209 53.33
|
||||||
|
2.501 0.984375 2610511 64.00
|
||||||
|
2.531 0.985938 2614746 71.11
|
||||||
|
2.563 0.987500 2618837 80.00
|
||||||
|
2.599 0.989062 2622929 91.43
|
||||||
|
2.641 0.990625 2627029 106.67
|
||||||
|
2.693 0.992188 2631191 128.00
|
||||||
|
2.723 0.992969 2633289 142.22
|
||||||
|
2.757 0.993750 2635352 160.00
|
||||||
|
2.797 0.994531 2637395 182.86
|
||||||
|
2.847 0.995313 2639527 213.33
|
||||||
|
2.907 0.996094 2641575 256.00
|
||||||
|
2.941 0.996484 2642588 284.44
|
||||||
|
2.981 0.996875 2643618 320.00
|
||||||
|
3.033 0.997266 2644663 365.71
|
||||||
|
3.093 0.997656 2645696 426.67
|
||||||
|
3.179 0.998047 2646730 512.00
|
||||||
|
3.229 0.998242 2647236 568.89
|
||||||
|
3.293 0.998437 2647751 640.00
|
||||||
|
3.377 0.998633 2648273 731.43
|
||||||
|
3.485 0.998828 2648782 853.33
|
||||||
|
3.637 0.999023 2649301 1024.00
|
||||||
|
3.729 0.999121 2649565 1137.78
|
||||||
|
3.837 0.999219 2649821 1280.00
|
||||||
|
3.939 0.999316 2650080 1462.86
|
||||||
|
4.039 0.999414 2650339 1706.67
|
||||||
|
4.167 0.999512 2650602 2048.00
|
||||||
|
4.227 0.999561 2650729 2275.56
|
||||||
|
4.307 0.999609 2650859 2560.00
|
||||||
|
4.395 0.999658 2650983 2925.71
|
||||||
|
4.507 0.999707 2651116 3413.33
|
||||||
|
4.619 0.999756 2651243 4096.00
|
||||||
|
4.675 0.999780 2651308 4551.11
|
||||||
|
4.751 0.999805 2651373 5120.00
|
||||||
|
4.827 0.999829 2651436 5851.43
|
||||||
|
4.915 0.999854 2651501 6826.67
|
||||||
|
5.023 0.999878 2651567 8192.00
|
||||||
|
5.071 0.999890 2651598 9102.22
|
||||||
|
5.131 0.999902 2651633 10240.00
|
||||||
|
5.175 0.999915 2651663 11702.86
|
||||||
|
5.251 0.999927 2651695 13653.33
|
||||||
|
5.371 0.999939 2651729 16384.00
|
||||||
|
5.431 0.999945 2651745 18204.44
|
||||||
|
5.491 0.999951 2651761 20480.00
|
||||||
|
5.603 0.999957 2651776 23405.71
|
||||||
|
5.735 0.999963 2651792 27306.67
|
||||||
|
5.847 0.999969 2651810 32768.00
|
||||||
|
5.871 0.999973 2651818 36408.89
|
||||||
|
5.907 0.999976 2651825 40960.00
|
||||||
|
6.035 0.999979 2651833 46811.43
|
||||||
|
6.155 0.999982 2651841 54613.33
|
||||||
|
6.247 0.999985 2651849 65536.00
|
||||||
|
6.351 0.999986 2651853 72817.78
|
||||||
|
6.427 0.999988 2651857 81920.00
|
||||||
|
6.475 0.999989 2651861 93622.86
|
||||||
|
6.543 0.999991 2651865 109226.67
|
||||||
|
6.663 0.999992 2651869 131072.00
|
||||||
|
6.775 0.999993 2651871 145635.56
|
||||||
|
6.807 0.999994 2651873 163840.00
|
||||||
|
6.835 0.999995 2651875 187245.71
|
||||||
|
6.887 0.999995 2651877 218453.33
|
||||||
|
7.015 0.999996 2651879 262144.00
|
||||||
|
7.139 0.999997 2651880 291271.11
|
||||||
|
7.239 0.999997 2651881 327680.00
|
||||||
|
7.355 0.999997 2651882 374491.43
|
||||||
|
7.467 0.999998 2651883 436906.67
|
||||||
|
8.839 0.999998 2651884 524288.00
|
||||||
|
8.879 0.999998 2651885 582542.22
|
||||||
|
8.879 0.999998 2651885 655360.00
|
||||||
|
9.487 0.999999 2651886 748982.86
|
||||||
|
9.487 0.999999 2651886 873813.33
|
||||||
|
9.871 0.999999 2651887 1048576.00
|
||||||
|
9.871 0.999999 2651887 1165084.44
|
||||||
|
9.871 0.999999 2651887 1310720.00
|
||||||
|
10.127 0.999999 2651888 1497965.71
|
||||||
|
10.127 0.999999 2651888 1747626.67
|
||||||
|
10.127 1.000000 2651888 2097152.00
|
||||||
|
10.127 1.000000 2651888 2330168.89
|
||||||
|
10.127 1.000000 2651888 2621440.00
|
||||||
|
10.271 1.000000 2651889 2995931.43
|
||||||
|
10.271 1.000000 2651889 inf
|
||||||
|
#[Mean = 1.215, StdDeviation = 0.552]
|
||||||
|
#[Max = 10.264, Total count = 2651889]
|
||||||
|
#[Buckets = 27, SubBuckets = 2048]
|
||||||
|
----------------------------------------------------------
|
||||||
|
3188375 requests in 1.00m, 428.73MB read
|
||||||
|
Non-2xx or 3xx responses: 3188375
|
||||||
|
Requests/sec: 53139.27
|
||||||
|
Transfer/sec: 7.15MB
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 30s test @ http://127.0.0.1:8082
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 3.36ms 588.20us 28.42ms 90.23%
|
||||||
|
Req/Sec 9.57k 1.00k 38.51k 93.17%
|
||||||
|
Latency Distribution
|
||||||
|
50% 3.24ms
|
||||||
|
75% 3.53ms
|
||||||
|
90% 3.92ms
|
||||||
|
99% 4.73ms
|
||||||
|
2287972 requests in 30.10s, 307.66MB read
|
||||||
|
Non-2xx or 3xx responses: 2287972
|
||||||
|
Requests/sec: 76012.04
|
||||||
|
Transfer/sec: 10.22MB
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
ts cpu_pct rss_kb
|
||||||
|
1779826107 267,00 9824
|
||||||
|
1779826109 289,00 18180
|
||||||
|
1779826111 286,00 18208
|
||||||
|
1779826113 285,00 18216
|
||||||
|
1779826115 281,00 18248
|
||||||
|
1779826117 282,00 18280
|
||||||
|
1779826119 286,00 18280
|
||||||
|
1779826121 283,00 18304
|
||||||
|
1779826123 286,00 18308
|
||||||
|
1779826125 288,00 18312
|
||||||
|
1779826127 286,00 18356
|
||||||
|
1779826129 283,00 18356
|
||||||
|
1779826131 288,00 18356
|
||||||
|
1779826133 290,00 18356
|
||||||
|
1779826135 283,00 18356
|
||||||
|
1779826137 179,00 16568
|
||||||
|
1779826139 222,00 18424
|
||||||
|
1779826141 215,00 18428
|
||||||
|
1779826143 225,00 18428
|
||||||
|
1779826145 221,00 18448
|
||||||
|
1779826147 221,00 18448
|
||||||
|
1779826149 217,00 18448
|
||||||
|
1779826151 224,00 18448
|
||||||
|
1779826153 221,00 18448
|
||||||
|
1779826155 223,00 18448
|
||||||
|
1779826157 220,00 18448
|
||||||
|
1779826159 224,00 18448
|
||||||
|
1779826161 223,00 18448
|
||||||
|
1779826163 218,00 18448
|
||||||
|
1779826165 227,00 18448
|
||||||
|
1779826167 197,00 18280
|
||||||
|
1779826169 196,00 18540
|
||||||
|
1779826171 206,00 18548
|
||||||
|
1779826173 223,00 18548
|
||||||
|
1779826175 212,00 18548
|
||||||
|
1779826177 215,00 18548
|
||||||
|
1779826179 221,00 18560
|
||||||
|
1779826181 205,00 18560
|
||||||
|
1779826183 214,00 18568
|
||||||
|
1779826185 211,00 18576
|
||||||
|
1779826187 201,00 18576
|
||||||
|
1779826189 220,00 18576
|
||||||
|
1779826191 207,00 18576
|
||||||
|
1779826193 190,00 18576
|
||||||
|
1779826195 219,00 18584
|
||||||
|
1779826197 195,00 18584
|
||||||
|
1779826199 221,00 18584
|
||||||
|
1779826201 202,97 18584
|
||||||
|
1779826204 201,00 18584
|
||||||
|
1779826206 211,00 18584
|
||||||
|
1779826208 195,00 18584
|
||||||
|
1779826210 193,00 18584
|
||||||
|
1779826212 206,00 18584
|
||||||
|
1779826214 211,00 18584
|
||||||
|
1779826216 210,00 18584
|
||||||
|
1779826218 211,00 18584
|
||||||
|
1779826220 215,00 18584
|
||||||
|
1779826222 219,00 18584
|
||||||
|
1779826224 219,00 18584
|
||||||
|
1779826226 215,00 18584
|
||||||
|
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"run_id": "urus-mem-s2",
|
||||||
|
"server": "urus-mem",
|
||||||
|
"scenario": "s2",
|
||||||
|
"probe_rps": 76012.04,
|
||||||
|
"target_rps": 53208,
|
||||||
|
"sustained_rps": 53139.27,
|
||||||
|
"latency": {
|
||||||
|
"p50": "1.17ms",
|
||||||
|
"p90": "1.94ms",
|
||||||
|
"p99": "2.62ms",
|
||||||
|
"p999": "3.62ms",
|
||||||
|
"max": "10.27ms"
|
||||||
|
},
|
||||||
|
"non_2xx": 3188375,
|
||||||
|
"mean_cpu_pct": "230.1",
|
||||||
|
"max_rss_kb": 18584
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
runner: launching server on cores 0-7: /home/mark/projects/urus-bench/target/release/urus-server --addr=127.0.0.1:8082 --store=memory
|
||||||
|
runner: smoke OK
|
||||||
|
runner: pre-populating store with 10000 users
|
||||||
|
runner: store now reports 100 users (list cap is 100)
|
||||||
|
runner: probe (30s closed-loop, 256 conns)
|
||||||
|
runner: probe RPS=76012.04, target (sustained)=53208
|
||||||
|
runner: warm-up (30s at -R53208)
|
||||||
|
runner: measure (60s at -R53208)
|
||||||
|
|
||||||
|
runner: DONE -> /home/mark/projects/urus-bench/results/urus-mem-s2
|
||||||
|
{
|
||||||
|
"run_id": "urus-mem-s2",
|
||||||
|
"server": "urus-mem",
|
||||||
|
"scenario": "s2",
|
||||||
|
"probe_rps": 76012.04,
|
||||||
|
"target_rps": 53208,
|
||||||
|
"sustained_rps": 53139.27,
|
||||||
|
"latency": {
|
||||||
|
"p50": "1.17ms",
|
||||||
|
"p90": "1.94ms",
|
||||||
|
"p99": "2.62ms",
|
||||||
|
"p999": "3.62ms",
|
||||||
|
"max": "10.27ms"
|
||||||
|
},
|
||||||
|
"non_2xx": 3188375,
|
||||||
|
"mean_cpu_pct": "230.1",
|
||||||
|
"max_rss_kb": 18584
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,125 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s2_user_get.lua: /home/mark/projects/urus-bench/loadgen/s2_user_get.lua:4: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 30s test @ http://127.0.0.1:8082
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 1.175ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.177ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.174ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.171ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.180ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.179ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.224ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.179ms, rate sampling interval: 10ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 1.18ms 538.34us 6.68ms 67.16%
|
||||||
|
Req/Sec 7.01k 517.92 10.67k 75.53%
|
||||||
|
1585917 requests in 30.00s, 213.26MB read
|
||||||
|
Non-2xx or 3xx responses: 1585917
|
||||||
|
Requests/sec: 52864.79
|
||||||
|
Transfer/sec: 7.11MB
|
||||||
@@ -0,0 +1,252 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 1m test @ http://127.0.0.1:8083
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 1.286ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.323ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.293ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.319ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.326ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.286ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.289ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.287ms, rate sampling interval: 10ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 1.23ms 561.06us 7.58ms 67.45%
|
||||||
|
Req/Sec 7.07k 461.87 10.22k 68.78%
|
||||||
|
Latency Distribution (HdrHistogram - Recorded Latency)
|
||||||
|
50.000% 1.19ms
|
||||||
|
75.000% 1.60ms
|
||||||
|
90.000% 1.97ms
|
||||||
|
99.000% 2.67ms
|
||||||
|
99.900% 3.71ms
|
||||||
|
99.990% 5.19ms
|
||||||
|
99.999% 6.75ms
|
||||||
|
100.000% 7.58ms
|
||||||
|
|
||||||
|
Detailed Percentile spectrum:
|
||||||
|
Value Percentile TotalCount 1/(1-Percentile)
|
||||||
|
|
||||||
|
0.052 0.000000 2 1.00
|
||||||
|
0.535 0.100000 267869 1.11
|
||||||
|
0.729 0.200000 536075 1.25
|
||||||
|
0.890 0.300000 802909 1.43
|
||||||
|
1.041 0.400000 1071845 1.67
|
||||||
|
1.189 0.500000 1338619 2.00
|
||||||
|
1.265 0.550000 1472720 2.22
|
||||||
|
1.342 0.600000 1605568 2.50
|
||||||
|
1.423 0.650000 1740210 2.86
|
||||||
|
1.507 0.700000 1873403 3.33
|
||||||
|
1.598 0.750000 2007598 4.00
|
||||||
|
1.647 0.775000 2074294 4.44
|
||||||
|
1.699 0.800000 2141221 5.00
|
||||||
|
1.755 0.825000 2207705 5.71
|
||||||
|
1.817 0.850000 2274506 6.67
|
||||||
|
1.888 0.875000 2341913 8.00
|
||||||
|
1.927 0.887500 2374736 8.89
|
||||||
|
1.970 0.900000 2408193 10.00
|
||||||
|
2.017 0.912500 2441503 11.43
|
||||||
|
2.071 0.925000 2475843 13.33
|
||||||
|
2.131 0.937500 2508859 16.00
|
||||||
|
2.165 0.943750 2525409 17.78
|
||||||
|
2.203 0.950000 2542421 20.00
|
||||||
|
2.245 0.956250 2559261 22.86
|
||||||
|
2.291 0.962500 2575646 26.67
|
||||||
|
2.345 0.968750 2592041 32.00
|
||||||
|
2.377 0.971875 2600774 35.56
|
||||||
|
2.411 0.975000 2609119 40.00
|
||||||
|
2.449 0.978125 2617401 45.71
|
||||||
|
2.491 0.981250 2625472 53.33
|
||||||
|
2.543 0.984375 2634034 64.00
|
||||||
|
2.573 0.985938 2638237 71.11
|
||||||
|
2.605 0.987500 2642235 80.00
|
||||||
|
2.643 0.989062 2646539 91.43
|
||||||
|
2.687 0.990625 2650694 106.67
|
||||||
|
2.739 0.992188 2654835 128.00
|
||||||
|
2.769 0.992969 2656810 142.22
|
||||||
|
2.805 0.993750 2658926 160.00
|
||||||
|
2.847 0.994531 2661037 182.86
|
||||||
|
2.897 0.995313 2663118 213.33
|
||||||
|
2.961 0.996094 2665201 256.00
|
||||||
|
2.999 0.996484 2666220 284.44
|
||||||
|
3.047 0.996875 2667293 320.00
|
||||||
|
3.105 0.997266 2668310 365.71
|
||||||
|
3.177 0.997656 2669362 426.67
|
||||||
|
3.271 0.998047 2670394 512.00
|
||||||
|
3.331 0.998242 2670928 568.89
|
||||||
|
3.405 0.998437 2671447 640.00
|
||||||
|
3.497 0.998633 2671968 731.43
|
||||||
|
3.599 0.998828 2672483 853.33
|
||||||
|
3.731 0.999023 2673009 1024.00
|
||||||
|
3.805 0.999121 2673269 1137.78
|
||||||
|
3.885 0.999219 2673531 1280.00
|
||||||
|
3.969 0.999316 2673792 1462.86
|
||||||
|
4.083 0.999414 2674053 1706.67
|
||||||
|
4.203 0.999512 2674312 2048.00
|
||||||
|
4.271 0.999561 2674444 2275.56
|
||||||
|
4.351 0.999609 2674573 2560.00
|
||||||
|
4.435 0.999658 2674707 2925.71
|
||||||
|
4.531 0.999707 2674838 3413.33
|
||||||
|
4.651 0.999756 2674968 4096.00
|
||||||
|
4.707 0.999780 2675032 4551.11
|
||||||
|
4.775 0.999805 2675101 5120.00
|
||||||
|
4.839 0.999829 2675162 5851.43
|
||||||
|
4.967 0.999854 2675231 6826.67
|
||||||
|
5.079 0.999878 2675292 8192.00
|
||||||
|
5.131 0.999890 2675325 9102.22
|
||||||
|
5.195 0.999902 2675358 10240.00
|
||||||
|
5.291 0.999915 2675393 11702.86
|
||||||
|
5.403 0.999927 2675424 13653.33
|
||||||
|
5.559 0.999939 2675456 16384.00
|
||||||
|
5.599 0.999945 2675472 18204.44
|
||||||
|
5.727 0.999951 2675488 20480.00
|
||||||
|
5.851 0.999957 2675504 23405.71
|
||||||
|
5.915 0.999963 2675521 27306.67
|
||||||
|
6.171 0.999969 2675537 32768.00
|
||||||
|
6.231 0.999973 2675545 36408.89
|
||||||
|
6.327 0.999976 2675553 40960.00
|
||||||
|
6.411 0.999979 2675561 46811.43
|
||||||
|
6.547 0.999982 2675570 54613.33
|
||||||
|
6.619 0.999985 2675578 65536.00
|
||||||
|
6.655 0.999986 2675582 72817.78
|
||||||
|
6.679 0.999988 2675586 81920.00
|
||||||
|
6.723 0.999989 2675590 93622.86
|
||||||
|
6.795 0.999991 2675594 109226.67
|
||||||
|
6.879 0.999992 2675598 131072.00
|
||||||
|
6.895 0.999993 2675600 145635.56
|
||||||
|
6.927 0.999994 2675602 163840.00
|
||||||
|
6.931 0.999995 2675604 187245.71
|
||||||
|
7.019 0.999995 2675606 218453.33
|
||||||
|
7.119 0.999996 2675608 262144.00
|
||||||
|
7.131 0.999997 2675609 291271.11
|
||||||
|
7.135 0.999997 2675610 327680.00
|
||||||
|
7.147 0.999997 2675611 374491.43
|
||||||
|
7.151 0.999998 2675612 436906.67
|
||||||
|
7.187 0.999998 2675613 524288.00
|
||||||
|
7.331 0.999998 2675614 582542.22
|
||||||
|
7.331 0.999998 2675614 655360.00
|
||||||
|
7.399 0.999999 2675615 748982.86
|
||||||
|
7.399 0.999999 2675615 873813.33
|
||||||
|
7.439 0.999999 2675616 1048576.00
|
||||||
|
7.439 0.999999 2675616 1165084.44
|
||||||
|
7.439 0.999999 2675616 1310720.00
|
||||||
|
7.491 0.999999 2675617 1497965.71
|
||||||
|
7.491 0.999999 2675617 1747626.67
|
||||||
|
7.491 1.000000 2675617 2097152.00
|
||||||
|
7.491 1.000000 2675617 2330168.89
|
||||||
|
7.491 1.000000 2675617 2621440.00
|
||||||
|
7.583 1.000000 2675618 2995931.43
|
||||||
|
7.583 1.000000 2675618 inf
|
||||||
|
#[Mean = 1.232, StdDeviation = 0.561]
|
||||||
|
#[Max = 7.580, Total count = 2675618]
|
||||||
|
#[Buckets = 27, SubBuckets = 2048]
|
||||||
|
----------------------------------------------------------
|
||||||
|
3216932 requests in 1.00m, 432.57MB read
|
||||||
|
Non-2xx or 3xx responses: 3216932
|
||||||
|
Requests/sec: 53615.94
|
||||||
|
Transfer/sec: 7.21MB
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 30s test @ http://127.0.0.1:8083
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 3.33ms 491.70us 19.58ms 86.60%
|
||||||
|
Req/Sec 9.66k 1.41k 74.99k 99.25%
|
||||||
|
Latency Distribution
|
||||||
|
50% 3.20ms
|
||||||
|
75% 3.44ms
|
||||||
|
90% 3.92ms
|
||||||
|
99% 4.73ms
|
||||||
|
2308402 requests in 30.10s, 310.41MB read
|
||||||
|
Non-2xx or 3xx responses: 2308402
|
||||||
|
Requests/sec: 76692.95
|
||||||
|
Transfer/sec: 10.31MB
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
ts cpu_pct rss_kb
|
||||||
|
1779826228 277,00 9860
|
||||||
|
1779826230 283,00 18204
|
||||||
|
1779826232 285,00 18220
|
||||||
|
1779826234 286,00 18232
|
||||||
|
1779826237 290,00 18236
|
||||||
|
1779826239 273,00 18248
|
||||||
|
1779826241 281,00 18308
|
||||||
|
1779826243 279,21 18328
|
||||||
|
1779826245 283,00 18332
|
||||||
|
1779826247 286,00 18332
|
||||||
|
1779826249 285,00 18356
|
||||||
|
1779826251 277,00 18356
|
||||||
|
1779826253 283,00 18356
|
||||||
|
1779826255 281,00 18356
|
||||||
|
1779826257 289,00 18356
|
||||||
|
1779826259 186,00 16564
|
||||||
|
1779826261 213,00 18432
|
||||||
|
1779826263 198,00 18440
|
||||||
|
1779826265 216,00 18520
|
||||||
|
1779826267 205,00 18548
|
||||||
|
1779826269 208,00 18548
|
||||||
|
1779826271 222,00 18552
|
||||||
|
1779826273 224,00 18552
|
||||||
|
1779826275 218,00 18552
|
||||||
|
1779826277 215,00 18592
|
||||||
|
1779826279 221,00 18592
|
||||||
|
1779826281 210,00 18592
|
||||||
|
1779826283 200,00 18592
|
||||||
|
1779826285 218,00 18592
|
||||||
|
1779826287 220,00 18592
|
||||||
|
1779826289 207,00 18464
|
||||||
|
1779826291 204,00 18744
|
||||||
|
1779826293 211,00 18744
|
||||||
|
1779826295 210,00 18744
|
||||||
|
1779826297 212,00 18744
|
||||||
|
1779826299 223,00 18744
|
||||||
|
1779826301 221,00 18744
|
||||||
|
1779826303 211,00 18744
|
||||||
|
1779826305 221,00 18744
|
||||||
|
1779826307 216,00 18784
|
||||||
|
1779826309 217,00 18784
|
||||||
|
1779826311 217,00 18784
|
||||||
|
1779826313 221,00 18784
|
||||||
|
1779826315 222,00 18784
|
||||||
|
1779826317 221,00 18784
|
||||||
|
1779826319 212,00 18784
|
||||||
|
1779826321 214,00 18784
|
||||||
|
1779826323 223,00 18784
|
||||||
|
1779826325 214,00 18784
|
||||||
|
1779826327 211,00 18784
|
||||||
|
1779826329 214,00 18784
|
||||||
|
1779826331 208,00 18784
|
||||||
|
1779826333 210,00 18784
|
||||||
|
1779826335 178,00 18784
|
||||||
|
1779826337 206,00 18784
|
||||||
|
1779826339 206,00 18784
|
||||||
|
1779826341 208,00 18784
|
||||||
|
1779826343 184,00 18784
|
||||||
|
1779826345 216,00 18784
|
||||||
|
1779826347 214,00 18784
|
||||||
|
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"run_id": "urus-mem-s3",
|
||||||
|
"server": "urus-mem",
|
||||||
|
"scenario": "s3",
|
||||||
|
"probe_rps": 76692.95,
|
||||||
|
"target_rps": 53685,
|
||||||
|
"sustained_rps": 53615.94,
|
||||||
|
"latency": {
|
||||||
|
"p50": "1.19ms",
|
||||||
|
"p90": "1.97ms",
|
||||||
|
"p99": "2.67ms",
|
||||||
|
"p999": "3.71ms",
|
||||||
|
"max": "7.58ms"
|
||||||
|
},
|
||||||
|
"non_2xx": 3216932,
|
||||||
|
"mean_cpu_pct": "229.4",
|
||||||
|
"max_rss_kb": 18784
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
runner: launching server on cores 0-7: /home/mark/projects/urus-bench/target/release/urus-server --addr=127.0.0.1:8083 --store=memory
|
||||||
|
runner: smoke OK
|
||||||
|
runner: pre-populating store with 10000 users
|
||||||
|
runner: store now reports 100 users (list cap is 100)
|
||||||
|
runner: probe (30s closed-loop, 256 conns)
|
||||||
|
runner: probe RPS=76692.95, target (sustained)=53685
|
||||||
|
runner: warm-up (30s at -R53685)
|
||||||
|
runner: measure (60s at -R53685)
|
||||||
|
|
||||||
|
runner: DONE -> /home/mark/projects/urus-bench/results/urus-mem-s3
|
||||||
|
{
|
||||||
|
"run_id": "urus-mem-s3",
|
||||||
|
"server": "urus-mem",
|
||||||
|
"scenario": "s3",
|
||||||
|
"probe_rps": 76692.95,
|
||||||
|
"target_rps": 53685,
|
||||||
|
"sustained_rps": 53615.94,
|
||||||
|
"latency": {
|
||||||
|
"p50": "1.19ms",
|
||||||
|
"p90": "1.97ms",
|
||||||
|
"p99": "2.67ms",
|
||||||
|
"p999": "3.71ms",
|
||||||
|
"max": "7.58ms"
|
||||||
|
},
|
||||||
|
"non_2xx": 3216932,
|
||||||
|
"mean_cpu_pct": "229.4",
|
||||||
|
"max_rss_kb": 18784
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,125 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 30s test @ http://127.0.0.1:8083
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 1.321ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.331ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.314ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.321ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.350ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.345ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.312ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.350ms, rate sampling interval: 10ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 1.26ms 585.94us 8.00ms 68.15%
|
||||||
|
Req/Sec 7.07k 491.83 10.33k 74.67%
|
||||||
|
1606397 requests in 30.00s, 216.01MB read
|
||||||
|
Non-2xx or 3xx responses: 1606397
|
||||||
|
Requests/sec: 53547.34
|
||||||
|
Transfer/sec: 7.20MB
|
||||||
@@ -0,0 +1,252 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 1m test @ http://127.0.0.1:8087
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 1.149ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.140ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.137ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.143ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.138ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.148ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.143ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.255ms, rate sampling interval: 10ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 1.17ms 535.60us 6.75ms 67.06%
|
||||||
|
Req/Sec 6.95k 485.27 10.56k 72.39%
|
||||||
|
Latency Distribution (HdrHistogram - Recorded Latency)
|
||||||
|
50.000% 1.13ms
|
||||||
|
75.000% 1.52ms
|
||||||
|
90.000% 1.87ms
|
||||||
|
99.000% 2.53ms
|
||||||
|
99.900% 3.53ms
|
||||||
|
99.990% 4.70ms
|
||||||
|
99.999% 5.57ms
|
||||||
|
100.000% 6.75ms
|
||||||
|
|
||||||
|
Detailed Percentile spectrum:
|
||||||
|
Value Percentile TotalCount 1/(1-Percentile)
|
||||||
|
|
||||||
|
0.048 0.000000 1 1.00
|
||||||
|
0.497 0.100000 264156 1.11
|
||||||
|
0.681 0.200000 526035 1.25
|
||||||
|
0.838 0.300000 788948 1.43
|
||||||
|
0.985 0.400000 1051873 1.67
|
||||||
|
1.132 0.500000 1316522 2.00
|
||||||
|
1.205 0.550000 1446440 2.22
|
||||||
|
1.280 0.600000 1578365 2.50
|
||||||
|
1.357 0.650000 1710105 2.86
|
||||||
|
1.437 0.700000 1841349 3.33
|
||||||
|
1.523 0.750000 1973519 4.00
|
||||||
|
1.568 0.775000 2037952 4.44
|
||||||
|
1.617 0.800000 2104514 5.00
|
||||||
|
1.669 0.825000 2169590 5.71
|
||||||
|
1.727 0.850000 2235549 6.67
|
||||||
|
1.793 0.875000 2301603 8.00
|
||||||
|
1.829 0.887500 2333983 8.89
|
||||||
|
1.869 0.900000 2366945 10.00
|
||||||
|
1.913 0.912500 2399521 11.43
|
||||||
|
1.963 0.925000 2432460 13.33
|
||||||
|
2.021 0.937500 2465640 16.00
|
||||||
|
2.053 0.943750 2482183 17.78
|
||||||
|
2.089 0.950000 2498948 20.00
|
||||||
|
2.127 0.956250 2514972 22.86
|
||||||
|
2.171 0.962500 2531105 26.67
|
||||||
|
2.225 0.968750 2547964 32.00
|
||||||
|
2.253 0.971875 2555696 35.56
|
||||||
|
2.287 0.975000 2564213 40.00
|
||||||
|
2.323 0.978125 2572456 45.71
|
||||||
|
2.363 0.981250 2580486 53.33
|
||||||
|
2.411 0.984375 2588666 64.00
|
||||||
|
2.439 0.985938 2592852 71.11
|
||||||
|
2.469 0.987500 2596892 80.00
|
||||||
|
2.503 0.989062 2600927 91.43
|
||||||
|
2.543 0.990625 2605025 106.67
|
||||||
|
2.591 0.992188 2609065 128.00
|
||||||
|
2.621 0.992969 2611180 142.22
|
||||||
|
2.653 0.993750 2613165 160.00
|
||||||
|
2.693 0.994531 2615312 182.86
|
||||||
|
2.739 0.995313 2617352 213.33
|
||||||
|
2.795 0.996094 2619364 256.00
|
||||||
|
2.833 0.996484 2620390 284.44
|
||||||
|
2.877 0.996875 2621416 320.00
|
||||||
|
2.929 0.997266 2622439 365.71
|
||||||
|
2.991 0.997656 2623440 426.67
|
||||||
|
3.079 0.998047 2624469 512.00
|
||||||
|
3.135 0.998242 2624994 568.89
|
||||||
|
3.211 0.998437 2625492 640.00
|
||||||
|
3.305 0.998633 2626014 731.43
|
||||||
|
3.413 0.998828 2626523 853.33
|
||||||
|
3.547 0.999023 2627035 1024.00
|
||||||
|
3.625 0.999121 2627292 1137.78
|
||||||
|
3.701 0.999219 2627547 1280.00
|
||||||
|
3.785 0.999316 2627808 1462.86
|
||||||
|
3.873 0.999414 2628062 1706.67
|
||||||
|
3.979 0.999512 2628322 2048.00
|
||||||
|
4.035 0.999561 2628449 2275.56
|
||||||
|
4.099 0.999609 2628579 2560.00
|
||||||
|
4.159 0.999658 2628709 2925.71
|
||||||
|
4.231 0.999707 2628830 3413.33
|
||||||
|
4.315 0.999756 2628959 4096.00
|
||||||
|
4.363 0.999780 2629028 4551.11
|
||||||
|
4.411 0.999805 2629087 5120.00
|
||||||
|
4.471 0.999829 2629153 5851.43
|
||||||
|
4.527 0.999854 2629217 6826.67
|
||||||
|
4.619 0.999878 2629281 8192.00
|
||||||
|
4.663 0.999890 2629315 9102.22
|
||||||
|
4.715 0.999902 2629347 10240.00
|
||||||
|
4.783 0.999915 2629376 11702.86
|
||||||
|
4.843 0.999927 2629411 13653.33
|
||||||
|
4.915 0.999939 2629441 16384.00
|
||||||
|
4.967 0.999945 2629456 18204.44
|
||||||
|
5.007 0.999951 2629472 20480.00
|
||||||
|
5.055 0.999957 2629488 23405.71
|
||||||
|
5.127 0.999963 2629505 27306.67
|
||||||
|
5.175 0.999969 2629521 32768.00
|
||||||
|
5.187 0.999973 2629528 36408.89
|
||||||
|
5.227 0.999976 2629537 40960.00
|
||||||
|
5.255 0.999979 2629544 46811.43
|
||||||
|
5.303 0.999982 2629553 54613.33
|
||||||
|
5.359 0.999985 2629560 65536.00
|
||||||
|
5.407 0.999986 2629564 72817.78
|
||||||
|
5.479 0.999988 2629568 81920.00
|
||||||
|
5.547 0.999989 2629572 93622.86
|
||||||
|
5.635 0.999991 2629576 109226.67
|
||||||
|
5.707 0.999992 2629580 131072.00
|
||||||
|
5.739 0.999993 2629582 145635.56
|
||||||
|
5.743 0.999994 2629584 163840.00
|
||||||
|
5.779 0.999995 2629587 187245.71
|
||||||
|
5.783 0.999995 2629588 218453.33
|
||||||
|
5.827 0.999996 2629590 262144.00
|
||||||
|
5.867 0.999997 2629591 291271.11
|
||||||
|
5.871 0.999997 2629592 327680.00
|
||||||
|
5.891 0.999997 2629593 374491.43
|
||||||
|
5.911 0.999998 2629594 436906.67
|
||||||
|
5.923 0.999998 2629595 524288.00
|
||||||
|
6.003 0.999998 2629596 582542.22
|
||||||
|
6.003 0.999998 2629596 655360.00
|
||||||
|
6.295 0.999999 2629597 748982.86
|
||||||
|
6.295 0.999999 2629597 873813.33
|
||||||
|
6.479 0.999999 2629598 1048576.00
|
||||||
|
6.479 0.999999 2629598 1165084.44
|
||||||
|
6.479 0.999999 2629598 1310720.00
|
||||||
|
6.595 0.999999 2629599 1497965.71
|
||||||
|
6.595 0.999999 2629599 1747626.67
|
||||||
|
6.595 1.000000 2629599 2097152.00
|
||||||
|
6.595 1.000000 2629599 2330168.89
|
||||||
|
6.595 1.000000 2629599 2621440.00
|
||||||
|
6.751 1.000000 2629600 2995931.43
|
||||||
|
6.751 1.000000 2629600 inf
|
||||||
|
#[Mean = 1.168, StdDeviation = 0.536]
|
||||||
|
#[Max = 6.748, Total count = 2629600]
|
||||||
|
#[Buckets = 27, SubBuckets = 2048]
|
||||||
|
----------------------------------------------------------
|
||||||
|
3155499 requests in 1.00m, 424.31MB read
|
||||||
|
Non-2xx or 3xx responses: 3155499
|
||||||
|
Requests/sec: 52589.50
|
||||||
|
Transfer/sec: 7.07MB
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 30s test @ http://127.0.0.1:8087
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 3.39ms 478.41us 19.15ms 84.07%
|
||||||
|
Req/Sec 9.48k 599.23 13.12k 69.45%
|
||||||
|
Latency Distribution
|
||||||
|
50% 3.26ms
|
||||||
|
75% 3.57ms
|
||||||
|
90% 3.98ms
|
||||||
|
99% 4.74ms
|
||||||
|
2268670 requests in 30.10s, 305.06MB read
|
||||||
|
Non-2xx or 3xx responses: 2268670
|
||||||
|
Requests/sec: 75372.95
|
||||||
|
Transfer/sec: 10.14MB
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
ts cpu_pct rss_kb
|
||||||
|
1779826713 281,00 11060
|
||||||
|
1779826715 285,00 19396
|
||||||
|
1779826717 280,00 19476
|
||||||
|
1779826719 279,00 19524
|
||||||
|
1779826721 286,00 19524
|
||||||
|
1779826723 285,00 19528
|
||||||
|
1779826725 283,00 19528
|
||||||
|
1779826727 282,00 19540
|
||||||
|
1779826729 288,00 19540
|
||||||
|
1779826731 282,00 19540
|
||||||
|
1779826733 278,00 19540
|
||||||
|
1779826735 292,00 19540
|
||||||
|
1779826737 279,00 19540
|
||||||
|
1779826739 283,00 19540
|
||||||
|
1779826741 289,00 19540
|
||||||
|
1779826743 211,00 17812
|
||||||
|
1779826745 207,00 19664
|
||||||
|
1779826747 213,00 19664
|
||||||
|
1779826749 216,00 19664
|
||||||
|
1779826751 209,00 19664
|
||||||
|
1779826753 216,00 19668
|
||||||
|
1779826755 195,00 19668
|
||||||
|
1779826757 207,00 19668
|
||||||
|
1779826759 207,00 19668
|
||||||
|
1779826761 200,00 19668
|
||||||
|
1779826763 199,01 19668
|
||||||
|
1779826765 201,00 19668
|
||||||
|
1779826767 210,00 19668
|
||||||
|
1779826769 174,00 19668
|
||||||
|
1779826771 187,00 19672
|
||||||
|
1779826773 198,00 19328
|
||||||
|
1779826775 214,00 19724
|
||||||
|
1779826777 220,00 19724
|
||||||
|
1779826779 229,00 19724
|
||||||
|
1779826781 220,00 19724
|
||||||
|
1779826783 216,00 19724
|
||||||
|
1779826785 217,00 19724
|
||||||
|
1779826787 226,00 19724
|
||||||
|
1779826789 225,00 19724
|
||||||
|
1779826791 222,00 19724
|
||||||
|
1779826793 221,00 19724
|
||||||
|
1779826795 225,00 19724
|
||||||
|
1779826797 215,00 19724
|
||||||
|
1779826799 227,00 19724
|
||||||
|
1779826801 220,00 19724
|
||||||
|
1779826803 215,00 19724
|
||||||
|
1779826805 222,00 19724
|
||||||
|
1779826807 222,00 19724
|
||||||
|
1779826809 223,00 19724
|
||||||
|
1779826811 220,00 19724
|
||||||
|
1779826813 214,00 19724
|
||||||
|
1779826815 201,00 19724
|
||||||
|
1779826818 208,00 19724
|
||||||
|
1779826820 214,00 19724
|
||||||
|
1779826822 210,00 19728
|
||||||
|
1779826824 219,00 19728
|
||||||
|
1779826826 189,00 19728
|
||||||
|
1779826828 224,00 19728
|
||||||
|
1779826830 222,00 19728
|
||||||
|
1779826832 219,00 19728
|
||||||
|
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"run_id": "urus-sqlite-s4",
|
||||||
|
"server": "urus-sqlite",
|
||||||
|
"scenario": "s4",
|
||||||
|
"probe_rps": 75372.95,
|
||||||
|
"target_rps": 52761,
|
||||||
|
"sustained_rps": 52589.50,
|
||||||
|
"latency": {
|
||||||
|
"p50": "1.13ms",
|
||||||
|
"p90": "1.87ms",
|
||||||
|
"p99": "2.53ms",
|
||||||
|
"p999": "3.53ms",
|
||||||
|
"max": "6.75ms"
|
||||||
|
},
|
||||||
|
"non_2xx": 3155499,
|
||||||
|
"mean_cpu_pct": "230.3",
|
||||||
|
"max_rss_kb": 19728
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
runner: launching server on cores 0-7: /home/mark/projects/urus-bench/target/release/urus-server --addr=127.0.0.1:8087 --store=sqlite --db-path=/tmp/urus-bench-urus-sqlite-s4.sqlite
|
||||||
|
runner: smoke OK
|
||||||
|
runner: pre-populating store with 10000 users
|
||||||
|
runner: store now reports 100 users (list cap is 100)
|
||||||
|
runner: probe (30s closed-loop, 256 conns)
|
||||||
|
runner: probe RPS=75372.95, target (sustained)=52761
|
||||||
|
runner: warm-up (30s at -R52761)
|
||||||
|
runner: measure (60s at -R52761)
|
||||||
|
|
||||||
|
runner: DONE -> /home/mark/projects/urus-bench/results/urus-sqlite-s4
|
||||||
|
{
|
||||||
|
"run_id": "urus-sqlite-s4",
|
||||||
|
"server": "urus-sqlite",
|
||||||
|
"scenario": "s4",
|
||||||
|
"probe_rps": 75372.95,
|
||||||
|
"target_rps": 52761,
|
||||||
|
"sustained_rps": 52589.50,
|
||||||
|
"latency": {
|
||||||
|
"p50": "1.13ms",
|
||||||
|
"p90": "1.87ms",
|
||||||
|
"p99": "2.53ms",
|
||||||
|
"p999": "3.53ms",
|
||||||
|
"max": "6.75ms"
|
||||||
|
},
|
||||||
|
"non_2xx": 3155499,
|
||||||
|
"mean_cpu_pct": "230.3",
|
||||||
|
"max_rss_kb": 19728
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,125 @@
|
|||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
/home/mark/projects/urus-bench/loadgen/s3_mixed.lua: /home/mark/projects/urus-bench/loadgen/s3_mixed.lua:6: module 'common' not found:
|
||||||
|
no field package.preload['common']
|
||||||
|
no file './common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/luajit-2.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common.lua'
|
||||||
|
no file '/usr/local/share/lua/5.1/common/init.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common.lua'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/share/lua/5.1/common/init.lua'
|
||||||
|
no file './common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/common.so'
|
||||||
|
no file '/nix/store/l2j91s4fj2n0r47fcd77r6kk18sbbndx-luajit-2.1.1741730670/lib/lua/5.1/common.so'
|
||||||
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
||||||
|
Running 30s test @ http://127.0.0.1:8087
|
||||||
|
8 threads and 256 connections
|
||||||
|
Thread calibration: mean lat.: 1.238ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.234ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.246ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.237ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.241ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.240ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.254ms, rate sampling interval: 10ms
|
||||||
|
Thread calibration: mean lat.: 1.243ms, rate sampling interval: 10ms
|
||||||
|
Thread Stats Avg Stdev Max +/- Stdev
|
||||||
|
Latency 1.20ms 546.91us 6.64ms 66.90%
|
||||||
|
Req/Sec 6.94k 416.47 10.11k 71.16%
|
||||||
|
1578753 requests in 30.00s, 212.29MB read
|
||||||
|
Non-2xx or 3xx responses: 1578753
|
||||||
|
Requests/sec: 52625.73
|
||||||
|
Transfer/sec: 7.08MB
|
||||||
Executable
+411
@@ -0,0 +1,411 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# urus-bench/run_all.sh
|
||||||
|
#
|
||||||
|
# Runs the full (server, scenario) matrix and writes a summary.md.
|
||||||
|
#
|
||||||
|
# Default matrix (8 runs):
|
||||||
|
# urus-mem × s1, s2, s3
|
||||||
|
# axum-mem × s1, s2, s3
|
||||||
|
# urus-sqlite × s4
|
||||||
|
# axum-sqlite × s4
|
||||||
|
#
|
||||||
|
# Cowboy is not built; skipped.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./run_all.sh # full matrix, defaults
|
||||||
|
# ./run_all.sh --quick # short timings (15s+15s+15s)
|
||||||
|
# ./run_all.sh --scenarios=s1,s2 # subset of scenarios
|
||||||
|
# ./run_all.sh --servers=urus-mem # subset of servers
|
||||||
|
# ./run_all.sh --batch=foo # batch label (default: timestamp)
|
||||||
|
#
|
||||||
|
# Per-run env vars (PROBE_SEC, WARMUP_SEC, MEASURE_SEC, PREPOP, SERVER_CPUS,
|
||||||
|
# LOADGEN_CPUS, WRK_CONNS, WRK_THREADS, SAT_RATIO) are passed through to
|
||||||
|
# runner.sh; --quick is just a preset for the timings.
|
||||||
|
#
|
||||||
|
# Output:
|
||||||
|
# results/<batch>/ batch dir
|
||||||
|
# <server>-<scenario>/ per-run dir (from runner.sh)
|
||||||
|
# summary.md aggregated headline table
|
||||||
|
# index.json machine-readable index of all runs
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Defaults
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ALL_SERVERS_MEM=(urus-mem axum-mem)
|
||||||
|
ALL_SERVERS_SQLITE=(urus-sqlite axum-sqlite)
|
||||||
|
ALL_SCENARIOS_MEM=(s1 s2 s3)
|
||||||
|
ALL_SCENARIOS_SQLITE=(s4)
|
||||||
|
|
||||||
|
SERVERS_FILTER=""
|
||||||
|
SCENARIOS_FILTER=""
|
||||||
|
BATCH=""
|
||||||
|
QUICK=0
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Arg parsing
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--quick) QUICK=1 ;;
|
||||||
|
--servers=*) SERVERS_FILTER="${arg#*=}" ;;
|
||||||
|
--scenarios=*) SCENARIOS_FILTER="${arg#*=}" ;;
|
||||||
|
--batch=*) BATCH="${arg#*=}" ;;
|
||||||
|
-h|--help)
|
||||||
|
sed -n '2,/^$/p' "$0" | sed 's/^# \{0,1\}//'
|
||||||
|
exit 0 ;;
|
||||||
|
*)
|
||||||
|
echo "run_all: unknown arg: $arg" >&2
|
||||||
|
exit 2 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$QUICK" == "1" ]]; then
|
||||||
|
export PROBE_SEC="${PROBE_SEC:-15}"
|
||||||
|
export WARMUP_SEC="${WARMUP_SEC:-15}"
|
||||||
|
export MEASURE_SEC="${MEASURE_SEC:-15}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
BATCH="${BATCH:-$(date +%Y%m%d-%H%M%S)}"
|
||||||
|
BATCH_DIR="${REPO_ROOT}/results/${BATCH}"
|
||||||
|
mkdir -p "$BATCH_DIR"
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Build the matrix
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# A run is a pair "<server> <scenario>". We compute the full matrix, then
|
||||||
|
# apply filters. s1/s2/s3 always pair with the memory backends; s4 only
|
||||||
|
# pairs with sqlite backends.
|
||||||
|
|
||||||
|
contains() {
|
||||||
|
# contains "needle" "csv-list" → 0 if needle in csv (or csv empty), else 1
|
||||||
|
local needle="$1" haystack="$2"
|
||||||
|
[[ -z "$haystack" ]] && return 0
|
||||||
|
local IFS=,
|
||||||
|
for item in $haystack; do
|
||||||
|
[[ "$item" == "$needle" ]] && return 0
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
runs=()
|
||||||
|
for srv in "${ALL_SERVERS_MEM[@]}"; do
|
||||||
|
contains "$srv" "$SERVERS_FILTER" || continue
|
||||||
|
for sc in "${ALL_SCENARIOS_MEM[@]}"; do
|
||||||
|
contains "$sc" "$SCENARIOS_FILTER" || continue
|
||||||
|
runs+=("$srv $sc")
|
||||||
|
done
|
||||||
|
done
|
||||||
|
for srv in "${ALL_SERVERS_SQLITE[@]}"; do
|
||||||
|
contains "$srv" "$SERVERS_FILTER" || continue
|
||||||
|
for sc in "${ALL_SCENARIOS_SQLITE[@]}"; do
|
||||||
|
contains "$sc" "$SCENARIOS_FILTER" || continue
|
||||||
|
runs+=("$srv $sc")
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "${#runs[@]}" -eq 0 ]]; then
|
||||||
|
echo "run_all: empty matrix (filters too narrow?)" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Build binaries up front
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# We always rebuild in --release. If urus-server or axum-server is not
|
||||||
|
# requested, cargo will still build the workspace, but that's fine — a
|
||||||
|
# 1-minute one-time cost beats a confusing "binary not found" mid-batch.
|
||||||
|
|
||||||
|
echo "run_all: building binaries (release)..."
|
||||||
|
( cd "$REPO_ROOT" && cargo build --release ) || {
|
||||||
|
echo "run_all: cargo build failed" >&2
|
||||||
|
exit 3
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Run the matrix
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
total="${#runs[@]}"
|
||||||
|
echo
|
||||||
|
echo "run_all: batch=${BATCH}, ${total} run(s):"
|
||||||
|
i=0
|
||||||
|
for r in "${runs[@]}"; do
|
||||||
|
i=$((i + 1))
|
||||||
|
printf " [%d/%d] %s\n" "$i" "$total" "$r"
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
|
||||||
|
i=0
|
||||||
|
failed=()
|
||||||
|
succeeded=()
|
||||||
|
START_TS=$(date +%s)
|
||||||
|
|
||||||
|
# Per-run port offset so concurrent stale processes (if any) don't collide.
|
||||||
|
BASE_PORT="${BASE_PORT:-8080}"
|
||||||
|
|
||||||
|
for r in "${runs[@]}"; do
|
||||||
|
i=$((i + 1))
|
||||||
|
set -- $r
|
||||||
|
SERVER="$1"; SCENARIO="$2"
|
||||||
|
RUN_ID="${SERVER}-${SCENARIO}"
|
||||||
|
RUN_DIR="${BATCH_DIR}/${RUN_ID}"
|
||||||
|
|
||||||
|
printf '\n========== [%d/%d] %-12s %-3s ==========\n' \
|
||||||
|
"$i" "$total" "$SERVER" "$SCENARIO"
|
||||||
|
|
||||||
|
# Each run gets its own port so a hung server from a previous run can't
|
||||||
|
# silently keep answering on the default port.
|
||||||
|
PORT=$((BASE_PORT + i))
|
||||||
|
|
||||||
|
# Each run gets a unique results dir under the batch dir. runner.sh
|
||||||
|
# writes to results/<run_id>/ at the repo root by default — we pass the
|
||||||
|
# run_id but also need it to land under the batch dir. Cheapest fix:
|
||||||
|
# let runner write to its default location, then move it under batch.
|
||||||
|
if PORT="$PORT" "${REPO_ROOT}/runner.sh" "$SERVER" "$SCENARIO" "$RUN_ID" \
|
||||||
|
> "${BATCH_DIR}/${RUN_ID}.stdout.log" 2>&1; then
|
||||||
|
# Move the runner's output dir into the batch dir.
|
||||||
|
if [[ -d "${REPO_ROOT}/results/${RUN_ID}" ]]; then
|
||||||
|
rm -rf "$RUN_DIR"
|
||||||
|
mv "${REPO_ROOT}/results/${RUN_ID}" "$RUN_DIR"
|
||||||
|
fi
|
||||||
|
# Move the stdout log next to the run.
|
||||||
|
mv "${BATCH_DIR}/${RUN_ID}.stdout.log" "${RUN_DIR}/run_all.log" 2>/dev/null || true
|
||||||
|
|
||||||
|
# Pretty-print the headline line from the result.
|
||||||
|
if [[ -f "${RUN_DIR}/result.json" ]]; then
|
||||||
|
rps=$(awk -F'[:,]' '/"sustained_rps"/ {gsub(/[ "]/, "", $2); print $2; exit}' "${RUN_DIR}/result.json")
|
||||||
|
p99=$(awk -F'"' '/"p99"/ {print $4; exit}' "${RUN_DIR}/result.json")
|
||||||
|
printf ' sustained=%s rps p99=%s\n' "$rps" "$p99"
|
||||||
|
fi
|
||||||
|
succeeded+=("$r")
|
||||||
|
else
|
||||||
|
echo " FAILED (see ${BATCH_DIR}/${RUN_ID}.stdout.log)"
|
||||||
|
failed+=("$r")
|
||||||
|
# Also try to salvage anything runner left behind for debugging.
|
||||||
|
if [[ -d "${REPO_ROOT}/results/${RUN_ID}" ]]; then
|
||||||
|
mkdir -p "${BATCH_DIR}/${RUN_ID}"
|
||||||
|
mv "${REPO_ROOT}/results/${RUN_ID}"/* "${BATCH_DIR}/${RUN_ID}/" 2>/dev/null || true
|
||||||
|
rmdir "${REPO_ROOT}/results/${RUN_ID}" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
END_TS=$(date +%s)
|
||||||
|
ELAPSED=$((END_TS - START_TS))
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Build summary.md
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# The headline-table shape from urus-bench-spec.md §6 has servers as
|
||||||
|
# columns, scenarios as rows, two metrics per scenario (RPS sustained,
|
||||||
|
# p99). We render whatever subset of the matrix actually ran.
|
||||||
|
|
||||||
|
SUMMARY="${BATCH_DIR}/summary.md"
|
||||||
|
INDEX="${BATCH_DIR}/index.json"
|
||||||
|
|
||||||
|
# Discover every server / scenario actually represented in the batch.
|
||||||
|
declare -A by_run # by_run["server scenario"] = path to result.json
|
||||||
|
servers_seen=()
|
||||||
|
scenarios_seen=()
|
||||||
|
for d in "$BATCH_DIR"/*/; do
|
||||||
|
rj="${d}result.json"
|
||||||
|
[[ -f "$rj" ]] || continue
|
||||||
|
srv=$(awk -F'"' '/"server":/ {print $4; exit}' "$rj")
|
||||||
|
scn=$(awk -F'"' '/"scenario":/ {print $4; exit}' "$rj")
|
||||||
|
[[ -z "$srv" || -z "$scn" ]] && continue
|
||||||
|
by_run["$srv $scn"]="$rj"
|
||||||
|
# Track distinct lists (order preserved by first occurrence).
|
||||||
|
if ! printf '%s\n' "${servers_seen[@]}" | grep -qx "$srv"; then
|
||||||
|
servers_seen+=("$srv")
|
||||||
|
fi
|
||||||
|
if ! printf '%s\n' "${scenarios_seen[@]}" | grep -qx "$scn"; then
|
||||||
|
scenarios_seen+=("$scn")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Sort scenarios in canonical order s1..s4.
|
||||||
|
IFS=$'\n' scenarios_seen=($(printf '%s\n' "${scenarios_seen[@]}" | sort))
|
||||||
|
unset IFS
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Emit summary.md
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "# urus-bench summary"
|
||||||
|
echo
|
||||||
|
echo "- **Batch:** \`${BATCH}\`"
|
||||||
|
echo "- **Host:** \`$(uname -n)\` (\`$(uname -srm)\`)"
|
||||||
|
echo "- **CPUs:** \`$(nproc) cores\`"
|
||||||
|
if [[ -r /proc/cpuinfo ]]; then
|
||||||
|
model=$(awk -F: '/^model name/ {print $2; exit}' /proc/cpuinfo | sed 's/^ *//')
|
||||||
|
[[ -n "$model" ]] && echo "- **Model:** ${model}"
|
||||||
|
fi
|
||||||
|
echo "- **Started:** \`$(date -d "@$START_TS" -Iseconds 2>/dev/null || date -Iseconds)\`"
|
||||||
|
echo "- **Elapsed:** ${ELAPSED}s"
|
||||||
|
echo "- **Successful runs:** ${#succeeded[@]} / ${total}"
|
||||||
|
if [[ "${#failed[@]}" -gt 0 ]]; then
|
||||||
|
echo "- **Failed runs:** ${failed[*]}"
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo "Timings: probe=${PROBE_SEC:-30}s, warmup=${WARMUP_SEC:-30}s, measure=${MEASURE_SEC:-60}s, sat_ratio=${SAT_RATIO:-0.70}"
|
||||||
|
echo
|
||||||
|
|
||||||
|
if [[ "${#servers_seen[@]}" -eq 0 ]]; then
|
||||||
|
echo "_No successful runs to summarize._"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Sustained RPS table -----------------------------------------------
|
||||||
|
echo "## Sustained RPS (wrk2 @ ${SAT_RATIO:-0.70} of saturation)"
|
||||||
|
echo
|
||||||
|
printf '| '
|
||||||
|
for srv in "${servers_seen[@]}"; do printf '| %-14s ' "$srv"; done
|
||||||
|
printf '|\n'
|
||||||
|
printf '|------------'
|
||||||
|
for _ in "${servers_seen[@]}"; do printf '|----------------'; done
|
||||||
|
printf '|\n'
|
||||||
|
for scn in "${scenarios_seen[@]}"; do
|
||||||
|
printf '| %-10s ' "$scn"
|
||||||
|
for srv in "${servers_seen[@]}"; do
|
||||||
|
rj="${by_run["$srv $scn"]:-}"
|
||||||
|
if [[ -n "$rj" ]]; then
|
||||||
|
rps=$(awk -F'[:,]' '/"sustained_rps"/ {gsub(/[ "]/, "", $2); print $2; exit}' "$rj")
|
||||||
|
# round to integer for readability
|
||||||
|
rps=$(awk -v x="$rps" 'BEGIN {printf "%d", x+0.5}')
|
||||||
|
printf '| %14s ' "$rps"
|
||||||
|
else
|
||||||
|
printf '| %14s ' "—"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
printf '|\n'
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
|
||||||
|
# --- p99 table ----------------------------------------------------------
|
||||||
|
echo "## p99 latency (at target rate)"
|
||||||
|
echo
|
||||||
|
printf '| '
|
||||||
|
for srv in "${servers_seen[@]}"; do printf '| %-14s ' "$srv"; done
|
||||||
|
printf '|\n'
|
||||||
|
printf '|------------'
|
||||||
|
for _ in "${servers_seen[@]}"; do printf '|----------------'; done
|
||||||
|
printf '|\n'
|
||||||
|
for scn in "${scenarios_seen[@]}"; do
|
||||||
|
printf '| %-10s ' "$scn"
|
||||||
|
for srv in "${servers_seen[@]}"; do
|
||||||
|
rj="${by_run["$srv $scn"]:-}"
|
||||||
|
if [[ -n "$rj" ]]; then
|
||||||
|
p99=$(awk -F'"' '/"p99"/ {print $4; exit}' "$rj")
|
||||||
|
printf '| %14s ' "$p99"
|
||||||
|
else
|
||||||
|
printf '| %14s ' "—"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
printf '|\n'
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
|
||||||
|
# --- Spec pass/fail check, urus vs axum --------------------------------
|
||||||
|
# Per spec §6: urus RPS >= 50% of axum RPS on the same scenario.
|
||||||
|
printf '## Spec checks (urus vs axum)\n\n'
|
||||||
|
printf '| Scenario | urus RPS | axum RPS | urus/axum | within 2× of axum |\n'
|
||||||
|
printf '|----------|----------|----------|-----------|-------------------|\n'
|
||||||
|
for scn in "${scenarios_seen[@]}"; do
|
||||||
|
# Match urus-{mem,sqlite} against axum-{mem,sqlite} for the matching tier.
|
||||||
|
urus_run=""; axum_run=""
|
||||||
|
for k in "${!by_run[@]}"; do
|
||||||
|
set -- $k
|
||||||
|
s="$1"; sc="$2"
|
||||||
|
[[ "$sc" != "$scn" ]] && continue
|
||||||
|
case "$s" in
|
||||||
|
urus-*) urus_run="${by_run[$k]}" ;;
|
||||||
|
axum-*) axum_run="${by_run[$k]}" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
if [[ -n "$urus_run" && -n "$axum_run" ]]; then
|
||||||
|
u=$(awk -F'[:,]' '/"sustained_rps"/ {gsub(/[ "]/, "", $2); print $2; exit}' "$urus_run")
|
||||||
|
a=$(awk -F'[:,]' '/"sustained_rps"/ {gsub(/[ "]/, "", $2); print $2; exit}' "$axum_run")
|
||||||
|
ratio=$(awk -v u="$u" -v a="$a" 'BEGIN { if (a+0 > 0) printf "%.2f", (u+0)/(a+0); else print "n/a" }')
|
||||||
|
pass=$(awk -v r="$ratio" 'BEGIN { print (r != "n/a" && r+0 >= 0.5) ? "✅" : "❌" }')
|
||||||
|
printf '| %-8s | %8.0f | %8.0f | %9s | %-17s |\n' "$scn" "$u" "$a" "$ratio" "$pass"
|
||||||
|
else
|
||||||
|
printf '| %-8s | %8s | %8s | %9s | %-17s |\n' "$scn" "—" "—" "—" "—"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
|
||||||
|
# --- per-run detail links ----------------------------------------------
|
||||||
|
echo "## Per-run artefacts"
|
||||||
|
echo
|
||||||
|
for r in "${succeeded[@]}"; do
|
||||||
|
set -- $r
|
||||||
|
s="$1"; sc="$2"
|
||||||
|
echo "- \`${s}-${sc}/\` — [result.json](${s}-${sc}/result.json), [measure.txt](${s}-${sc}/measure.txt), [server.log](${s}-${sc}/server.log)"
|
||||||
|
done
|
||||||
|
if [[ "${#failed[@]}" -gt 0 ]]; then
|
||||||
|
echo
|
||||||
|
echo "### Failed runs"
|
||||||
|
for r in "${failed[@]}"; do
|
||||||
|
set -- $r
|
||||||
|
s="$1"; sc="$2"
|
||||||
|
echo "- \`${s}-${sc}\` — see \`${s}-${sc}.stdout.log\`"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
} > "$SUMMARY"
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Emit machine-readable index.json
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "{"
|
||||||
|
echo " \"batch\": \"${BATCH}\","
|
||||||
|
echo " \"elapsed_seconds\": ${ELAPSED},"
|
||||||
|
echo " \"runs\": ["
|
||||||
|
first=1
|
||||||
|
for k in "${!by_run[@]}"; do
|
||||||
|
set -- $k
|
||||||
|
s="$1"; sc="$2"
|
||||||
|
rj="${by_run[$k]}"
|
||||||
|
[[ "$first" -eq 1 ]] || echo " ,"
|
||||||
|
first=0
|
||||||
|
echo " {"
|
||||||
|
echo " \"server\": \"${s}\","
|
||||||
|
echo " \"scenario\": \"${sc}\","
|
||||||
|
echo " \"result_path\": \"${s}-${sc}/result.json\","
|
||||||
|
# Inline the result.json contents, indented; simplest is to just paste.
|
||||||
|
awk '/^\{/{p=1} p{print " " $0} /^\}/{p=0}' "$rj" \
|
||||||
|
| sed '1d' | head -n -1 | sed 's/^/ "result": {/; t; s/^/ /' >/dev/null
|
||||||
|
# Simpler: just reference the file path. The result.json is already
|
||||||
|
# right there. We don't need to inline.
|
||||||
|
echo " }"
|
||||||
|
done
|
||||||
|
echo " ]"
|
||||||
|
echo "}"
|
||||||
|
} > "$INDEX"
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Wrap up
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "=========================================================="
|
||||||
|
echo "run_all: DONE"
|
||||||
|
echo " batch: ${BATCH}"
|
||||||
|
echo " elapsed: ${ELAPSED}s"
|
||||||
|
echo " successful: ${#succeeded[@]} / ${total}"
|
||||||
|
[[ "${#failed[@]}" -gt 0 ]] && echo " failed: ${failed[*]}"
|
||||||
|
echo " summary: ${SUMMARY}"
|
||||||
|
echo "=========================================================="
|
||||||
|
echo
|
||||||
|
cat "$SUMMARY"
|
||||||
@@ -0,0 +1,367 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# urus-bench/runner.sh
|
||||||
|
#
|
||||||
|
# Runs one (server, scenario) measurement and saves all artefacts under
|
||||||
|
# results/${run_id}/. The intent is to make a single run trivially
|
||||||
|
# repeatable so the headline table in the bench-spec can be filled in
|
||||||
|
# row by row.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./runner.sh <server> <scenario> [run_id]
|
||||||
|
#
|
||||||
|
# server:
|
||||||
|
# urus-mem | urus-sqlite | axum-mem | axum-sqlite | cowboy-mem | cowboy-sqlite
|
||||||
|
# scenario:
|
||||||
|
# s1 | s2 | s3 | s4
|
||||||
|
# run_id:
|
||||||
|
# optional; defaults to ${date}-${server}-${scenario}
|
||||||
|
#
|
||||||
|
# Requirements on the host:
|
||||||
|
# - taskset (util-linux)
|
||||||
|
# - wrk2 in PATH (https://github.com/giltene/wrk2)
|
||||||
|
# - wrk in PATH (saturation probe)
|
||||||
|
# - pidstat (sysstat) -- optional, CPU stats only
|
||||||
|
# - jq -- pretty-prints the result.json
|
||||||
|
#
|
||||||
|
# CPU pinning (defaults; override with SERVER_CPUS / LOADGEN_CPUS):
|
||||||
|
# server: taskset -c 0-7
|
||||||
|
# loadgen: taskset -c 8-15
|
||||||
|
#
|
||||||
|
# Probe / measurement times: 30s probe, 30s warm-up, 60s measured (per the
|
||||||
|
# bench-spec §1.5). Override with PROBE_SEC / WARMUP_SEC / MEASURE_SEC.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Args / config
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
SERVER="${1:-}"
|
||||||
|
SCENARIO="${2:-}"
|
||||||
|
RUN_ID="${3:-$(date +%Y%m%d-%H%M%S)-${SERVER}-${SCENARIO}}"
|
||||||
|
|
||||||
|
if [[ -z "$SERVER" || -z "$SCENARIO" ]]; then
|
||||||
|
echo "usage: $0 <server> <scenario> [run_id]" >&2
|
||||||
|
echo " server: urus-mem | urus-sqlite | axum-mem | axum-sqlite | cowboy-mem | cowboy-sqlite" >&2
|
||||||
|
echo " scenario: s1 | s2 | s3 | s4" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
RESULTS_DIR="${REPO_ROOT}/results/${RUN_ID}"
|
||||||
|
mkdir -p "$RESULTS_DIR"
|
||||||
|
|
||||||
|
SERVER_CPUS="${SERVER_CPUS:-0-7}"
|
||||||
|
LOADGEN_CPUS="${LOADGEN_CPUS:-8-15}"
|
||||||
|
PROBE_SEC="${PROBE_SEC:-30}"
|
||||||
|
WARMUP_SEC="${WARMUP_SEC:-30}"
|
||||||
|
MEASURE_SEC="${MEASURE_SEC:-60}"
|
||||||
|
PORT="${PORT:-8080}"
|
||||||
|
HOST="${HOST:-127.0.0.1:${PORT}}"
|
||||||
|
BEARER="${BEARER:-test-token-aaaaaaaaaaaaaaaaaaaa}"
|
||||||
|
WRK_THREADS="${WRK_THREADS:-8}"
|
||||||
|
WRK_CONNS="${WRK_CONNS:-256}"
|
||||||
|
SAT_RATIO="${SAT_RATIO:-0.70}" # wrk2 target = saturation * SAT_RATIO
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Pick server command + lua script
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
case "$SERVER" in
|
||||||
|
urus-mem)
|
||||||
|
SERVER_CMD=("${REPO_ROOT}/target/release/urus-server"
|
||||||
|
"--addr=127.0.0.1:${PORT}" "--store=memory") ;;
|
||||||
|
urus-sqlite)
|
||||||
|
DB="/tmp/urus-bench-${RUN_ID}.sqlite"; rm -f "${DB}"*
|
||||||
|
SERVER_CMD=("${REPO_ROOT}/target/release/urus-server"
|
||||||
|
"--addr=127.0.0.1:${PORT}" "--store=sqlite"
|
||||||
|
"--db-path=${DB}") ;;
|
||||||
|
axum-mem)
|
||||||
|
SERVER_CMD=("${REPO_ROOT}/target/release/axum-server"
|
||||||
|
"--addr=127.0.0.1:${PORT}" "--store=memory") ;;
|
||||||
|
axum-sqlite)
|
||||||
|
DB="/tmp/axum-bench-${RUN_ID}.sqlite"; rm -f "${DB}"*
|
||||||
|
SERVER_CMD=("${REPO_ROOT}/target/release/axum-server"
|
||||||
|
"--addr=127.0.0.1:${PORT}" "--store=sqlite"
|
||||||
|
"--db-path=${DB}") ;;
|
||||||
|
cowboy-mem|cowboy-sqlite)
|
||||||
|
# cowboy-server is a placeholder in this checkout; wire when ready.
|
||||||
|
echo "runner: cowboy backends are not wired yet" >&2
|
||||||
|
exit 3 ;;
|
||||||
|
*)
|
||||||
|
echo "runner: unknown server '${SERVER}'" >&2; exit 2 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$SCENARIO" in
|
||||||
|
s1) LUA="${REPO_ROOT}/loadgen/s1_ping.lua" ;;
|
||||||
|
s2) LUA="${REPO_ROOT}/loadgen/s2_user_get.lua" ;;
|
||||||
|
s3) LUA="${REPO_ROOT}/loadgen/s3_mixed.lua" ;;
|
||||||
|
s4) LUA="${REPO_ROOT}/loadgen/s3_mixed.lua" ;; # same script, different store
|
||||||
|
*) echo "runner: unknown scenario '${SCENARIO}'" >&2; exit 2 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Compatibility check: s4 requires a sqlite-backed server.
|
||||||
|
if [[ "$SCENARIO" == "s4" && "$SERVER" != *-sqlite ]]; then
|
||||||
|
echo "runner: scenario s4 requires a *-sqlite server (got ${SERVER})" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Tool checks
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
need() {
|
||||||
|
command -v "$1" >/dev/null || { echo "runner: missing tool: $1" >&2; exit 4; }
|
||||||
|
}
|
||||||
|
need taskset
|
||||||
|
need wrk
|
||||||
|
need wrk2
|
||||||
|
|
||||||
|
HAS_PIDSTAT=0; command -v pidstat >/dev/null && HAS_PIDSTAT=1
|
||||||
|
HAS_JQ=0; command -v jq >/dev/null && HAS_JQ=1
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Verify the server binary actually exists before launching. Without this
|
||||||
|
# check, a missing binary surfaces as "server did not come up" 10 seconds
|
||||||
|
# later, which is misleading.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
SERVER_BIN="${SERVER_CMD[0]}"
|
||||||
|
if [[ ! -x "$SERVER_BIN" ]]; then
|
||||||
|
echo "runner: server binary not found or not executable: ${SERVER_BIN}" >&2
|
||||||
|
echo "runner: did you run \`cargo build --release\` in the workspace root?" >&2
|
||||||
|
exit 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Boot server (pinned), wait for it to listen
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
SERVER_LOG="${RESULTS_DIR}/server.log"
|
||||||
|
echo "runner: launching server on cores ${SERVER_CPUS}: ${SERVER_CMD[*]}"
|
||||||
|
taskset -c "$SERVER_CPUS" "${SERVER_CMD[@]}" \
|
||||||
|
> "$SERVER_LOG" 2>&1 &
|
||||||
|
SERVER_PID=$!
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
if kill -0 "$SERVER_PID" 2>/dev/null; then
|
||||||
|
kill "$SERVER_PID" 2>/dev/null || true
|
||||||
|
wait "$SERVER_PID" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
trap cleanup EXIT INT TERM
|
||||||
|
|
||||||
|
# Wait up to 10s for the port to accept.
|
||||||
|
for _ in $(seq 1 100); do
|
||||||
|
if (echo > /dev/tcp/127.0.0.1/${PORT}) 2>/dev/null; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
if ! (echo > /dev/tcp/127.0.0.1/${PORT}) 2>/dev/null; then
|
||||||
|
echo "runner: server did not come up; see ${SERVER_LOG}" >&2
|
||||||
|
exit 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Wire-level smoke test — fail fast if the routes don't behave.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
smoke_curl() {
|
||||||
|
local expected="$1"; shift
|
||||||
|
local got
|
||||||
|
got=$(curl -s -o /dev/null -w "%{http_code}" "$@")
|
||||||
|
if [[ "$got" != "$expected" ]]; then
|
||||||
|
echo "runner: smoke fail: expected ${expected} got ${got} for: $*" >&2
|
||||||
|
exit 6
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
smoke_curl 200 "http://127.0.0.1:${PORT}/ping"
|
||||||
|
smoke_curl 200 -H "Authorization: Bearer ${BEARER}" \
|
||||||
|
"http://127.0.0.1:${PORT}/api/v1/users"
|
||||||
|
smoke_curl 401 "http://127.0.0.1:${PORT}/api/v1/users"
|
||||||
|
|
||||||
|
echo "runner: smoke OK"
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Pre-populate store for s2/s3/s4 (s1 doesn't touch the store).
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# The s2 / s3 / s4 Lua scripts pick random IDs in [1, 10000]. Against an
|
||||||
|
# empty store every GET-by-id is a 404 fast path on most stacks, which is
|
||||||
|
# *not* what we want to bench. Seed the store with PREPOP=10000 users
|
||||||
|
# (matching the ID range) so GETs hit the actual happy path. This is also
|
||||||
|
# why the bench-spec calls for warm-up: pre-population is part of that.
|
||||||
|
#
|
||||||
|
# For s1 (/ping), skip prepop entirely.
|
||||||
|
|
||||||
|
PREPOP="${PREPOP:-10000}"
|
||||||
|
if [[ "$SCENARIO" != "s1" && "$PREPOP" -gt 0 ]]; then
|
||||||
|
echo "runner: pre-populating store with ${PREPOP} users"
|
||||||
|
TMP_REQUESTS=$(mktemp)
|
||||||
|
# awk is ~100x faster than a bash for-loop at producing this file.
|
||||||
|
awk -v n="$PREPOP" -v tok="$BEARER" -v port="$PORT" '
|
||||||
|
BEGIN {
|
||||||
|
for (i = 1; i <= n; i++) {
|
||||||
|
printf "url = http://127.0.0.1:%s/api/v1/users\n", port
|
||||||
|
printf "request = POST\n"
|
||||||
|
printf "header = \"Authorization: Bearer %s\"\n", tok
|
||||||
|
printf "header = \"Content-Type: application/json\"\n"
|
||||||
|
printf "data = \"{\\\"name\\\":\\\"u%d\\\",\\\"email\\\":\\\"u%d@x\\\"}\"\n", i, i
|
||||||
|
if (i < n) printf "next\n"
|
||||||
|
}
|
||||||
|
}' > "$TMP_REQUESTS"
|
||||||
|
# Send all curl output (response bodies + status) to the runner log.
|
||||||
|
# -K does not honor a global -o; the cleanest suppression is shell-level.
|
||||||
|
curl -s -K "$TMP_REQUESTS" >> "$SERVER_LOG" 2>&1 || true
|
||||||
|
rm -f "$TMP_REQUESTS"
|
||||||
|
# Verify list has at least one entry; print count for visibility.
|
||||||
|
N=$(curl -s -H "Authorization: Bearer ${BEARER}" \
|
||||||
|
"http://127.0.0.1:${PORT}/api/v1/users" | tr ',' '\n' | grep -c '"id"' || echo 0)
|
||||||
|
echo "runner: store now reports ${N} users (list cap is 100)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# pidstat sampler (background) — CPU% and RSS at 1Hz
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
STATS_LOG="${RESULTS_DIR}/proc-stats.tsv"
|
||||||
|
echo -e "ts\tcpu_pct\trss_kb" > "$STATS_LOG"
|
||||||
|
(
|
||||||
|
while kill -0 "$SERVER_PID" 2>/dev/null; do
|
||||||
|
ts=$(date +%s)
|
||||||
|
rss=$(awk '/^VmRSS:/ {print $2}' "/proc/${SERVER_PID}/status" 2>/dev/null || echo 0)
|
||||||
|
if [[ "$HAS_PIDSTAT" == "1" ]]; then
|
||||||
|
cpu=$(pidstat -p "$SERVER_PID" 1 1 2>/dev/null \
|
||||||
|
| awk '/Average:/ {print $8}' | head -1)
|
||||||
|
else
|
||||||
|
cpu=""
|
||||||
|
fi
|
||||||
|
echo -e "${ts}\t${cpu}\t${rss}" >> "$STATS_LOG"
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
) &
|
||||||
|
STATS_PID=$!
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Phase 1: saturation probe with wrk (closed-loop peak)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
echo "runner: probe (${PROBE_SEC}s closed-loop, ${WRK_CONNS} conns)"
|
||||||
|
PROBE_OUT="${RESULTS_DIR}/probe.txt"
|
||||||
|
taskset -c "$LOADGEN_CPUS" \
|
||||||
|
env HOST="$HOST" BEARER="$BEARER" \
|
||||||
|
wrk -t"$WRK_THREADS" -c"$WRK_CONNS" -d"${PROBE_SEC}s" --latency \
|
||||||
|
-s "$LUA" "http://${HOST}" \
|
||||||
|
> "$PROBE_OUT" 2>&1 || true
|
||||||
|
|
||||||
|
PROBE_RPS=$(awk '/Requests\/sec:/ {print $2}' "$PROBE_OUT" | head -1)
|
||||||
|
if [[ -z "$PROBE_RPS" ]]; then
|
||||||
|
echo "runner: probe did not report Requests/sec; see ${PROBE_OUT}" >&2
|
||||||
|
exit 7
|
||||||
|
fi
|
||||||
|
|
||||||
|
# floor(PROBE_RPS * SAT_RATIO) as an integer (wrk2 requires int -R)
|
||||||
|
TARGET_RPS=$(awk -v p="$PROBE_RPS" -v r="$SAT_RATIO" \
|
||||||
|
'BEGIN { printf("%d", int(p * r)) }')
|
||||||
|
echo "runner: probe RPS=${PROBE_RPS}, target (sustained)=${TARGET_RPS}"
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Phase 2: warm-up at target rate (discarded)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
echo "runner: warm-up (${WARMUP_SEC}s at -R${TARGET_RPS})"
|
||||||
|
taskset -c "$LOADGEN_CPUS" \
|
||||||
|
env HOST="$HOST" BEARER="$BEARER" \
|
||||||
|
wrk2 -t"$WRK_THREADS" -c"$WRK_CONNS" -d"${WARMUP_SEC}s" \
|
||||||
|
-R"$TARGET_RPS" -s "$LUA" "http://${HOST}" \
|
||||||
|
> "${RESULTS_DIR}/warmup.txt" 2>&1 || true
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Phase 3: measured run with wrk2 (latency-honest)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
echo "runner: measure (${MEASURE_SEC}s at -R${TARGET_RPS})"
|
||||||
|
MEASURE_OUT="${RESULTS_DIR}/measure.txt"
|
||||||
|
taskset -c "$LOADGEN_CPUS" \
|
||||||
|
env HOST="$HOST" BEARER="$BEARER" \
|
||||||
|
wrk2 -t"$WRK_THREADS" -c"$WRK_CONNS" -d"${MEASURE_SEC}s" \
|
||||||
|
-R"$TARGET_RPS" --latency \
|
||||||
|
-s "$LUA" "http://${HOST}" \
|
||||||
|
> "$MEASURE_OUT" 2>&1
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Phase 4: parse + write result.json
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# wrk2 output format (excerpt; this regex stack is fragile but works on
|
||||||
|
# upstream wrk2's current build):
|
||||||
|
#
|
||||||
|
# Requests/sec: 149999.74
|
||||||
|
# Latency Distribution (HdrHistogram - Recorded Latency)
|
||||||
|
# 50.000% 0.50ms
|
||||||
|
# 75.000% 0.61ms
|
||||||
|
# ...
|
||||||
|
# 99.000% 1.83ms
|
||||||
|
# 99.900% 4.21ms
|
||||||
|
# 99.990% 13.50ms
|
||||||
|
# 99.999% 24.50ms
|
||||||
|
# 100.000% 31.50ms
|
||||||
|
|
||||||
|
extract() {
|
||||||
|
local label="$1" # e.g. "50.000%"
|
||||||
|
awk -v lbl="$label" '$1 == lbl { print $2; exit }' "$MEASURE_OUT"
|
||||||
|
}
|
||||||
|
|
||||||
|
SUSTAINED_RPS=$(awk '/Requests\/sec:/ {print $2}' "$MEASURE_OUT" | head -1)
|
||||||
|
P50=$(extract "50.000%")
|
||||||
|
P90=$(extract "90.000%")
|
||||||
|
P99=$(extract "99.000%")
|
||||||
|
P999=$(extract "99.900%")
|
||||||
|
MAX=$(extract "100.000%")
|
||||||
|
NON_2XX=$(awk '/Non-2xx or 3xx responses:/ {print $5}' "$MEASURE_OUT" | head -1)
|
||||||
|
# Coerce to a JSON integer; empty (line absent → no errors) or non-numeric
|
||||||
|
# becomes 0.
|
||||||
|
if ! [[ "$NON_2XX" =~ ^[0-9]+$ ]]; then NON_2XX=0; fi
|
||||||
|
|
||||||
|
# Best-effort RSS / CPU summary from the sampler
|
||||||
|
MEAN_CPU=$(awk -F'\t' 'NR>1 && $2 != "" { s+=$2; n++ } END { if (n>0) printf("%.1f", s/n); else print "" }' "$STATS_LOG")
|
||||||
|
MAX_RSS=$(awk -F'\t' 'NR>1 { if ($3+0 > m) m=$3 } END { print m+0 }' "$STATS_LOG")
|
||||||
|
|
||||||
|
cat > "${RESULTS_DIR}/result.json" <<JSON
|
||||||
|
{
|
||||||
|
"run_id": "${RUN_ID}",
|
||||||
|
"server": "${SERVER}",
|
||||||
|
"scenario": "${SCENARIO}",
|
||||||
|
"probe_rps": ${PROBE_RPS},
|
||||||
|
"target_rps": ${TARGET_RPS},
|
||||||
|
"sustained_rps": ${SUSTAINED_RPS:-0},
|
||||||
|
"latency": {
|
||||||
|
"p50": "${P50}",
|
||||||
|
"p90": "${P90}",
|
||||||
|
"p99": "${P99}",
|
||||||
|
"p999": "${P999}",
|
||||||
|
"max": "${MAX}"
|
||||||
|
},
|
||||||
|
"non_2xx": ${NON_2XX},
|
||||||
|
"mean_cpu_pct": "${MEAN_CPU}",
|
||||||
|
"max_rss_kb": ${MAX_RSS}
|
||||||
|
}
|
||||||
|
JSON
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Done
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
kill "$STATS_PID" 2>/dev/null || true
|
||||||
|
wait "$STATS_PID" 2>/dev/null || true
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "runner: DONE -> ${RESULTS_DIR}"
|
||||||
|
if [[ "$HAS_JQ" == "1" ]]; then
|
||||||
|
jq . "${RESULTS_DIR}/result.json"
|
||||||
|
else
|
||||||
|
cat "${RESULTS_DIR}/result.json"
|
||||||
|
fi
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
# urus-bench shell.nix
|
||||||
|
#
|
||||||
|
# Assumes you already have a working rust toolchain (cargo, rustc) and
|
||||||
|
# elixir/erlang in your environment. This shell adds:
|
||||||
|
#
|
||||||
|
# - the load generators (wrk, wrk2)
|
||||||
|
# - process introspection (pidstat, taskset)
|
||||||
|
# - small conveniences (jq, sqlite CLI for poking at the WAL'd DBs)
|
||||||
|
# - C toolchain bits so `rusqlite` (bundled SQLite) and `sqlx` compile
|
||||||
|
#
|
||||||
|
# Drop into the workspace root and run `nix-shell`. Then:
|
||||||
|
# cargo build --release
|
||||||
|
# ./runner.sh urus-mem s1
|
||||||
|
#
|
||||||
|
# For cowboy-server you'll use your existing rebar3/elixir setup; this
|
||||||
|
# shell deliberately doesn't pin a beam toolchain since you have one.
|
||||||
|
|
||||||
|
{ pkgs ? import <nixpkgs> {} }:
|
||||||
|
|
||||||
|
pkgs.mkShell {
|
||||||
|
name = "urus-bench";
|
||||||
|
|
||||||
|
# buildInputs vs nativeBuildInputs: for a developer shell the
|
||||||
|
# distinction barely matters; either works. Keeping everything in
|
||||||
|
# `packages` since that's the recommended modern form.
|
||||||
|
packages = with pkgs; [
|
||||||
|
# Load generators (the whole point of this shell).
|
||||||
|
wrk # closed-loop, used as the saturation probe
|
||||||
|
wrk2 # constant-rate, latency-honest measurement
|
||||||
|
|
||||||
|
# Runner deps.
|
||||||
|
sysstat # provides pidstat for CPU sampling
|
||||||
|
util-linux # provides taskset for CPU pinning
|
||||||
|
jq # pretty-prints result.json (runner falls back without it)
|
||||||
|
curl # the prepopulate step uses curl --config (-K)
|
||||||
|
gawk # explicit; busybox awk lacks some printf bits we use
|
||||||
|
|
||||||
|
# SQLite tooling — handy for inspecting WAL'd DBs between runs.
|
||||||
|
# rusqlite/sqlx bring their own embedded sqlite so this is *not* a
|
||||||
|
# build dep, just a CLI for poking around.
|
||||||
|
sqlite
|
||||||
|
|
||||||
|
# C toolchain — rusqlite's `bundled` feature compiles sqlite from
|
||||||
|
# source, and sqlx's macros also need a working cc. Without these
|
||||||
|
# the rust build fails on a fresh nix shell.
|
||||||
|
pkg-config
|
||||||
|
gcc
|
||||||
|
];
|
||||||
|
|
||||||
|
# Environment hints. Nothing strictly required, but these defaults
|
||||||
|
# match what runner.sh already expects when invoked without env
|
||||||
|
# overrides, so a fresh shell `just works` for `./runner.sh ...`.
|
||||||
|
BEARER = "test-token-aaaaaaaaaaaaaaaaaaaa";
|
||||||
|
|
||||||
|
shellHook = ''
|
||||||
|
echo "urus-bench shell:"
|
||||||
|
echo " wrk $(wrk --version 2>&1 | head -1 || echo missing)"
|
||||||
|
echo " wrk2 $(wrk2 --version 2>&1 | head -1 || echo missing)"
|
||||||
|
echo " pidstat $(command -v pidstat || echo missing)"
|
||||||
|
echo " taskset $(command -v taskset || echo missing)"
|
||||||
|
echo " cargo $(command -v cargo || echo 'NOT FOUND — expected on host')"
|
||||||
|
echo
|
||||||
|
echo "Build: cargo build --release"
|
||||||
|
echo "Run: ./runner.sh urus-mem s1"
|
||||||
|
'';
|
||||||
|
}
|
||||||
Executable
+244
@@ -0,0 +1,244 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# spin_ab_urus.sh — A/B the RFC 004 spinning policy on the *realistic* urus
|
||||||
|
# workload (not the multi_scheduler microbench).
|
||||||
|
#
|
||||||
|
# It does exactly what the handoff asks: check out the pre-spin smarm commit,
|
||||||
|
# run the urus benches; check out the latest smarm commit, run them again;
|
||||||
|
# then print a before/after comparison.
|
||||||
|
#
|
||||||
|
# BEFORE = b0c9685 (pre-spin: no spinning code exists at all)
|
||||||
|
# AFTER = current smarm HEAD (spin defaults on + N=1 fix; e.g. 2f011f6)
|
||||||
|
#
|
||||||
|
# smarm is a *path dependency* of urus, which is a path dependency of
|
||||||
|
# urus-benches (all three are siblings). So we A/B by checking out smarm at
|
||||||
|
# each sha and rebuilding urus-benches; urus itself is held fixed — only the
|
||||||
|
# smarm under it changes between A and B. Each (commit, scenario, cores) run
|
||||||
|
# goes through the existing runner.sh (saturation probe -> warmup -> wrk2
|
||||||
|
# latency-honest measure) and lands a result.json; analyze_spin_ab_urus.py
|
||||||
|
# pairs them up at the end.
|
||||||
|
#
|
||||||
|
# Scenarios (per RECON §6.4): s2 (router+auth, no store) and s3 (memory store,
|
||||||
|
# the headline). Server is urus-mem for both. We do NOT touch s4/sqlite.
|
||||||
|
#
|
||||||
|
# Core sweep: the spin gate is active at 2-4 schedulers and inert at 1 and
|
||||||
|
# >=5. We sweep 1/2/4/6 server cores: 2 and 4 are gate-ACTIVE, 1 and 6 are
|
||||||
|
# inert controls -- 6 also being a *saturating* control, since the old 8-core
|
||||||
|
# point couldn't be saturated by an 8-core loadgen (it plateaued ~102k rps,
|
||||||
|
# loadgen-bound). Server is pinned to cores 0..N-1; the load generator gets
|
||||||
|
# its own disjoint cores (LOADGEN_CPUS), sized ~>=2x the server cores per the
|
||||||
|
# saturation goal while leaving cores free for the OS.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./spin_ab_urus.sh # full A/B, defaults
|
||||||
|
# ./spin_ab_urus.sh --quick # short timings (15s phases)
|
||||||
|
# ./spin_ab_urus.sh --dry-run # print the plan, run nothing
|
||||||
|
# CORES="2 4" SCENARIOS="s3" ./spin_ab_urus.sh
|
||||||
|
# BEFORE=b0c9685 AFTER=2f011f6 ./spin_ab_urus.sh
|
||||||
|
# ./spin_ab_urus.sh --with-axum-control # also run axum-mem (smarm-free
|
||||||
|
# # invariant; should be flat A vs B)
|
||||||
|
#
|
||||||
|
# Env knobs (all overridable):
|
||||||
|
# BEFORE / AFTER smarm commit-ishes (default b0c9685 / HEAD)
|
||||||
|
# SCENARIOS space-separated (default "s2 s3")
|
||||||
|
# CORES server core counts to sweep (default "1 2 4 6")
|
||||||
|
# LOADGEN_CPUS loadgen taskset range (default "8-23" = 16 cores)
|
||||||
|
# WRK_THREADS loadgen wrk/wrk2 threads (default 16)
|
||||||
|
# WRK_CONNS loadgen open connections (default 512)
|
||||||
|
# SERVER memory server backend (default urus-mem)
|
||||||
|
# PROBE_SEC/WARMUP_SEC/MEASURE_SEC/SAT_RATIO/PREPOP/WRK_CONNS/WRK_THREADS
|
||||||
|
# passed straight through to runner.sh
|
||||||
|
# SMARM_DIR override smarm location (default: sibling ../smarm)
|
||||||
|
# OUTDIR results dir (default: results/spin_ab_urus_<ts>)
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Locate the pieces
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
BENCH_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # urus-benches
|
||||||
|
RUNNER="${BENCH_DIR}/runner.sh"
|
||||||
|
ANALYZER="${BENCH_DIR}/analyze_spin_ab_urus.py"
|
||||||
|
SMARM_DIR="${SMARM_DIR:-$(cd "${BENCH_DIR}/../smarm" 2>/dev/null && pwd || true)}"
|
||||||
|
|
||||||
|
if [[ ! -x "$RUNNER" ]]; then
|
||||||
|
echo "ERROR: runner.sh not found/executable at $RUNNER" >&2; exit 1
|
||||||
|
fi
|
||||||
|
if [[ -z "$SMARM_DIR" || ! -d "$SMARM_DIR/.git" ]]; then
|
||||||
|
echo "ERROR: smarm git repo not found (looked for sibling ../smarm). Set SMARM_DIR." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Config
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
BEFORE="${BEFORE:-b0c9685}"
|
||||||
|
# AFTER defaults to whatever smarm is currently on ("the latest").
|
||||||
|
AFTER_DEFAULT="$(git -C "$SMARM_DIR" rev-parse --short HEAD)"
|
||||||
|
AFTER="${AFTER:-$AFTER_DEFAULT}"
|
||||||
|
|
||||||
|
SCENARIOS="${SCENARIOS:-s2 s3}"
|
||||||
|
CORES="${CORES:-1 2 4 6}"
|
||||||
|
SERVER="${SERVER:-urus-mem}"
|
||||||
|
LOADGEN_CPUS="${LOADGEN_CPUS:-8-23}"
|
||||||
|
|
||||||
|
# Loadgen sizing: ~2x loadgen cores per server core. 16 cores covers the
|
||||||
|
# 6-core server at ~2.7x and the 4-core at 4x. Threads track the core count;
|
||||||
|
# connections bumped so the probe can actually find the server's peak.
|
||||||
|
export WRK_THREADS="${WRK_THREADS:-16}"
|
||||||
|
export WRK_CONNS="${WRK_CONNS:-512}"
|
||||||
|
|
||||||
|
QUICK=0
|
||||||
|
DRY=0
|
||||||
|
WITH_AXUM=0
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--quick) QUICK=1 ;;
|
||||||
|
--dry-run|-n) DRY=1 ;;
|
||||||
|
--with-axum-control) WITH_AXUM=1 ;;
|
||||||
|
-h|--help) sed -n '2,/^set -euo/p' "$0" | sed 's/^# \{0,1\}//; $d'; exit 0 ;;
|
||||||
|
*) echo "unknown arg: $arg" >&2; exit 2 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$QUICK" == "1" ]]; then
|
||||||
|
export PROBE_SEC="${PROBE_SEC:-15}"
|
||||||
|
export WARMUP_SEC="${WARMUP_SEC:-15}"
|
||||||
|
export MEASURE_SEC="${MEASURE_SEC:-15}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
TS="$(date +%Y%m%d-%H%M%S)"
|
||||||
|
OUTDIR="${OUTDIR:-${BENCH_DIR}/results/spin_ab_urus_${TS}}"
|
||||||
|
|
||||||
|
NPROC="$(nproc)"
|
||||||
|
# Loadgen low core, for an overlap sanity check against the server range.
|
||||||
|
LG_LO="${LOADGEN_CPUS%%-*}"
|
||||||
|
|
||||||
|
SERVERS_TO_RUN=("$SERVER")
|
||||||
|
[[ "$WITH_AXUM" == "1" ]] && SERVERS_TO_RUN+=("axum-mem")
|
||||||
|
|
||||||
|
echo ">>> smarm: $SMARM_DIR"
|
||||||
|
echo ">>> BEFORE=$BEFORE AFTER=$AFTER"
|
||||||
|
echo ">>> servers: ${SERVERS_TO_RUN[*]}"
|
||||||
|
echo ">>> scenarios: $SCENARIOS"
|
||||||
|
echo ">>> cores: $CORES"
|
||||||
|
echo ">>> loadgen: cpus=$LOADGEN_CPUS threads=$WRK_THREADS conns=$WRK_CONNS"
|
||||||
|
echo ">>> machine: $NPROC cores"
|
||||||
|
echo ">>> outdir: $OUTDIR"
|
||||||
|
[[ "$QUICK" == "1" ]] && echo ">>> --quick: probe/warmup/measure = ${PROBE_SEC}/${WARMUP_SEC}/${MEASURE_SEC}s"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# server core range for a given count: "0" for 1, else "0-(N-1)"
|
||||||
|
server_cpus() { (( $1 == 1 )) && echo "0" || echo "0-$(( $1 - 1 ))"; }
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Safety: refuse a dirty smarm tree; restore original ref on exit
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if ! git -C "$SMARM_DIR" diff-index --quiet HEAD -- 2>/dev/null; then
|
||||||
|
echo "ERROR: smarm working tree is dirty. Commit/stash before A/B so checkouts are safe." >&2
|
||||||
|
git -C "$SMARM_DIR" status --short >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
ORIG_REF="$(git -C "$SMARM_DIR" symbolic-ref --quiet --short HEAD || git -C "$SMARM_DIR" rev-parse HEAD)"
|
||||||
|
restore_smarm() {
|
||||||
|
echo
|
||||||
|
echo ">>> restoring smarm to $ORIG_REF"
|
||||||
|
git -C "$SMARM_DIR" checkout --quiet "$ORIG_REF" 2>/dev/null \
|
||||||
|
|| echo "WARN: could not restore $ORIG_REF — smarm is on $(git -C "$SMARM_DIR" rev-parse --short HEAD)" >&2
|
||||||
|
}
|
||||||
|
[[ "$DRY" == "0" ]] && trap restore_smarm EXIT
|
||||||
|
|
||||||
|
# Overlap sanity: server top core must be below the loadgen range.
|
||||||
|
MAX_SRV=0; for c in $CORES; do (( c > MAX_SRV )) && MAX_SRV=$c; done
|
||||||
|
if [[ "$LG_LO" =~ ^[0-9]+$ ]] && (( MAX_SRV - 1 >= LG_LO )); then
|
||||||
|
echo "WARN: server cores reach $((MAX_SRV-1)) which overlaps LOADGEN_CPUS=$LOADGEN_CPUS." >&2
|
||||||
|
echo " set LOADGEN_CPUS to a disjoint range (two-process discipline)." >&2
|
||||||
|
fi
|
||||||
|
if (( MAX_SRV > NPROC )); then
|
||||||
|
echo "WARN: sweep asks for up to ${MAX_SRV} server cores but machine has ${NPROC}." >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$OUTDIR"
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Run one commit across the (server x scenario x cores) sub-matrix
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
run_commit() {
|
||||||
|
local sha="$1" label="$2"
|
||||||
|
echo "============================================================"
|
||||||
|
echo ">>> $label: checking out smarm $sha and rebuilding urus-benches"
|
||||||
|
echo "============================================================"
|
||||||
|
if [[ "$DRY" == "1" ]]; then
|
||||||
|
echo " [dry] git -C $SMARM_DIR checkout $sha"
|
||||||
|
echo " [dry] (cd $BENCH_DIR && cargo build --release)"
|
||||||
|
else
|
||||||
|
git -C "$SMARM_DIR" checkout --quiet "$sha"
|
||||||
|
# urus is a path dep of urus-benches and smarm a path dep of urus, so a
|
||||||
|
# workspace release build picks up the swapped smarm. cargo refingerprints
|
||||||
|
# on the changed sources.
|
||||||
|
( cd "$BENCH_DIR" && cargo build --release ) 2>&1 | tail -3
|
||||||
|
fi
|
||||||
|
|
||||||
|
for srv in "${SERVERS_TO_RUN[@]}"; do
|
||||||
|
for scn in $SCENARIOS; do
|
||||||
|
for c in $CORES; do
|
||||||
|
local scpus; scpus="$(server_cpus "$c")"
|
||||||
|
local run_id="${label}__${srv}__${scn}__c${c}"
|
||||||
|
local dest="${OUTDIR}/${label}/${srv}-${scn}-c${c}"
|
||||||
|
echo ">>> $label $srv $scn server-cores=$c (taskset $scpus) loadgen=$LOADGEN_CPUS"
|
||||||
|
if [[ "$DRY" == "1" ]]; then
|
||||||
|
echo " [dry] SERVER_CPUS=$scpus LOADGEN_CPUS=$LOADGEN_CPUS $RUNNER $srv $scn $run_id"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
mkdir -p "$dest"
|
||||||
|
if SERVER_CPUS="$scpus" LOADGEN_CPUS="$LOADGEN_CPUS" \
|
||||||
|
"$RUNNER" "$srv" "$scn" "$run_id" > "${dest}/runner.log" 2>&1; then
|
||||||
|
if [[ -d "${BENCH_DIR}/results/${run_id}" ]]; then
|
||||||
|
mv "${BENCH_DIR}/results/${run_id}/"* "$dest/" 2>/dev/null || true
|
||||||
|
rmdir "${BENCH_DIR}/results/${run_id}" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
local rps p99 non2xx ms errpct
|
||||||
|
rps=$(awk -F'[:,]' '/"sustained_rps"/ {gsub(/[ "]/,"",$2); print $2; exit}' "${dest}/result.json" 2>/dev/null || echo "?")
|
||||||
|
p99=$(awk -F'"' '/"p99"/ {print $4; exit}' "${dest}/result.json" 2>/dev/null || echo "?")
|
||||||
|
non2xx=$(awk -F'[:,]' '/"non_2xx"/ {gsub(/[ "]/,"",$2); print $2; exit}' "${dest}/result.json" 2>/dev/null || echo 0)
|
||||||
|
ms="${MEASURE_SEC:-60}"
|
||||||
|
# error rate vs approx total requests (sustained_rps * measure_sec).
|
||||||
|
errpct=$(awk -v n="$non2xx" -v r="$rps" -v s="$ms" \
|
||||||
|
'BEGIN { t=r*s; if (t>0) printf "%.1f", 100*n/t; else print "?" }')
|
||||||
|
if awk -v e="$errpct" 'BEGIN { exit !(e+0 > 2.0) }' 2>/dev/null; then
|
||||||
|
echo " -> VOID: ${errpct}% non-2xx (${non2xx}) — server is erroring, not serving. rps=${rps} is meaningless."
|
||||||
|
else
|
||||||
|
echo " -> sustained=${rps} rps p99=${p99} (non-2xx ${errpct}%)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo " -> FAILED (see ${dest}/runner.log)"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
run_commit "$BEFORE" "before"
|
||||||
|
run_commit "$AFTER" "after"
|
||||||
|
|
||||||
|
[[ "$DRY" == "1" ]] && { echo; echo ">>> dry run complete (nothing executed, smarm untouched)."; exit 0; }
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Analyze
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "============================================================"
|
||||||
|
echo ">>> A/B comparison"
|
||||||
|
echo "============================================================"
|
||||||
|
if command -v python3 >/dev/null && [[ -f "$ANALYZER" ]]; then
|
||||||
|
python3 "$ANALYZER" "$OUTDIR" --before before --after after | tee "${OUTDIR}/comparison.txt"
|
||||||
|
else
|
||||||
|
echo "(python3 or analyzer missing; raw result.json files are under $OUTDIR)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo ">>> DONE. results: $OUTDIR"
|
||||||
@@ -0,0 +1,462 @@
|
|||||||
|
# Urus v1 Benchmark Plan
|
||||||
|
|
||||||
|
> Goal: produce defensible HTTP/1.1 numbers for **urus v0.1**, framed by
|
||||||
|
> **hyper** (Rust async reference) above and **cowboy** (BEAM reference)
|
||||||
|
> below. Per the urus spec: target is **within 2x of hyper**; significantly
|
||||||
|
> outperform Cowboy 2 on HTTP/1.1.
|
||||||
|
|
||||||
|
The benchmark is layered, smallest-first, so we can see *what* costs what:
|
||||||
|
the plug indirection, the connection-actor context switch, the pipeline
|
||||||
|
middleware stack, and finally the DB layer.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Design considerations (read first)
|
||||||
|
|
||||||
|
### 1.1 Don't bench the DB
|
||||||
|
|
||||||
|
A "realistic" load that hits a DB on every request will almost certainly
|
||||||
|
bench the DB instead of the HTTP stack. SQLite single-writer contention is
|
||||||
|
the most likely culprit. The plan is:
|
||||||
|
|
||||||
|
- Tier the scenarios. The cheapest scenario does **no DB work** so we get a
|
||||||
|
clean read on the HTTP stack itself. Each subsequent tier adds one source
|
||||||
|
of work and is compared against the previous tier — the *delta* is the
|
||||||
|
cost of that layer.
|
||||||
|
- Instrument the handler with a histogram of "handler-inside time"
|
||||||
|
(microseconds spent between the start of the handler and the moment it
|
||||||
|
returns the `Conn`). If at high concurrency the handler-inside time
|
||||||
|
dominates request latency, we're benching the DB / the in-memory actor /
|
||||||
|
the auth check, not the framework. Report this metric *next to* RPS.
|
||||||
|
- For the DB tier, use **SQLite in WAL mode**, with one dedicated writer
|
||||||
|
actor and N reader connections (or a single-conn reader pool with `BEGIN
|
||||||
|
IMMEDIATE` semantics). This matches urus's actor-style data ownership and
|
||||||
|
is fair to all three frameworks.
|
||||||
|
- Cross-check by also running each scenario with the in-memory store from
|
||||||
|
`examples/crud.rs`. If urus's in-memory and SQLite numbers are close at
|
||||||
|
low write ratios, the DB is not the bottleneck; if SQLite is much lower,
|
||||||
|
it is.
|
||||||
|
|
||||||
|
### 1.2 wrk2, not wrk
|
||||||
|
|
||||||
|
`wrk` (Glenn's original) is closed-loop: it sends a new request only after
|
||||||
|
the previous one returns. Tail latency in that model is meaningless
|
||||||
|
("coordinated omission" — the load generator stalls when the server stalls,
|
||||||
|
so it can't *measure* the stall). We use **wrk2** with a fixed rate `-R`.
|
||||||
|
|
||||||
|
For a smoke-test top-end RPS we'll also run plain `wrk` at maximum offered
|
||||||
|
load to find each server's *saturation point*. That number is then used to
|
||||||
|
pick the target rate for wrk2 — typically 60–80% of saturation, where tail
|
||||||
|
latency is the actual measurement of interest.
|
||||||
|
|
||||||
|
Cross-checks: `oha` (open-loop, HDR-histogram output) and `rewrk`.
|
||||||
|
|
||||||
|
### 1.3 Equivalent stacks across servers
|
||||||
|
|
||||||
|
The bench is unfair unless the middleware stack is materially the same on
|
||||||
|
all three. Spec:
|
||||||
|
|
||||||
|
- Request logger (writes to a bounded ring buffer in memory; **no stdout**,
|
||||||
|
which would skew everything).
|
||||||
|
- Request ID middleware (generates a short ID, sets a response header).
|
||||||
|
- Bearer token auth (constant-time compare against a fixed valid token).
|
||||||
|
- JSON request/response on the write paths.
|
||||||
|
- Router with at least one literal route, one parameterised route, and one
|
||||||
|
POST route.
|
||||||
|
|
||||||
|
Cowboy's idiomatic equivalent is `cowboy_router` + handler modules + an
|
||||||
|
`onrequest` hook for auth. Hyper's idiomatic equivalent is **axum**: it
|
||||||
|
exposes the closest analogue to urus's pipeline (`tower::Service` + layers
|
||||||
|
+ Router). We bench against axum, and note that "raw hyper" would be 10–20%
|
||||||
|
faster but is not a fair comparison to a routing+middleware stack.
|
||||||
|
|
||||||
|
### 1.4 Two-process discipline
|
||||||
|
|
||||||
|
Server and load generator run on the **same host but with pinned, disjoint
|
||||||
|
CPU sets** to avoid each starving the other. On a 16-core box:
|
||||||
|
|
||||||
|
- Server: `taskset -c 0-7`
|
||||||
|
- Loadgen: `taskset -c 8-15`
|
||||||
|
|
||||||
|
This matters more than it sounds: with both on all cores, you measure the
|
||||||
|
loadgen's scheduling as much as the server's.
|
||||||
|
|
||||||
|
### 1.5 Warm-up
|
||||||
|
|
||||||
|
Each run is `30s warm-up + 60s measured`. The warm-up is necessary because:
|
||||||
|
- TCP window scaling needs time to ramp.
|
||||||
|
- Page-fault costs for the read buffers happen once.
|
||||||
|
- BEAM in particular has a JIT (BeamAsm) that benefits from warm-up.
|
||||||
|
|
||||||
|
Save raw HDR histograms (wrk2 emits one); aggregate p50/p95/p99/p99.9/max.
|
||||||
|
|
||||||
|
### 1.6 What we don't measure (yet)
|
||||||
|
|
||||||
|
- TLS: deferred per urus spec (v2+).
|
||||||
|
- HTTP/2: deferred per urus spec (v2).
|
||||||
|
- WebSocket: deferred (v3).
|
||||||
|
- Cold-start / spawn cost: orthogonal to the steady-state question this
|
||||||
|
bench answers.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Scenarios
|
||||||
|
|
||||||
|
Four scenarios, ordered cheapest to most realistic. Each is run against
|
||||||
|
each framework. Each measures the **delta** over the previous one.
|
||||||
|
|
||||||
|
### S1: `GET /ping` — naked hello world
|
||||||
|
|
||||||
|
- Pipeline: a single handler. No logger, no auth, no router.
|
||||||
|
- Response: `200 OK`, body `pong` (4 bytes), `content-type: text/plain`.
|
||||||
|
- Measures: raw protocol throughput. The floor on framework overhead.
|
||||||
|
- Connection: keep-alive (default in HTTP/1.1).
|
||||||
|
|
||||||
|
This is the number to compare against hyper's `hello` benchmark. The urus
|
||||||
|
spec target is "within 2x". The plug pipeline isn't really exercised here —
|
||||||
|
that's deliberate. S1 isolates the connection actor + parser + serialiser.
|
||||||
|
|
||||||
|
### S2: `GET /api/v1/users/:id` — router + middleware, no DB
|
||||||
|
|
||||||
|
- Pipeline: `logger → request_id → auth → router`.
|
||||||
|
- Route: `GET /api/v1/users/:id` returns a hard-coded `User` struct
|
||||||
|
serialised to JSON. The `:id` is echoed into the response so the
|
||||||
|
serialiser cannot const-fold it away.
|
||||||
|
- Bearer token check: a known good token sent in the `Authorization`
|
||||||
|
header. Mismatch → 401 + halt.
|
||||||
|
- Measures: the cost of the pipeline (4 plug hops) and the router lookup.
|
||||||
|
This is where urus's spec budget ("one vtable dispatch per plug per
|
||||||
|
request") gets tested.
|
||||||
|
- Connection: keep-alive.
|
||||||
|
|
||||||
|
Expected: lower RPS than S1 by a measurable but non-catastrophic margin (a
|
||||||
|
few % to maybe 20%). If S2 is half of S1, something is allocating per
|
||||||
|
request.
|
||||||
|
|
||||||
|
### S3: `POST /api/v1/users` + `GET /api/v1/users/:id` — in-memory store
|
||||||
|
|
||||||
|
- Pipeline: same as S2.
|
||||||
|
- Routes:
|
||||||
|
- `POST /api/v1/users` with a small JSON body (`{"name":"alice","email":"a@x"}`).
|
||||||
|
- `GET /api/v1/users/:id`.
|
||||||
|
- `GET /api/v1/users` (list, capped at 100).
|
||||||
|
- Store: in-memory actor (urus: the actor from `examples/crud.rs`; hyper:
|
||||||
|
`tokio::sync::Mutex<HashMap>`; cowboy: a `gen_server`). No persistence.
|
||||||
|
- Traffic mix: **80% GET single, 15% GET list, 5% POST**. This is the
|
||||||
|
typical web-app shape and exposes the message-passing path on urus
|
||||||
|
without making writes the bottleneck.
|
||||||
|
- Measures: actor channel round-trip vs. mutex contention. Urus does a
|
||||||
|
channel send-recv to its store; hyper holds a brief mutex. The bench
|
||||||
|
shows the cost of message passing vs. the cost of contention as
|
||||||
|
concurrency rises.
|
||||||
|
- Connection: keep-alive.
|
||||||
|
|
||||||
|
### S4: Same as S3, with SQLite (WAL)
|
||||||
|
|
||||||
|
- Same routes and mix as S3.
|
||||||
|
- Backing store:
|
||||||
|
- urus: one writer actor owning a write connection; reads go through a
|
||||||
|
pool of N=`min(cpus, 4)` read-only connections (each held by its own
|
||||||
|
actor, requested via a worker pool). All `BEGIN IMMEDIATE`.
|
||||||
|
- hyper/axum: `sqlx::SqlitePool` with WAL + busy_timeout.
|
||||||
|
- cowboy: `esqlite` with the same WAL config; pool via `poolboy`.
|
||||||
|
- Measures: realism. We expect everyone to be much lower here. If the
|
||||||
|
three framework numbers *converge*, the DB is the bottleneck and the
|
||||||
|
framework comparison can't be made from this scenario alone — that's
|
||||||
|
the answer S4 might give us, and it's still useful information.
|
||||||
|
|
||||||
|
In **all four scenarios** the handler instruments
|
||||||
|
`handler_microseconds_histogram` so we can detect DB domination.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. The middleware stack (spec for all three implementations)
|
||||||
|
|
||||||
|
Each implementation MUST expose these middlewares with materially identical
|
||||||
|
behaviour. The wire-level outputs (status codes, body shapes, headers) MUST
|
||||||
|
match — verified by a small `curl`-based smoke test before each bench run.
|
||||||
|
|
||||||
|
### 3.1 Logger
|
||||||
|
|
||||||
|
- Captures: `method`, `path`, `status`, `elapsed_us`.
|
||||||
|
- Writes into a **bounded ring buffer in memory** (e.g. `crossbeam::ArrayQueue<LogEntry>` for Rust, an ETS table for cowboy with capped size).
|
||||||
|
- Does **not** touch stdout, stderr, or the filesystem during the run.
|
||||||
|
- The buffer is drained on shutdown to a file for inspection.
|
||||||
|
|
||||||
|
### 3.2 Request ID
|
||||||
|
|
||||||
|
- 12-byte random ID, base32-encoded.
|
||||||
|
- Set as response header `x-request-id`.
|
||||||
|
- Generated from a thread-local fast RNG (avoid the global `rand::thread_rng()` mutex on Rust; use SplitMix64 seeded once per actor/task).
|
||||||
|
|
||||||
|
### 3.3 Auth
|
||||||
|
|
||||||
|
- Reads `Authorization: Bearer <token>` from request headers.
|
||||||
|
- Compares against a fixed token (configured at startup) using
|
||||||
|
**constant-time compare** (`subtle::ConstantTimeEq` on Rust;
|
||||||
|
`crypto:hash`-based on BEAM is fine — the constant-time property is
|
||||||
|
pedagogical here, not a security claim).
|
||||||
|
- On mismatch: `401`, body `{"error":"unauthorized"}`, halt the pipeline.
|
||||||
|
- The bench load generator always sends the valid token (we are not
|
||||||
|
benching the failure path).
|
||||||
|
|
||||||
|
### 3.4 Router
|
||||||
|
|
||||||
|
- Methods: GET, POST, PUT, DELETE.
|
||||||
|
- Patterns: `/api/v1/users`, `/api/v1/users/:id`, `/ping`.
|
||||||
|
- 404 on no match; 405 on method-mismatch (urus already does this).
|
||||||
|
|
||||||
|
### 3.5 JSON
|
||||||
|
|
||||||
|
- `serde_json` for Rust, `jsx` or `jsone` for BEAM.
|
||||||
|
- Bodies are small: well under 1 KiB for the user payload.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Queries (load-gen scripts)
|
||||||
|
|
||||||
|
`wrk2` takes a Lua script. Below are the four scripts. They share a single
|
||||||
|
common header script (`common.lua`) for token + content-type.
|
||||||
|
|
||||||
|
### `common.lua`
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- Shared header config; included by every script below.
|
||||||
|
local M = {}
|
||||||
|
M.token = os.getenv("BEARER") or "test-token-aaaaaaaaaaaaaaaaaaaa"
|
||||||
|
M.headers = {
|
||||||
|
["Authorization"] = "Bearer " .. M.token,
|
||||||
|
["Connection"] = "keep-alive",
|
||||||
|
["Host"] = os.getenv("HOST") or "127.0.0.1:8080",
|
||||||
|
}
|
||||||
|
return M
|
||||||
|
```
|
||||||
|
|
||||||
|
### `s1_ping.lua` — S1 ping, no auth header (it's a naked endpoint)
|
||||||
|
|
||||||
|
```lua
|
||||||
|
wrk.method = "GET"
|
||||||
|
wrk.path = "/ping"
|
||||||
|
wrk.headers["Connection"] = "keep-alive"
|
||||||
|
```
|
||||||
|
|
||||||
|
Invocation:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Saturation probe (closed-loop wrk):
|
||||||
|
wrk -t8 -c256 -d60s --latency http://127.0.0.1:8080/ping
|
||||||
|
|
||||||
|
# Latency-honest measurement (wrk2, target rate from probe):
|
||||||
|
wrk2 -t8 -c256 -d60s -R200000 --latency -s s1_ping.lua \
|
||||||
|
http://127.0.0.1:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
### `s2_user_get.lua` — single-route GET with middleware
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local common = require("common")
|
||||||
|
wrk.method = "GET"
|
||||||
|
wrk.headers = common.headers
|
||||||
|
|
||||||
|
-- Spread :id across 10_000 values so per-id caches can't trivially win.
|
||||||
|
math.randomseed(os.time() + os.getpid())
|
||||||
|
request = function()
|
||||||
|
local id = math.random(1, 10000)
|
||||||
|
return wrk.format(nil, "/api/v1/users/" .. id)
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Invocation:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
wrk2 -t8 -c256 -d60s -R150000 --latency -s s2_user_get.lua \
|
||||||
|
http://127.0.0.1:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
### `s3_mixed.lua` — 80% GET-one / 15% GET-list / 5% POST
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local common = require("common")
|
||||||
|
wrk.headers = common.headers
|
||||||
|
wrk.headers["Content-Type"] = "application/json"
|
||||||
|
|
||||||
|
math.randomseed(os.time() + os.getpid())
|
||||||
|
local body_pool = {}
|
||||||
|
for i = 1, 64 do
|
||||||
|
body_pool[i] = string.format(
|
||||||
|
[[{"name":"user%d","email":"u%d@example.test"}]], i, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
request = function()
|
||||||
|
local r = math.random()
|
||||||
|
if r < 0.80 then
|
||||||
|
return wrk.format("GET", "/api/v1/users/" .. math.random(1, 10000))
|
||||||
|
elseif r < 0.95 then
|
||||||
|
return wrk.format("GET", "/api/v1/users")
|
||||||
|
else
|
||||||
|
local body = body_pool[math.random(1, #body_pool)]
|
||||||
|
return wrk.format("POST", "/api/v1/users", nil, body)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Invocation: same shape as s2, lower `-R` (writes are slower).
|
||||||
|
|
||||||
|
```sh
|
||||||
|
wrk2 -t8 -c512 -d60s -R80000 --latency -s s3_mixed.lua \
|
||||||
|
http://127.0.0.1:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
### `s4_mixed_sqlite.lua`
|
||||||
|
|
||||||
|
Identical to `s3_mixed.lua`. Only the server's backing store differs.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
wrk2 -t8 -c512 -d60s -R20000 --latency -s s4_mixed_sqlite.lua \
|
||||||
|
http://127.0.0.1:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
(`-R20000` is a guess; the real number comes from a `wrk` probe of each
|
||||||
|
framework first.)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Implementation plan
|
||||||
|
|
||||||
|
Three sibling crates / projects under a `urus-bench/` workspace, each
|
||||||
|
exposing the same routes and middleware:
|
||||||
|
|
||||||
|
```
|
||||||
|
urus-bench/
|
||||||
|
├── urus-server/ # Rust, urus
|
||||||
|
├── axum-server/ # Rust, hyper via axum
|
||||||
|
└── cowboy-server/ # Erlang/OTP, cowboy 2
|
||||||
|
```
|
||||||
|
|
||||||
|
Plus:
|
||||||
|
|
||||||
|
```
|
||||||
|
urus-bench/
|
||||||
|
├── loadgen/ # wrk2 scripts (common.lua, s1..s4 above)
|
||||||
|
├── runner.sh # orchestrates pin-cpu, warm-up, measurement, save HDR
|
||||||
|
└── results/ # one subdir per run: ${date}-${server}-${scenario}/
|
||||||
|
```
|
||||||
|
|
||||||
|
The runner:
|
||||||
|
|
||||||
|
1. Boots the target server pinned to cores 0-7.
|
||||||
|
2. `curl`-smoke-tests every route.
|
||||||
|
3. Probes saturation with `wrk` at a high `-c`.
|
||||||
|
4. Reads back the saturation RPS and chooses 70% of it for wrk2.
|
||||||
|
5. Runs wrk2 with HDR output (`--latency`), captures stdout + HDR file.
|
||||||
|
6. Greps server process for RSS (`/proc/$pid/status`) and CPU (`pidstat -p $pid 1`) during the run.
|
||||||
|
7. Saves everything under `results/${run_id}/`.
|
||||||
|
8. Kills server, sleeps 5s, moves on.
|
||||||
|
|
||||||
|
### 5.1 urus-server
|
||||||
|
|
||||||
|
Port `examples/crud.rs` with:
|
||||||
|
|
||||||
|
- Routes adjusted to `/api/v1/users{,/:id}` and `/ping`.
|
||||||
|
- Logger replaced with a ring-buffer-backed plug.
|
||||||
|
- New `request_id` and `auth` plugs.
|
||||||
|
- Switchable backing store: `--store=memory` (the existing actor) or
|
||||||
|
`--store=sqlite` (a new actor wrapping `rusqlite` in WAL).
|
||||||
|
|
||||||
|
For SQLite on urus: spawn one writer actor + 4 reader actors, each owning
|
||||||
|
its own `rusqlite::Connection`. Handlers route reads to a free reader via
|
||||||
|
a worker-pool channel, writes to the writer. Pool selection is FIFO over a
|
||||||
|
single shared `Receiver<RequestForReader>` — readers race to receive, which
|
||||||
|
is exactly what smarm's MPSC gives for free.
|
||||||
|
|
||||||
|
### 5.2 axum-server
|
||||||
|
|
||||||
|
Standard axum + tokio multi-thread. Same routes. Layers: `Logger`,
|
||||||
|
`SetRequestIdLayer`, `RequireAuthorizationLayer`. State: `sqlx::SqlitePool`
|
||||||
|
for S4, `Arc<RwLock<HashMap>>` for S3.
|
||||||
|
|
||||||
|
### 5.3 cowboy-server
|
||||||
|
|
||||||
|
Standard cowboy 2 with `cowboy_router`. Handlers as `cowboy_handler`
|
||||||
|
modules. Auth as an `onrequest`-style middleware. Store: a `gen_server`
|
||||||
|
for S3, `esqlite` + `poolboy` for S4.
|
||||||
|
|
||||||
|
Build with `rebar3`, run with `+S 8 +sbt db` (8 schedulers, scheduler-thread
|
||||||
|
binding) under the same `taskset -c 0-7`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Metrics and reporting
|
||||||
|
|
||||||
|
Per (server × scenario) run, capture and report:
|
||||||
|
|
||||||
|
| Metric | How |
|
||||||
|
|-----------------------------|------------------------------------------------|
|
||||||
|
| RPS (saturation, `wrk`) | `wrk -c256 -d60s` — closed-loop peak |
|
||||||
|
| RPS (sustained, `wrk2`) | `wrk2 -R$target -d60s` at 70% of saturation |
|
||||||
|
| p50 / p95 / p99 / p99.9 / max latency | HDR histogram from wrk2 |
|
||||||
|
| Server CPU% | `pidstat -p $pid 1 60` → mean over run |
|
||||||
|
| Server RSS | `/proc/$pid/status` `VmRSS` sampled at 1 Hz |
|
||||||
|
| Handler-inside p99 (µs) | server-side histogram, emitted to ring buffer |
|
||||||
|
| Dropped/errored requests | wrk2's "Non-2xx or 3xx responses" |
|
||||||
|
|
||||||
|
The headline table:
|
||||||
|
|
||||||
|
| | urus | axum | cowboy |
|
||||||
|
|--------------------|------|------|--------|
|
||||||
|
| S1 RPS (sat) | | | |
|
||||||
|
| S1 p99 @ 70% | | | |
|
||||||
|
| S2 RPS (sat) | | | |
|
||||||
|
| S2 p99 @ 70% | | | |
|
||||||
|
| S3 RPS (sat) | | | |
|
||||||
|
| S3 p99 @ 70% | | | |
|
||||||
|
| S4 RPS (sat) | | | |
|
||||||
|
| S4 p99 @ 70% | | | |
|
||||||
|
| urus / axum (S1) | — | | — |
|
||||||
|
| urus / axum (S2) | — | | — |
|
||||||
|
|
||||||
|
Pass/fail per the urus spec:
|
||||||
|
|
||||||
|
- **S1**: urus RPS ≥ 50% of axum RPS (within 2x).
|
||||||
|
- **S2**: urus RPS ≥ 50% of axum RPS.
|
||||||
|
- **All scenarios**: urus RPS > cowboy RPS by a clear margin (native
|
||||||
|
expectation).
|
||||||
|
- **All scenarios**: urus p99 < 2× axum p99 at the same offered rate.
|
||||||
|
- Handler-inside p99 ≪ end-to-end p99 in S1/S2 (proves we're benching the
|
||||||
|
framework, not the handler).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Order of operations (suggested)
|
||||||
|
|
||||||
|
1. Build `urus-server` with S1 (`/ping`) only. Run S1 against it. Make
|
||||||
|
sure the saturation number is plausible (tens to hundreds of kRPS on
|
||||||
|
a decent box).
|
||||||
|
2. Build `axum-server` with S1. Run S1. Sanity-check the ratio against
|
||||||
|
public hyper hello-world numbers (axum should land near hyper).
|
||||||
|
3. Add the middleware stack to both, run S2, capture deltas.
|
||||||
|
4. Add the in-memory store, run S3.
|
||||||
|
5. Bring up `cowboy-server` and bring all three up to S3.
|
||||||
|
6. Add SQLite to all three; run S4.
|
||||||
|
7. Write the headline table; produce HDR plots from the saved files
|
||||||
|
(gnuplot or a tiny Python script — wrk2 ships an HDR-plot helper).
|
||||||
|
|
||||||
|
If at any point a tier's results are dominated by a non-framework cost
|
||||||
|
(handler-inside p99 ≥ ~50% of end-to-end p99), stop and instrument before
|
||||||
|
moving on. That's the whole point of tiering.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Open questions deliberately left for later
|
||||||
|
|
||||||
|
- Whether to also bench under `tc`-induced packet loss / RTT. The current
|
||||||
|
setup uses loopback, which is a generous environment. A loopback win is
|
||||||
|
necessary but not sufficient for "fast on the real network".
|
||||||
|
- Whether to bench HTTP/1.1 pipelining (multiple in-flight requests per
|
||||||
|
connection without waiting). urus claims it's a non-goal-for-now, and
|
||||||
|
axum/hyper don't pipeline either, so the comparison is moot — but it's
|
||||||
|
worth a note.
|
||||||
|
- Whether to add a "slow handler" scenario (one route that sleeps 50ms)
|
||||||
|
to demonstrate urus's blocking-handler-without-thread-pool claim. That's
|
||||||
|
more of a *qualitative* demo than a throughput bench, but it's the kind
|
||||||
|
of thing reviewers ask about.
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
[package]
|
||||||
|
name = "urus-server"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
rust-version = "1.95"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
# Path deps point at the user's local checkouts; adjust if your tree
|
||||||
|
# differs. urus's own Cargo.toml has `smarm = { path = "../smarm" }`, so
|
||||||
|
# cargo resolves smarm transitively as long as it's a sibling of urus.
|
||||||
|
urus = { path = "../../urus" }
|
||||||
|
smarm = { path = "../../smarm" }
|
||||||
|
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
serde_json = "1"
|
||||||
|
|
||||||
|
# Constant-time compare for the bearer-token check. Tiny dep, no transitive
|
||||||
|
# bloat, and the right thing to use.
|
||||||
|
subtle = "2"
|
||||||
|
|
||||||
|
# In-memory ring buffer for the logger plug. Bounded MPSC over a fixed
|
||||||
|
# array — no allocation on the hot path.
|
||||||
|
crossbeam-queue = "0.3"
|
||||||
|
|
||||||
|
# Embedded SQLite. The `bundled` feature compiles SQLite from source so we
|
||||||
|
# don't depend on the system library — important for reproducibility on
|
||||||
|
# build hosts that may or may not have libsqlite3-dev.
|
||||||
|
rusqlite = { version = "0.32", features = ["bundled"] }
|
||||||
|
|
||||||
|
# Tiny argv parser so we don't pull in clap for a 3-flag CLI.
|
||||||
|
# We hand-roll it instead. No dep here.
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "urus-server"
|
||||||
|
path = "src/main.rs"
|
||||||
@@ -0,0 +1,172 @@
|
|||||||
|
//! Request handlers and the AppState that holds the store-handle factory.
|
||||||
|
//!
|
||||||
|
//! The trick: smarm requires `spawn` (and `gen_server::start`) to be called
|
||||||
|
//! from inside an actor. The bootstrap thread that calls `serve_with` is NOT
|
||||||
|
//! an actor — it's the user's main(). So we can't spawn the store actor at
|
||||||
|
//! startup; we defer to the first request that asks for it. That request runs
|
||||||
|
//! inside a connection actor, which is a valid place to spawn.
|
||||||
|
//!
|
||||||
|
//! AppState holds:
|
||||||
|
//! - a "store_init" factory that lazily spawns the store on first use
|
||||||
|
//! and caches the resulting StoreHandle
|
||||||
|
//! - the shared log ring (not yet used here; handlers don't log
|
||||||
|
//! directly, the logger plug does)
|
||||||
|
//!
|
||||||
|
//! Concurrency: the first connection actor to ask wins the init race;
|
||||||
|
//! the rest see the already-initialised handle. We use OnceLock for this
|
||||||
|
//! — std primitive, no extra dep.
|
||||||
|
|
||||||
|
use std::sync::{Arc, OnceLock};
|
||||||
|
|
||||||
|
use urus::{Conn, Next, Plug, Router};
|
||||||
|
|
||||||
|
use crate::middleware::LogRing;
|
||||||
|
use crate::store::{StoreHandle, StoreReq};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// AppState
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct AppState {
|
||||||
|
inner: Arc<AppStateInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AppStateInner {
|
||||||
|
store_handle: OnceLock<StoreHandle>,
|
||||||
|
store_init: Arc<dyn Fn() -> StoreHandle + Send + Sync + 'static>,
|
||||||
|
// Kept for parity with the spec even though handlers don't read it.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
log_ring: LogRing,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AppState {
|
||||||
|
pub fn new(
|
||||||
|
store_init: Arc<dyn Fn() -> StoreHandle + Send + Sync + 'static>,
|
||||||
|
log_ring: LogRing,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: Arc::new(AppStateInner {
|
||||||
|
store_handle: OnceLock::new(),
|
||||||
|
store_init,
|
||||||
|
log_ring,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Lazy store accessor. Safe to call from inside any connection
|
||||||
|
/// actor; safe to call concurrently — `OnceLock::get_or_init`
|
||||||
|
/// guarantees the init closure runs exactly once.
|
||||||
|
pub fn store(&self) -> &StoreHandle {
|
||||||
|
self.inner.store_handle.get_or_init(|| (self.inner.store_init)())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Tiny helpers
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
fn json(conn: Conn, status: u16, body: Vec<u8>) -> Conn {
|
||||||
|
conn.put_status(status)
|
||||||
|
.put_header("content-type", "application/json")
|
||||||
|
.put_body(body)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn text(conn: Conn, status: u16, body: &'static str) -> Conn {
|
||||||
|
conn.put_status(status)
|
||||||
|
.put_header("content-type", "text/plain; charset=utf-8")
|
||||||
|
.put_body(body)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_id(s: &str) -> Option<u64> { s.parse().ok() }
|
||||||
|
|
||||||
|
const STORE_UNAVAILABLE: &[u8] = b"{\"error\":\"store unavailable\"}";
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Handlers
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// All handlers close over a clone of AppState. Each handler closure is a
|
||||||
|
// `Fn(Conn, Next) -> Conn`, which is exactly the Plug shape urus's blanket
|
||||||
|
// impl picks up. A request is now a single `store().call(...)`: the gen_server
|
||||||
|
// `call` builds the reply channel, sends, and parks for the reply, so the
|
||||||
|
// old per-handler channel + send + recv boilerplate is gone.
|
||||||
|
|
||||||
|
fn build_ping_handler() -> impl Plug {
|
||||||
|
// /ping is a literal endpoint: status 200, body "pong". No work.
|
||||||
|
move |conn: Conn, _next: Next| text(conn, 200, "pong")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_list_handler(state: AppState) -> impl Plug {
|
||||||
|
move |conn: Conn, _next: Next| {
|
||||||
|
match state.store().call(StoreReq::List) {
|
||||||
|
Ok((s, b)) => json(conn, s, b),
|
||||||
|
Err(_) => json(conn, 503, STORE_UNAVAILABLE.to_vec()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_get_one_handler(state: AppState) -> impl Plug {
|
||||||
|
move |conn: Conn, _next: Next| {
|
||||||
|
let id = match conn.params.get("id").and_then(parse_id) {
|
||||||
|
Some(id) => id,
|
||||||
|
None => return json(conn, 400, b"{\"error\":\"bad id\"}".to_vec()),
|
||||||
|
};
|
||||||
|
match state.store().call(StoreReq::Get { id }) {
|
||||||
|
Ok((s, b)) => json(conn, s, b),
|
||||||
|
Err(_) => json(conn, 503, STORE_UNAVAILABLE.to_vec()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_create_handler(state: AppState) -> impl Plug {
|
||||||
|
move |conn: Conn, _next: Next| {
|
||||||
|
// Clone the body bytes out; we still need `conn` to build the reply.
|
||||||
|
let body = conn.body.as_bytes().to_vec();
|
||||||
|
match state.store().call(StoreReq::Create { body }) {
|
||||||
|
Ok((s, b)) => json(conn, s, b),
|
||||||
|
Err(_) => json(conn, 503, STORE_UNAVAILABLE.to_vec()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_update_handler(state: AppState) -> impl Plug {
|
||||||
|
move |conn: Conn, _next: Next| {
|
||||||
|
let id = match conn.params.get("id").and_then(parse_id) {
|
||||||
|
Some(id) => id,
|
||||||
|
None => return json(conn, 400, b"{\"error\":\"bad id\"}".to_vec()),
|
||||||
|
};
|
||||||
|
let body = conn.body.as_bytes().to_vec();
|
||||||
|
match state.store().call(StoreReq::Update { id, body }) {
|
||||||
|
Ok((s, b)) => json(conn, s, b),
|
||||||
|
Err(_) => json(conn, 503, STORE_UNAVAILABLE.to_vec()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_delete_handler(state: AppState) -> impl Plug {
|
||||||
|
move |conn: Conn, _next: Next| {
|
||||||
|
let id = match conn.params.get("id").and_then(parse_id) {
|
||||||
|
Some(id) => id,
|
||||||
|
None => return json(conn, 400, b"{\"error\":\"bad id\"}".to_vec()),
|
||||||
|
};
|
||||||
|
match state.store().call(StoreReq::Delete { id }) {
|
||||||
|
Ok((s, b)) => json(conn, s, b),
|
||||||
|
Err(_) => json(conn, 503, STORE_UNAVAILABLE.to_vec()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Router assembly
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
pub fn build_router(state: AppState) -> Router {
|
||||||
|
Router::new()
|
||||||
|
.get( "/ping", build_ping_handler())
|
||||||
|
.get( "/api/v1/users", build_list_handler(state.clone()))
|
||||||
|
.post( "/api/v1/users", build_create_handler(state.clone()))
|
||||||
|
.get( "/api/v1/users/:id", build_get_one_handler(state.clone()))
|
||||||
|
.put( "/api/v1/users/:id", build_update_handler(state.clone()))
|
||||||
|
.delete("/api/v1/users/:id", build_delete_handler(state))
|
||||||
|
}
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
//! urus-server — the urus side of the urus / axum / cowboy benchmark.
|
||||||
|
//!
|
||||||
|
//! Exposes the routes from `urus-bench-spec.md` §3 with the middleware
|
||||||
|
//! stack from §3.1–§3.4. Backing store is switchable at startup:
|
||||||
|
//!
|
||||||
|
//! --store=memory in-memory actor (S1, S2, S3)
|
||||||
|
//! --store=sqlite single-writer + reader-pool over rusqlite (S4)
|
||||||
|
//!
|
||||||
|
//! Other flags:
|
||||||
|
//! --addr=HOST:PORT default 127.0.0.1:8080
|
||||||
|
//! --token=TOKEN default "test-token-aaaaaaaaaaaaaaaaaaaa"
|
||||||
|
//! --db-path=PATH SQLite file path (sqlite store only)
|
||||||
|
//! --no-auth skip the auth plug (used for S1 /ping check)
|
||||||
|
//!
|
||||||
|
//! The `/ping` route is mounted *outside* the auth plug so the S1 scenario
|
||||||
|
//! does not pay an auth cost it doesn't need. S2/S3/S4 routes are inside it.
|
||||||
|
|
||||||
|
mod handlers;
|
||||||
|
mod middleware;
|
||||||
|
mod store;
|
||||||
|
|
||||||
|
use std::process::ExitCode;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use urus::{serve_with, Config, Conn, Next, Pipeline};
|
||||||
|
|
||||||
|
use handlers::AppState;
|
||||||
|
use middleware::{auth_plug, logger_plug, request_id_plug, LogRing};
|
||||||
|
use store::{spawn_memory_store, spawn_sqlite_store, StoreHandle};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// CLI
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct Cli {
|
||||||
|
addr: String,
|
||||||
|
store: StoreKind,
|
||||||
|
token: String,
|
||||||
|
db_path: String,
|
||||||
|
no_auth: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
enum StoreKind { Memory, Sqlite }
|
||||||
|
|
||||||
|
impl Cli {
|
||||||
|
fn parse() -> Result<Self, String> {
|
||||||
|
// Hand-rolled because clap would dominate compile time for three
|
||||||
|
// flags. Each arg is `--name=value` or `--name` (no positionals).
|
||||||
|
let mut cli = Cli {
|
||||||
|
addr: "127.0.0.1:8080".into(),
|
||||||
|
store: StoreKind::Memory,
|
||||||
|
token: "test-token-aaaaaaaaaaaaaaaaaaaa".into(),
|
||||||
|
db_path: "/tmp/urus-bench.sqlite".into(),
|
||||||
|
no_auth: false,
|
||||||
|
};
|
||||||
|
for arg in std::env::args().skip(1) {
|
||||||
|
let (k, v) = match arg.split_once('=') {
|
||||||
|
Some((k, v)) => (k, Some(v.to_string())),
|
||||||
|
None => (arg.as_str(), None),
|
||||||
|
};
|
||||||
|
match (k, v) {
|
||||||
|
("--addr", Some(v)) => cli.addr = v,
|
||||||
|
("--token", Some(v)) => cli.token = v,
|
||||||
|
("--db-path", Some(v)) => cli.db_path = v,
|
||||||
|
("--store", Some(v)) => cli.store = match v.as_str() {
|
||||||
|
"memory" => StoreKind::Memory,
|
||||||
|
"sqlite" => StoreKind::Sqlite,
|
||||||
|
other => return Err(format!("unknown store: {other}")),
|
||||||
|
},
|
||||||
|
("--no-auth", None) => cli.no_auth = true,
|
||||||
|
("--help" | "-h", _) => {
|
||||||
|
print_usage();
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
(k, _) => return Err(format!("unknown flag: {k}")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(cli)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_usage() {
|
||||||
|
eprintln!(
|
||||||
|
"urus-server [--addr=HOST:PORT] [--store=memory|sqlite] \
|
||||||
|
[--token=TOKEN] [--db-path=PATH] [--no-auth]"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// main
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
fn main() -> ExitCode {
|
||||||
|
let cli = match Cli::parse() {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(e) => { eprintln!("urus-server: {e}"); print_usage(); return ExitCode::from(2); }
|
||||||
|
};
|
||||||
|
|
||||||
|
let addr = match cli.addr.parse() {
|
||||||
|
Ok(a) => a,
|
||||||
|
Err(e) => { eprintln!("urus-server: bad --addr: {e}"); return ExitCode::from(2); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// The log ring is a bounded MPSC-like buffer with a fixed capacity. It
|
||||||
|
// is shared by every connection actor (via Arc) and drained on Ctrl-C
|
||||||
|
// — but we don't wire shutdown in v1, so it's just an in-memory sink.
|
||||||
|
// Bounded means the bench can run for an hour without RSS growth.
|
||||||
|
let log_ring = LogRing::with_capacity(64 * 1024);
|
||||||
|
|
||||||
|
// Token is wrapped in Arc<[u8]> so each plug clone is a refcount bump.
|
||||||
|
// The constant-time compare reads it as bytes.
|
||||||
|
let token: Arc<[u8]> = cli.token.as_bytes().to_vec().into();
|
||||||
|
|
||||||
|
// The pipeline is shape:
|
||||||
|
// logger -> request_id -> [auth ->] router
|
||||||
|
//
|
||||||
|
// /ping is mounted as a literal at the top of the router so it shares
|
||||||
|
// the middleware chain with everything else; the bench spec says S1 is
|
||||||
|
// a "naked" hello world, but in this implementation /ping still goes
|
||||||
|
// through the logger and request_id plugs. That keeps the impl simple
|
||||||
|
// and lets us measure the middleware cost as the *S2 minus S1* delta,
|
||||||
|
// which is what the spec actually asks for (§2).
|
||||||
|
//
|
||||||
|
// --no-auth turns off auth for cases where the load generator can't
|
||||||
|
// easily set headers (it shouldn't be needed for wrk2 though).
|
||||||
|
let auth_token = token.clone();
|
||||||
|
let auth = move |conn: Conn, next: Next| auth_plug(conn, next, &auth_token);
|
||||||
|
|
||||||
|
// The store handle is what handlers use to talk to the store actor.
|
||||||
|
// It's a wrapper around a smarm Sender; cloning is cheap (refcount).
|
||||||
|
//
|
||||||
|
// We can't actually *spawn* the store actor here (smarm requires that
|
||||||
|
// spawn be called from inside an actor, not from the bootstrap
|
||||||
|
// thread). The OnceLock in handlers::AppState defers that until the
|
||||||
|
// first request comes in. We just pass the construction parameters
|
||||||
|
// through here.
|
||||||
|
//
|
||||||
|
// For SQLite we use the configured DB path; for memory we don't
|
||||||
|
// need anything.
|
||||||
|
let store_init: Arc<dyn Fn() -> StoreHandle + Send + Sync + 'static> =
|
||||||
|
match cli.store {
|
||||||
|
StoreKind::Memory => Arc::new(|| spawn_memory_store()),
|
||||||
|
StoreKind::Sqlite => {
|
||||||
|
let path = cli.db_path.clone();
|
||||||
|
Arc::new(move || spawn_sqlite_store(&path))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let state = AppState::new(store_init, log_ring.clone());
|
||||||
|
|
||||||
|
// Build the router. Handlers close over `state` (cheap Arc clone).
|
||||||
|
// Note that handlers themselves use the AppState to resolve the
|
||||||
|
// store on first call.
|
||||||
|
let router = handlers::build_router(state.clone());
|
||||||
|
|
||||||
|
// Assemble the pipeline.
|
||||||
|
//
|
||||||
|
// The closures below take `Conn, Next` with explicit type annotations.
|
||||||
|
// This is necessary because `Next<'a>` is generic over a lifetime;
|
||||||
|
// without the annotation rustc binds the closure to *one specific*
|
||||||
|
// lifetime and then it doesn't satisfy `Plug`'s `Fn(Conn, Next) -> Conn`
|
||||||
|
// higher-ranked bound. With `Next` written out, the closure parses as
|
||||||
|
// `for<'a> Fn(Conn, Next<'a>) -> Conn`, which is what Plug wants.
|
||||||
|
let log_plug = {
|
||||||
|
let ring = log_ring.clone();
|
||||||
|
move |conn: Conn, next: Next| logger_plug(conn, next, &ring)
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut pipeline = Pipeline::new()
|
||||||
|
.plug(log_plug)
|
||||||
|
.plug(request_id_plug);
|
||||||
|
|
||||||
|
if !cli.no_auth {
|
||||||
|
pipeline = pipeline.plug(auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
let pipeline = pipeline.plug(router);
|
||||||
|
|
||||||
|
// Serve. We use the default Config and let urus's heuristic pick
|
||||||
|
// listener pool size = num CPUs.
|
||||||
|
let cfg = Config::new(addr);
|
||||||
|
eprintln!(
|
||||||
|
"urus-server: store={:?} addr={} auth={}",
|
||||||
|
cli.store, cli.addr, !cli.no_auth
|
||||||
|
);
|
||||||
|
if let Err(e) = serve_with(cfg, pipeline) {
|
||||||
|
eprintln!("urus-server: serve failed: {e}");
|
||||||
|
return ExitCode::from(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExitCode::SUCCESS
|
||||||
|
}
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
//! Middleware plugs for the bench.
|
||||||
|
//!
|
||||||
|
//! Per the spec §3:
|
||||||
|
//! - Logger writes to a bounded ring (no stdout — that would dominate).
|
||||||
|
//! - Request ID is generated from a thread-local fast RNG (SplitMix64).
|
||||||
|
//! - Auth is constant-time bearer-token compare.
|
||||||
|
//!
|
||||||
|
//! Each plug is a `Fn(Conn, Next) -> Conn` closure; urus's blanket impl
|
||||||
|
//! turns them into Plug values when handed to Pipeline::plug.
|
||||||
|
|
||||||
|
use std::cell::Cell;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
use crossbeam_queue::ArrayQueue;
|
||||||
|
use subtle::ConstantTimeEq;
|
||||||
|
use urus::{Conn, Next};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Log ring
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Bounded MPSC over a fixed-capacity array. We push from many connection
|
||||||
|
// actors and never read during the bench (drain on shutdown only). If the
|
||||||
|
// ring fills, new entries are dropped — the bench is the priority, not
|
||||||
|
// the log. This matches what we said in spec §1.5: warm-up + 60s measured
|
||||||
|
// at high RPS would overflow any unbounded buffer.
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct LogEntry {
|
||||||
|
pub method: String,
|
||||||
|
pub path: String,
|
||||||
|
pub status: u16,
|
||||||
|
pub elapsed_us: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct LogRing {
|
||||||
|
inner: Arc<ArrayQueue<LogEntry>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LogRing {
|
||||||
|
pub fn with_capacity(n: usize) -> Self {
|
||||||
|
Self { inner: Arc::new(ArrayQueue::new(n)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Push an entry. Drops the entry on overflow (returns Err in
|
||||||
|
/// crossbeam's API — we discard).
|
||||||
|
pub fn push(&self, e: LogEntry) {
|
||||||
|
let _ = self.inner.push(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For inspection after a run.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn drain(&self) -> Vec<LogEntry> {
|
||||||
|
let mut out = Vec::with_capacity(self.inner.len());
|
||||||
|
while let Some(e) = self.inner.pop() { out.push(e); }
|
||||||
|
out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Logger plug
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Wraps `next`. Captures method/path *before* the inner plugs run (the
|
||||||
|
// router may move them), then captures status + elapsed after.
|
||||||
|
|
||||||
|
pub fn logger_plug(conn: Conn, next: Next, ring: &LogRing) -> Conn {
|
||||||
|
let start = Instant::now();
|
||||||
|
let method = conn.method.as_str().to_string();
|
||||||
|
let path = conn.path.clone();
|
||||||
|
let conn = next.run(conn);
|
||||||
|
let elapsed_us = start.elapsed().as_micros() as u64;
|
||||||
|
ring.push(LogEntry {
|
||||||
|
method,
|
||||||
|
path,
|
||||||
|
status: conn.status.unwrap_or(0),
|
||||||
|
elapsed_us,
|
||||||
|
});
|
||||||
|
conn
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Request ID — SplitMix64 in a thread-local, base32-encoded.
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// We avoid global RNG / OS getrandom on the hot path. Each scheduler OS
|
||||||
|
// thread gets its own seed (Cell + thread_local) and advances it with the
|
||||||
|
// SplitMix64 step. 12 bytes of output is encoded with the RFC 4648 base32
|
||||||
|
// alphabet (no padding, no lowercase — the header is opaque to the load
|
||||||
|
// generator).
|
||||||
|
//
|
||||||
|
// Crockford-style alphabet would be friendlier to humans but base32-hex
|
||||||
|
// is fine here.
|
||||||
|
|
||||||
|
thread_local! {
|
||||||
|
static RNG_STATE: Cell<u64> = const { Cell::new(0) };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn splitmix64(s: u64) -> (u64, u64) {
|
||||||
|
// Standard SplitMix64. One 64-bit step gives a uniformly distributed
|
||||||
|
// output and the next state.
|
||||||
|
let new_state = s.wrapping_add(0x9E3779B97F4A7C15);
|
||||||
|
let mut z = new_state;
|
||||||
|
z = (z ^ (z >> 30)).wrapping_mul(0xBF58476D1CE4E5B9);
|
||||||
|
z = (z ^ (z >> 27)).wrapping_mul(0x94D049BB133111EB);
|
||||||
|
(new_state, z ^ (z >> 31))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_random_bytes(out: &mut [u8; 12]) {
|
||||||
|
RNG_STATE.with(|cell| {
|
||||||
|
let mut s = cell.get();
|
||||||
|
if s == 0 {
|
||||||
|
// Lazy first-time seed. Mixing pointer + thread id + clock
|
||||||
|
// is sufficient for a bench-local RNG; this isn't crypto.
|
||||||
|
let p = cell as *const _ as usize as u64;
|
||||||
|
let t = std::time::SystemTime::now()
|
||||||
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
|
.map(|d| d.as_nanos() as u64)
|
||||||
|
.unwrap_or(0);
|
||||||
|
s = p ^ t ^ 0xA5A5_A5A5_A5A5_A5A5;
|
||||||
|
if s == 0 { s = 1; }
|
||||||
|
}
|
||||||
|
let (s1, r1) = splitmix64(s);
|
||||||
|
let (s2, r2) = splitmix64(s1);
|
||||||
|
cell.set(s2);
|
||||||
|
out[0..8].copy_from_slice(&r1.to_le_bytes());
|
||||||
|
out[8..12].copy_from_slice(&r2.to_le_bytes()[..4]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Base32 (RFC 4648) without padding. 12 bytes = 96 bits -> ceil(96/5) = 20
|
||||||
|
// output chars exactly. No padding needed.
|
||||||
|
fn b32_encode(input: &[u8; 12]) -> String {
|
||||||
|
static ALPHABET: &[u8; 32] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||||
|
let mut out = String::with_capacity(20);
|
||||||
|
let mut buf: u64 = 0;
|
||||||
|
let mut bits: u32 = 0;
|
||||||
|
for &b in input {
|
||||||
|
buf = (buf << 8) | (b as u64);
|
||||||
|
bits += 8;
|
||||||
|
while bits >= 5 {
|
||||||
|
bits -= 5;
|
||||||
|
let idx = ((buf >> bits) & 0x1F) as usize;
|
||||||
|
out.push(ALPHABET[idx] as char);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if bits > 0 {
|
||||||
|
let idx = ((buf << (5 - bits)) & 0x1F) as usize;
|
||||||
|
out.push(ALPHABET[idx] as char);
|
||||||
|
}
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn request_id_plug(conn: Conn, next: Next) -> Conn {
|
||||||
|
let mut raw = [0u8; 12];
|
||||||
|
next_random_bytes(&mut raw);
|
||||||
|
let id = b32_encode(&raw);
|
||||||
|
// Set on the response. We could also stash it in `conn.assigns` for
|
||||||
|
// handlers to read, but the bench doesn't need that.
|
||||||
|
let conn = next.run(conn);
|
||||||
|
conn.put_header("x-request-id", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Auth plug
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Read `Authorization: Bearer <token>`; constant-time compare against the
|
||||||
|
// configured token. Mismatch -> 401 + halt.
|
||||||
|
//
|
||||||
|
// The token is borrowed (&[u8]) so the closure that wraps this can hold
|
||||||
|
// it via Arc<[u8]> and pass a slice in. No alloc per request.
|
||||||
|
|
||||||
|
pub fn auth_plug(conn: Conn, next: Next, expected: &[u8]) -> Conn {
|
||||||
|
// /ping is the S1 "naked" endpoint per the bench spec — it must not
|
||||||
|
// pay the auth cost. We exempt it by path. This is a deliberate
|
||||||
|
// exception, not a generic feature; the rest of the pipeline (logger,
|
||||||
|
// request_id) still applies to /ping, which is what the spec asks for
|
||||||
|
// (S1 measures the framework floor, not "no middleware whatsoever").
|
||||||
|
if conn.path == "/ping" {
|
||||||
|
return next.run(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
let header = conn.headers.get("authorization");
|
||||||
|
let presented: Option<&[u8]> = header.and_then(|h| {
|
||||||
|
// strip the "Bearer " prefix (case-insensitive per RFC 6750, but
|
||||||
|
// wrk2 sends the canonical form so an exact prefix check is fine)
|
||||||
|
h.strip_prefix("Bearer ").map(|s| s.as_bytes())
|
||||||
|
});
|
||||||
|
|
||||||
|
let ok = match presented {
|
||||||
|
Some(p) if p.len() == expected.len() =>
|
||||||
|
bool::from(p.ct_eq(expected)),
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if ok {
|
||||||
|
next.run(conn)
|
||||||
|
} else {
|
||||||
|
conn.put_status(401)
|
||||||
|
.put_header("content-type", "application/json")
|
||||||
|
.put_body(&b"{\"error\":\"unauthorized\"}"[..])
|
||||||
|
.halt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Tests
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn b32_round_trip_lengths() {
|
||||||
|
let mut raw = [0u8; 12];
|
||||||
|
for i in 0..12u8 { raw[i as usize] = i; }
|
||||||
|
let s = b32_encode(&raw);
|
||||||
|
assert_eq!(s.len(), 20);
|
||||||
|
assert!(s.chars().all(|c| c.is_ascii_uppercase() || c.is_ascii_digit()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rng_advances() {
|
||||||
|
let mut a = [0u8; 12];
|
||||||
|
let mut b = [0u8; 12];
|
||||||
|
next_random_bytes(&mut a);
|
||||||
|
next_random_bytes(&mut b);
|
||||||
|
assert_ne!(a, b, "consecutive calls must produce different bytes");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,404 @@
|
|||||||
|
//! Store actors for the urus-server bench.
|
||||||
|
//!
|
||||||
|
//! Two implementations behind one [`StoreHandle`]:
|
||||||
|
//! - **Memory store** (S1/S2/S3): one `gen_server` actor owning a
|
||||||
|
//! `Vec<User>`. Reads and writes share the single gen_server inbox, so a
|
||||||
|
//! request is exactly one park/unpark round-trip — the path the RFC 004
|
||||||
|
//! spinning patch perturbs. This is the scenario we actually want clean.
|
||||||
|
//! - **SQLite store** (S4): one writer actor + a pool of reader actors over
|
||||||
|
//! raw `channel` actors. NOT ported to gen_server (single-inbox would
|
||||||
|
//! serialise the reader pool and kill S4 read parallelism); left exactly
|
||||||
|
//! as it was. It is not part of the spinning A/B and is kept only so the
|
||||||
|
//! binary still builds with `--store=sqlite`.
|
||||||
|
//!
|
||||||
|
//! `StoreHandle` is what handlers hold. It's cheap-cloneable and exposes a
|
||||||
|
//! single `call(StoreReq) -> Reply` that both backends answer.
|
||||||
|
|
||||||
|
use smarm::{channel, GenServer, Receiver, Sender, ServerBuilder, ServerRef};
|
||||||
|
use std::path::Path;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use rusqlite::{params, Connection, OpenFlags};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Wire types
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// We return (status, body_bytes) so handlers can hand them straight to
|
||||||
|
// `Conn::put_body` without re-serialising. The store does the JSON work.
|
||||||
|
|
||||||
|
pub type Reply = (u16, Vec<u8>);
|
||||||
|
|
||||||
|
/// The unified store request. One variant per route. Unlike the old
|
||||||
|
/// `ReadReq`/`WriteReq`, these carry *no* reply channel — gen_server's `call`
|
||||||
|
/// creates and threads the reply for us, so the request is just the payload.
|
||||||
|
pub enum StoreReq {
|
||||||
|
List,
|
||||||
|
Get { id: u64 },
|
||||||
|
Create { body: Vec<u8> },
|
||||||
|
Update { id: u64, body: Vec<u8> },
|
||||||
|
Delete { id: u64 },
|
||||||
|
}
|
||||||
|
|
||||||
|
// The SQLite backend still routes reads vs writes to two different actor
|
||||||
|
// sets, so it keeps the split request enums *with* their reply senders.
|
||||||
|
// These are now used ONLY by the SQLite store internals.
|
||||||
|
|
||||||
|
pub enum ReadReq {
|
||||||
|
List { reply: Sender<Reply> },
|
||||||
|
Get { id: u64, reply: Sender<Reply> },
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum WriteReq {
|
||||||
|
Create { body: Vec<u8>, reply: Sender<Reply> },
|
||||||
|
Update { id: u64, body: Vec<u8>, reply: Sender<Reply> },
|
||||||
|
Delete { id: u64, reply: Sender<Reply> },
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// User model
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||||
|
struct User {
|
||||||
|
id: u64,
|
||||||
|
name: String,
|
||||||
|
email: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize)]
|
||||||
|
struct NewUser {
|
||||||
|
name: String,
|
||||||
|
email: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Public handle
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Both backends produce a StoreHandle. Memory wraps a gen_server ServerRef;
|
||||||
|
// SQLite wraps the read/write Sender pair. `call` hides the difference so
|
||||||
|
// handlers issue one uniform request regardless of backend.
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum StoreHandle {
|
||||||
|
Memory(ServerRef<MemStore>),
|
||||||
|
Sqlite { reads: Sender<ReadReq>, writes: Sender<WriteReq> },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StoreHandle {
|
||||||
|
/// Issue a request and wait for the reply. `Err(())` means the store is
|
||||||
|
/// unreachable (server gone / channel closed); handlers turn that into a
|
||||||
|
/// 503. The memory path is a single gen_server `call`; the SQLite path
|
||||||
|
/// builds a one-shot reply channel and routes to the writer or a reader.
|
||||||
|
pub fn call(&self, req: StoreReq) -> Result<Reply, ()> {
|
||||||
|
match self {
|
||||||
|
StoreHandle::Memory(r) => r.call(req).map_err(|_| ()),
|
||||||
|
StoreHandle::Sqlite { reads, writes } => {
|
||||||
|
let (tx, rx) = channel::<Reply>();
|
||||||
|
// Map each backend's distinct SendError<T> to () so the arms
|
||||||
|
// unify, then `?` on the common Result<(), ()>.
|
||||||
|
let sent: Result<(), ()> = match req {
|
||||||
|
StoreReq::List => reads.send(ReadReq::List { reply: tx }).map_err(|_| ()),
|
||||||
|
StoreReq::Get { id } => reads.send(ReadReq::Get { id, reply: tx }).map_err(|_| ()),
|
||||||
|
StoreReq::Create { body } => writes.send(WriteReq::Create { body, reply: tx }).map_err(|_| ()),
|
||||||
|
StoreReq::Update { id, body } => writes.send(WriteReq::Update { id, body, reply: tx }).map_err(|_| ()),
|
||||||
|
StoreReq::Delete { id } => writes.send(WriteReq::Delete { id, reply: tx }).map_err(|_| ()),
|
||||||
|
};
|
||||||
|
sent?;
|
||||||
|
rx.recv().map_err(|_| ())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Memory store — one gen_server, one Vec.
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Everything is a `Call`: the HTTP handler needs the reply to build the
|
||||||
|
// response, so there is no fire-and-forget path here (`type Cast = ()`,
|
||||||
|
// unused). One inbox, one hop per request — no forwarder actors, which is the
|
||||||
|
// whole point of the port: the old raw-actor store needed two forwarders to
|
||||||
|
// fake a read/write select over smarm's single mailbox, costing two extra
|
||||||
|
// park/unpark hops per request and contaminating exactly the cost the spin
|
||||||
|
// patch moves.
|
||||||
|
|
||||||
|
pub struct MemStore {
|
||||||
|
users: Vec<User>,
|
||||||
|
next_id: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MemStore {
|
||||||
|
fn new() -> Self {
|
||||||
|
MemStore { users: Vec::with_capacity(1024), next_id: 1 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GenServer for MemStore {
|
||||||
|
type Call = StoreReq;
|
||||||
|
type Reply = Reply;
|
||||||
|
type Cast = ();
|
||||||
|
type Info = ();
|
||||||
|
|
||||||
|
fn handle_call(&mut self, req: StoreReq) -> Reply {
|
||||||
|
match req {
|
||||||
|
StoreReq::List => {
|
||||||
|
// Cap at 100 per the spec.
|
||||||
|
let snapshot: Vec<&User> = self.users.iter().take(100).collect();
|
||||||
|
let body = serde_json::to_vec(&snapshot).unwrap_or_else(|_| b"[]".to_vec());
|
||||||
|
(200, body)
|
||||||
|
}
|
||||||
|
StoreReq::Get { id } => {
|
||||||
|
match self.users.iter().find(|u| u.id == id) {
|
||||||
|
Some(u) => (200, serde_json::to_vec(u).unwrap()),
|
||||||
|
None => (404, b"{\"error\":\"not found\"}".to_vec()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StoreReq::Create { body } => {
|
||||||
|
match serde_json::from_slice::<NewUser>(&body) {
|
||||||
|
Ok(nu) => {
|
||||||
|
let u = User { id: self.next_id, name: nu.name, email: nu.email };
|
||||||
|
self.next_id += 1;
|
||||||
|
self.users.push(u.clone());
|
||||||
|
// Steady-state RPS bench: cap so we don't grow unbounded.
|
||||||
|
if self.users.len() > 100_000 {
|
||||||
|
self.users.drain(..50_000);
|
||||||
|
}
|
||||||
|
(201, serde_json::to_vec(&u).unwrap())
|
||||||
|
}
|
||||||
|
Err(_) => (400, b"{\"error\":\"invalid body\"}".to_vec()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StoreReq::Update { id, body } => {
|
||||||
|
match serde_json::from_slice::<NewUser>(&body) {
|
||||||
|
Ok(nu) => match self.users.iter_mut().find(|u| u.id == id) {
|
||||||
|
Some(u) => {
|
||||||
|
u.name = nu.name;
|
||||||
|
u.email = nu.email;
|
||||||
|
let snap = u.clone();
|
||||||
|
(200, serde_json::to_vec(&snap).unwrap())
|
||||||
|
}
|
||||||
|
None => (404, b"{\"error\":\"not found\"}".to_vec()),
|
||||||
|
},
|
||||||
|
Err(_) => (400, b"{\"error\":\"invalid body\"}".to_vec()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StoreReq::Delete { id } => {
|
||||||
|
let before = self.users.len();
|
||||||
|
self.users.retain(|u| u.id != id);
|
||||||
|
if self.users.len() < before {
|
||||||
|
(204, Vec::new())
|
||||||
|
} else {
|
||||||
|
(404, b"{\"error\":\"not found\"}".to_vec())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_cast(&mut self, _req: ()) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spawn_memory_store() -> StoreHandle {
|
||||||
|
// gen_server::start (via ServerBuilder) must run inside an actor — the
|
||||||
|
// OnceLock lazy-init in AppState::store() guarantees that, same as before.
|
||||||
|
StoreHandle::Memory(ServerBuilder::new(MemStore::new()).start())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// SQLite store — one writer + N readers. (UNCHANGED — not ported.)
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Per the spec §5.1:
|
||||||
|
// - One writer actor owns a single rusqlite::Connection (read-write).
|
||||||
|
// - N=4 reader actors each own a private channel; a dispatcher round-robins
|
||||||
|
// reads across them. (gen_server is single-inbox, so porting this would
|
||||||
|
// serialise reads through one actor and kill S4 read parallelism — hence
|
||||||
|
// it stays on raw actors. It is not part of the spinning A/B.)
|
||||||
|
//
|
||||||
|
// All connections open the same database file. WAL is set on the writer's
|
||||||
|
// connection (the journal mode is a database-wide setting). busy_timeout is
|
||||||
|
// set on every conn so a momentary writer hold doesn't EBUSY the readers.
|
||||||
|
|
||||||
|
const SQLITE_READER_COUNT: usize = 4;
|
||||||
|
|
||||||
|
pub fn spawn_sqlite_store(db_path: &str) -> StoreHandle {
|
||||||
|
let path: Arc<str> = Arc::from(db_path);
|
||||||
|
|
||||||
|
// The writer actor.
|
||||||
|
let (writes_tx, writes_rx) = channel::<WriteReq>();
|
||||||
|
{
|
||||||
|
let path = path.clone();
|
||||||
|
smarm::spawn(move || sqlite_writer_loop(&path, writes_rx));
|
||||||
|
}
|
||||||
|
|
||||||
|
// The readers. smarm's channel is MPSC, so we can't share a single
|
||||||
|
// Receiver across N reader actors. Instead: one dispatcher owns the
|
||||||
|
// public `reads_rx`, and round-robins each request into one of N
|
||||||
|
// per-reader private channels.
|
||||||
|
let (reads_tx, reads_rx) = channel::<ReadReq>();
|
||||||
|
let mut per_reader_txs: Vec<Sender<ReadReq>> = Vec::with_capacity(SQLITE_READER_COUNT);
|
||||||
|
for _ in 0..SQLITE_READER_COUNT {
|
||||||
|
let (tx, rx) = channel::<ReadReq>();
|
||||||
|
per_reader_txs.push(tx);
|
||||||
|
let path = path.clone();
|
||||||
|
smarm::spawn(move || sqlite_reader_loop(&path, rx));
|
||||||
|
}
|
||||||
|
smarm::spawn(move || dispatch_reads(reads_rx, per_reader_txs));
|
||||||
|
|
||||||
|
StoreHandle::Sqlite { reads: reads_tx, writes: writes_tx }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn open_writer(path: &str) -> Connection {
|
||||||
|
let conn = Connection::open(path).expect("sqlite: open writer");
|
||||||
|
// WAL is the whole reason this design works: writers don't block
|
||||||
|
// readers, readers don't block writers, only writers block other
|
||||||
|
// writers (and there's only one).
|
||||||
|
conn.pragma_update(None, "journal_mode", "WAL").expect("sqlite: WAL");
|
||||||
|
conn.pragma_update(None, "synchronous", "NORMAL").expect("sqlite: synchronous");
|
||||||
|
conn.pragma_update(None, "busy_timeout", 5000_i64).expect("sqlite: busy_timeout");
|
||||||
|
conn.execute_batch(
|
||||||
|
"CREATE TABLE IF NOT EXISTS users (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
email TEXT NOT NULL
|
||||||
|
);"
|
||||||
|
).expect("sqlite: schema");
|
||||||
|
conn
|
||||||
|
}
|
||||||
|
|
||||||
|
fn open_reader(path: &str) -> Connection {
|
||||||
|
let conn = Connection::open_with_flags(
|
||||||
|
Path::new(path),
|
||||||
|
OpenFlags::SQLITE_OPEN_READ_ONLY | OpenFlags::SQLITE_OPEN_NO_MUTEX,
|
||||||
|
).expect("sqlite: open reader");
|
||||||
|
conn.pragma_update(None, "busy_timeout", 5000_i64).expect("sqlite: busy_timeout");
|
||||||
|
// Readers inherit the DB-wide WAL setting from the writer.
|
||||||
|
conn
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sqlite_writer_loop(path: &str, rx: Receiver<WriteReq>) {
|
||||||
|
let conn = open_writer(path);
|
||||||
|
while let Ok(req) = rx.recv() {
|
||||||
|
match req {
|
||||||
|
WriteReq::Create { body, reply } => {
|
||||||
|
match serde_json::from_slice::<NewUser>(&body) {
|
||||||
|
Ok(nu) => {
|
||||||
|
let res = conn.execute(
|
||||||
|
"INSERT INTO users (name, email) VALUES (?1, ?2)",
|
||||||
|
params![nu.name, nu.email],
|
||||||
|
);
|
||||||
|
match res {
|
||||||
|
Ok(_) => {
|
||||||
|
let id = conn.last_insert_rowid() as u64;
|
||||||
|
let u = User { id, name: nu.name, email: nu.email };
|
||||||
|
let _ = reply.send((201, serde_json::to_vec(&u).unwrap()));
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("sqlite: insert failed: {e}");
|
||||||
|
let _ = reply.send((500, b"{\"error\":\"db\"}".to_vec()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
let _ = reply.send((400, b"{\"error\":\"invalid body\"}".to_vec()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WriteReq::Update { id, body, reply } => {
|
||||||
|
match serde_json::from_slice::<NewUser>(&body) {
|
||||||
|
Ok(nu) => {
|
||||||
|
let res = conn.execute(
|
||||||
|
"UPDATE users SET name=?1, email=?2 WHERE id=?3",
|
||||||
|
params![nu.name, nu.email, id as i64],
|
||||||
|
);
|
||||||
|
match res {
|
||||||
|
Ok(0) => { let _ = reply.send((404, b"{\"error\":\"not found\"}".to_vec())); }
|
||||||
|
Ok(_) => {
|
||||||
|
let u = User { id, name: nu.name, email: nu.email };
|
||||||
|
let _ = reply.send((200, serde_json::to_vec(&u).unwrap()));
|
||||||
|
}
|
||||||
|
Err(_) => { let _ = reply.send((500, b"{\"error\":\"db\"}".to_vec())); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
let _ = reply.send((400, b"{\"error\":\"invalid body\"}".to_vec()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WriteReq::Delete { id, reply } => {
|
||||||
|
let res = conn.execute(
|
||||||
|
"DELETE FROM users WHERE id=?1",
|
||||||
|
params![id as i64],
|
||||||
|
);
|
||||||
|
match res {
|
||||||
|
Ok(0) => { let _ = reply.send((404, b"{\"error\":\"not found\"}".to_vec())); }
|
||||||
|
Ok(_) => { let _ = reply.send((204, Vec::new())); }
|
||||||
|
Err(_) => { let _ = reply.send((500, b"{\"error\":\"db\"}".to_vec())); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dispatch_reads(rx: Receiver<ReadReq>, workers: Vec<Sender<ReadReq>>) {
|
||||||
|
// Strict round-robin. SQLite reads are uniform in cost (single-row PK
|
||||||
|
// lookup or LIMIT 100), so a brief reader stall just shifts a request to
|
||||||
|
// the next reader on the next pass.
|
||||||
|
let n = workers.len();
|
||||||
|
let mut idx = 0usize;
|
||||||
|
while let Ok(req) = rx.recv() {
|
||||||
|
let target = &workers[idx % n];
|
||||||
|
idx = idx.wrapping_add(1);
|
||||||
|
if target.send(req).is_err() {
|
||||||
|
// Reader died; skip it. Unsupervised in this binary — fine for the
|
||||||
|
// bench.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sqlite_reader_loop(path: &str, rx: Receiver<ReadReq>) {
|
||||||
|
let conn = open_reader(path);
|
||||||
|
let mut stmt_get = conn.prepare("SELECT id, name, email FROM users WHERE id=?1")
|
||||||
|
.expect("sqlite: prepare get");
|
||||||
|
let mut stmt_list = conn.prepare("SELECT id, name, email FROM users LIMIT 100")
|
||||||
|
.expect("sqlite: prepare list");
|
||||||
|
|
||||||
|
while let Ok(req) = rx.recv() {
|
||||||
|
match req {
|
||||||
|
ReadReq::Get { id, reply } => {
|
||||||
|
let row = stmt_get.query_row(params![id as i64], |r| {
|
||||||
|
Ok(User {
|
||||||
|
id: r.get::<_, i64>(0)? as u64,
|
||||||
|
name: r.get(1)?,
|
||||||
|
email: r.get(2)?,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
match row {
|
||||||
|
Ok(u) => { let _ = reply.send((200, serde_json::to_vec(&u).unwrap())); }
|
||||||
|
Err(rusqlite::Error::QueryReturnedNoRows) =>
|
||||||
|
{ let _ = reply.send((404, b"{\"error\":\"not found\"}".to_vec())); }
|
||||||
|
Err(_) =>
|
||||||
|
{ let _ = reply.send((500, b"{\"error\":\"db\"}".to_vec())); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ReadReq::List { reply } => {
|
||||||
|
let rows = stmt_list.query_map([], |r| {
|
||||||
|
Ok(User {
|
||||||
|
id: r.get::<_, i64>(0)? as u64,
|
||||||
|
name: r.get(1)?,
|
||||||
|
email: r.get(2)?,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
match rows {
|
||||||
|
Ok(iter) => {
|
||||||
|
let users: Vec<User> = iter.filter_map(|r| r.ok()).collect();
|
||||||
|
let body = serde_json::to_vec(&users).unwrap_or_else(|_| b"[]".to_vec());
|
||||||
|
let _ = reply.send((200, body));
|
||||||
|
}
|
||||||
|
Err(_) => { let _ = reply.send((500, b"{\"error\":\"db\"}".to_vec())); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user