Run
Fire real requests against a RoExpress route, named port, vanilla RemoteFunction, or RemoteEvent. A warmup pass runs first (results discarded) to prime the JIT and connection, then iterations measured requests are collected.
bench:Run()
Benchmarks a route on the main RoExpress channel. Returns a Results table with min, avg, median, p95, p99, max, errors, throughput, and more.
bench:RunOnPort()
Same as Run but fires against a named port channel. Obtain portNetwork with RoExpress("Network", "portName").
bench:RunRemoteFunction()
Full round-trip benchmark against a vanilla RemoteFunction. Calls remote:InvokeServer(...) and measures until the response arrives — directly comparable to a RoExpress route benchmark.
bench:RunRemoteEvent()
Fire-only timing for a vanilla RemoteEvent. Measures the client-side cost of FireServer — this is not round-trip. The target field reads "RemoteEvent (fire only)" so Compare output makes the distinction clear.
RunRemoteFunction for a fair comparison against RoExpress routes.bench:RunAndPrint()
Convenience wrapper — runs and prints in one call. Returns Results so you can store it for Compare.
Config
All run methods accept the same optional config table. Fields that don't apply to a target type are ignored.
| Field | Type | Default | Description |
|---|---|---|---|
method | "GET" | "POST" | "PUT" | "DELETE" | "GET" | HTTP method — RoExpress targets only |
data | any? | nil | Request body — RoExpress targets only |
args | { any }? | {} | Arguments unpacked into FireServer / InvokeServer — vanilla remotes only |
iterations | number? | 20 | Measured requests |
warmup | number? | 3 | Discarded warm-up requests (JIT / connection) |
interval | number? | 0 | Seconds between requests (0 = back-to-back) |
timeout | number? | nil | Per-request timeout passed to Network — RoExpress only |
label | string? | route / remote.Name | Display name in Print / Compare output |
Results
| Field | Type | Description |
|---|---|---|
label | string | Display name (from config or auto-assigned) |
target | string | "RoExpress" · "RoExpress Port" · "RemoteFunction" · "RemoteEvent (fire only)" |
method | string | GET / POST / PUT / DELETE / invoke / fire |
min | number | Fastest request (ms) |
avg | number | Mean RTT (ms) |
median | number | p50 (ms) |
p95 | number | 95th percentile (ms) |
p99 | number | 99th percentile (ms) |
max | number | Slowest request (ms) |
errors | number | Failed request count |
errorCodes | { [number]: number } | Error count per HTTP status code |
throughput | number | Requests per second (wall-clock) |
total | number | Total wall time for all iterations (ms) |
completed | number | Iterations actually measured |
iterations | number | Configured iteration count |
warmup | number | Configured warmup count |
bench:Print()
Writes a formatted summary to the Studio output window. The header line shows the target type and method so you can identify each run at a glance.
── player/123 [RoExpress GET] × 20 (warmup: 3) ───────────────
min 4.21 ms
avg 6.83 ms
median 6.10 ms
p95 12.44 ms
p99 18.07 ms
max 18.71 ms
─────────────────────────────────────────────────────────────
errors 0 / 20
throughput 8.3 req/s
──────────────────────────────────────────────────────────────────
Example — GET request benchmark
local bench = RoExpress("Benchmark")
-- RoExpress main channel
local result = bench:RunAndPrint("player/123", {
method = "GET",
iterations = 30,
warmup = 5,
label = "player GET",
})
-- Named port channel
local combatNet = RoExpress("Network", "combat")
local portResult = bench:RunOnPort(combatNet, "shoot/123", {
method = "POST",
data = { weapon = "AK47" },
label = "combat POST shoot",
})
bench:Print(portResult)
-- Vanilla RemoteFunction round-trip
local rs = game:GetService("ReplicatedStorage")
local echoFunc = rs:WaitForChild("EchoFunc")
local rfResult = bench:RunRemoteFunction(echoFunc, {
args = { "payload" },
iterations = 30,
label = "vanilla RF echo",
})
bench:Print(rfResult)
interval = 0 and high iteration counts you may see 429 errors in results.errorCodes. Call tokenBucket:Reset() on the server before each run to clear per-player state.See also
← Benchmark · Compare | side-by-side p95/p99 analysis · Network | the instance Benchmark fires through · TokenBucket | rate limits that affect results