Benchmarks

Measured, not marketed.

Every number below was produced by the load tools that ship in the repository, on a single machine running the entire stack — both gateway edges, MySQL, Redis and the load generators — at once. Nothing is extrapolated, and a message only counts when it is durably enqueued. Targets: 10,000 segments/s per process at p95 < 30 ms — both met on both edges. Dedicated hardware should expect better, not worse.

57,837
segments/sec — SMPP peak, multi-segment
19,692
submit/sec — SMPP single-segment, p95 7.1 ms
10,539
submit/sec — HTTP, target met on one edge
1.6M
endurance messages — 100% accepted
Methodology

The accept path, end to end.

Client submit → authentication → the full 18-stage pipeline → durable queue write. These are not echo-server numbers: acceptance was 100% in every run, every count was cross-checked against the queue store afterwards, and each worker sends sequentially — so latency is a true per-submit round trip.

Machine B — the current reference (2026-08-18 runs)

Deliberately not a tuned server — one developer machine carrying the whole stack and the load generation together.

CPUApple M5 Pro — 18 cores (arm64)
RAM24 GB
DiskApple NVMe
OSmacOS 26.4
StoresMySQL 9.7 + Redis 8.10
Buildsingle Go binary, one process per role

Machine A — the 2026-07/08 reference

The earlier runs (both-edges mix, endurance, batching) were measured here; identical tools and methodology.

CPUIntel Core i9-13900HX — 24 cores / 32 threads
RAM64 GB
DiskSamsung 9100 PRO 1 TB NVMe
OSWindows 11 Home
StoresMySQL 8.0 + Redis-compatible store
Buildsingle Go binary, one process per role
Peak Throughput

One machine, one edge at a time.

Machine B, sequential-per-connection methodology — a stricter measure than a pipelined generator, since throughput = concurrency ÷ real latency. Zero failed submits at every concurrency level. (Machine A's earlier peaks — 9,290 SMPP / 3,674 HTTP submit/s, 13,435 seg/s multi-segment — are retained in the full report.)

Single-segment submits
SMPP (100 binds)
19,692p95 7.1 ms
HTTP (150 workers)
10,539p95 15.9 ms
submits/sec
Multi-segment (3 segments)
SMPP multi-segment
57,8377.3 ms p95/segment
HTTP multi-segment
29,318segs = 3
segments/sec

Concurrency sweep — single segment, GSM-7 (Machine B)

05k10k15k20k255075100150concurrency (binds / workers)SMPPHTTP
ConcurrencySMPP submit/sSMPP p95HTTP submit/sHTTP p95
25——9,5123.2 ms
5019,5053.5 ms9,8486.0 ms
75——9,5929.5 ms
10019,6927.1 ms10,46110.9 ms
15016,45711.9 ms10,53915.9 ms

SMPP holds ~19.5k submit/s through 50–100 binds, then collapses at 200 as 18 cores oversubscribe — cap binds near 100 on this class of hardware. HTTP is processing-bound at ~9.5–10.5k submit/s across every worker count — past the knee, extra workers only add latency.

Both Edges at Once

9,196 msg/s with every budget met.

Machine A serving HTTP and SMPP simultaneously. The best mix — modest HTTP concurrency plus more binds — nearly matched the sum of that machine's single-edge peaks.

ConfigurationHTTP TPSSMPP TPSAggregateHTTP p95SMPP p95
100 conn + 10 binds (saturated)2,7003,3466,04661.5 ms10.0 ms
50 conn + 5 binds3,1683,4546,62229.3 ms3.7 ms
50 conn + 10 binds2,7693,9646,73326.3 ms5.3 ms
50 conn + 25 binds2,5886,6089,19627.6 ms6.3 ms

Endurance — 1.6 million messages (Machine A)

600,000 messages over HTTP and 1,000,000 over SMPP, concurrently: ~4,880 msg/s sustained during full overlap, 100% accepted on both edges. A separate single-recipient run held HTTP p95 at 45.3 ms for the entire five-minute run. Storage cost measured at ~1.6 KB per queued message, reclaimed as the queue drains.

What We Learned

Observations worth knowing.

Both targets met, single-segment, on both edges

Machine B clears the 10,000 seg/s-per-process target on HTTP alone and doubles it on SMPP, with p95 inside the 30 ms budget. Multi-segment SMPP moves ~58k seg/s at 7.3 ms — 5.8× the target.

The ceiling moves with the silicon; the shape holds

Machine A was processing-bound at ~270 µs per HTTP submit (flat ~3.4–3.7k); Machine B at ~95 µs (flat ~9.5–10.5k). Same plateau-shaped curve, ~2.9× the throughput — vertical scaling works.

Each protocol has a different concurrency dial

HTTP past the queueing knee only adds latency — fewer connections can mean more throughput. SMPP serializes per bind, so bind count is the throughput dial — but oversubscription bites: on 18 cores, SMPP holds ~19.5k through 100 binds then collapses at 200. Cap binds near 100 on this class of hardware.

Quote throughput at the latency budget

Every headline number is taken where p95 stays inside budget — not at maximum saturation. Endurance figures (not burst peaks) are the ones to use for capacity planning. The compiled Go generators behind every number ship in the repository — an interpreted generator would under-report by ~45%.

Don't take our word for it.

The compiled load generators ship in the repo, and the gateway measures itself — live counters at GET /status, fleet-wide at /status/cluster. Sweep the concurrency, find the knee, quote throughput at the latency budget.

Reproduce It LocallyFollow the Launch

The full BENCHMARKS.md report and the compiled load tools ship with the public repository — launching soon.