Abstract. rushort is a minimal URL shortener in Rust serving raw HTTP/1.1 on tokio with no web framework. On a 14-core M4 Pro over loopback it sustains 10.0M redirect RPS for 10 seconds (100,000,000 requests, zero drops, p99 17.6ms), peaks at 16.8M RPS under closed-loop saturation, serves 165k round-trip RPS without pipelining, and holds 1,158 RPS of durable mixed traffic with SIGKILL-safe acknowledgments. This paper documents the design, the measurement methodology, and the three benchmark defects found and fixed along the way. All results are reproducible from the open-source harness.

1. introduction

The motivating observation, stated in the post that prompted this work, is that 100 million requests per day averages only 1,157 RPS — a rate any single modern server should exceed by orders of magnitude on reads. The question is by how much, under what conditions, and with what durability semantics. This paper answers all three for one deliberately narrow service: URL shortening, i.e. mapping short codes to long URLs with 302 redirects.

The contribution is twofold: (i) a production-configured implementation in approximately 800 lines of Rust on the serving path (src/lib.rs, src/store.rs, src/bin/shortener.rs), and (ii) a fail-closed benchmark harness that verifies every response and fails on any drop, error, or mismatch. Reporting follows the three-number convention of Railway's CDN writeup: a sustained title number, a daily-rate number, and an ideal-lab peak, each bound to its workload.

2. background and related work

High-throughput HTTP serving on commodity hardware is well charted. Framework-based Rust services (axum/hyper) peak near 169k RPS on the evaluation hardware; the pipelined results below exceed that by 30–100x on the same machine, consistent with prior observations that per-request syscall and wakeup overhead dominates at high connection counts. Published reference points for non-pipelined traffic include Seastar at approximately 7M RPS (DPDK, 2×14-core), F-Stack nginx at 5M RPS, and io_uring configurations sustaining 7.8M RPS on 64-core EPYC hardware. Railway reports 30M RPS absorbed under DDoS across a 180-node anycast fleet with a 150M RPS laboratory ceiling — a distributed result that is not comparable to single-node loopback figures and is cited here only for its reporting discipline.

The durability design follows the standard write-ahead discipline: a single writer appends to SQLite in WAL mode with synchronous=FULL and fullfsync enabled, publishes to the read cache only after commit, and acknowledges last. This is the conventional log-first ordering shared by Postgres (WAL + heap) and other durable engines.

3. design

Three decisions determine nearly all observed performance. First, there is no framework on the hot path: one socket task per connection, a span-based header parser, and a direct match on (method, path). Second, every read drains all complete requests already buffered (up to 256 per batch) and answers them with a single write syscall, amortizing kernel crossings. Third, the store avoids lookup entirely: short codes are sequential IDs in base62, so a GET decodes the code and indexes directly into a sharded vector, with no hashing, no key comparison, and no per-read allocation.

pub fn resolve(&self, code: &str) -> Option<Arc<str>> {
    let id = usize::try_from(base62_decode(code)?).ok()?;
    self.shards[id & (self.shards.len() - 1)]
        .read()
        .get(id / self.shards.len())
        .cloned()
}

Sequential codes are a deliberate tradeoff: O(1) resolution in exchange for guessable identifiers and no URL deduplication. The service is therefore specified for trusted link creators; unguessable links and abuse controls are out of scope.

Admission is bounded at every layer: 1,024 connections, 32 concurrent writes, 5-second header/body/socket deadlines, 8 KiB bodies, 16 KiB header blocks, and a 1M-URL capacity. Writes beyond capacity or admission return 503. Malformed framing — duplicate Content-Length, Transfer-Encoding, conflicting expectations — is rejected (400/413/ 417/431) rather than interpreted.

4. implementation

The server (src/lib.rs, 546 lines) implements the connection loop, the batch drain, and routing. The store (src/store.rs, 130 lines) holds a 64-way sharded RAM cache backed by a single SQLite writer; a lock file refuses a second owner of the same database, and startup verifies contiguous IDs, URL validity, and capacity before serving. The binary (src/bin/shortener.rs, 128 lines) parses configuration, enforces bearer-token authentication on writes for durable and non-loopback operation, and drains connections for up to 10 seconds on SIGINT/SIGTERM. A separate load generator (src/bin/loadgen.rs) is bench-only and excluded from the serving line count.

5. evaluation

5.1 methodology

All measurements use the checked-in harness (./bench.sh scripts/simulate.py), which builds release, starts isolated servers with fresh credentials, and retains raw logs under target/benchmarks/<stamp>/ with a machine-stamped CLAIMS.md. The generator schedules arrivals on absolute deadlines (open-loop), independent of responses, through bounded per-connection queues: overload manifests as counted drops, and any drop, transport error, unexpected status, or location mismatch fails the run. Latency is full batch-completion time including scheduling delay; it is never divided by pipeline depth. A fixture suite verifies the harness fails closed on all-500 fixtures, wrong stored URLs, and duplicate codes.

5.2 results

Hardware: 14-core Apple Silicon, macOS, client and server co-resident over loopback. Release profile: lto=thin, codegen-units=1. Source: full validation run (--repeats 3 --seconds 30).

  • Sustained pipeline (title). 10M RPS target, 10s, 32 connections, pipeline depth 128: 100,000,000 successful requests in 10.002s (9,997,937 RPS), p99 17.62ms, zero drops.
  • Peak saturate (ceiling). Closed-loop, same pipelining: best single run 16,847,534 RPS, median 16,281,158 RPS across three runs, p99 approximately 0.5ms.
  • Round-trip (generalizable). No pipelining, 64 connections: median 164,907 RPS, p99 approximately 0.5ms, limited by macOS loopback/kqueue rather than application CPU.
  • Durable mixed (daily rate). 1,158 RPS for 30s at 94% GET / 5% authenticated POST / 1% miss: p99 6.39ms, zero drops, every acknowledged write re-verified after the run, including across a SIGKILL restart. A 2× burst at 2,315 RPS passes at p99 8.78ms.
  • Wide mixed. 100k-seed working set at 10% miss rate: 13,170,223 RPS saturate.
fig. 1 — measured throughput by workload (log scale, M4 Pro loopback)durable mixed1,158 RPSround-trip165k RPS100M in 10s10.0M RPSpeak saturate16.8M RPS
fig. 1 — the four workloads span four orders of magnitude. The top two rows amortize TCP round-trips via 128-deep pipelining and measure processing capacity; the round-trip row measures request/response latency as experienced by ordinary clients.

6. threats to validity

Four limitations bound these claims. (1) All figures are loopback on one machine with no NIC, no TLS, and a co-resident generator consuming 4–6 cores; they do not predict networked or multi-tenant behavior. (2) The 10M and 16.8M figures require 128-deep HTTP pipelining, a synthetic pattern that measures server processing rather than client- observed latency. (3) The 10-second sustained run was conducted on a fresh server; repeated back-to-back runs exhibit thermal throttling and measurable drops, which the harness reports as failures rather than absorbing. (4) The durable rate test covers 30 seconds at the 100M/day average rate; it is not a 24-hour soak, a power-loss test, or a replication evaluation — the system is single-writer by design. Extrapolating the 10-second burst to a daily volume (≈864B/day) would be arithmetic without evidentiary basis and is explicitly disclaimed.

Three defects in earlier benchmark revisions are disclosed for completeness: batch latency divided by pipeline depth, an extra half-second of unmeasured traffic in the peak window, and PASS verdicts on all-500 responses. Each is now covered by a regression test.

7. conclusion

A framework-free Rust shortener of ~800 serving-path lines sustains 10M pipelined redirect RPS for 10 seconds, peaks at 16.8M RPS, answers 165k honest round-trips per second, and holds the 100M/day average rate durably with kill-safe acknowledgments. The dominant optimization is request batching at the socket layer; the dominant methodological requirement is a harness that fails itself. Source, harness, and deployment notes are MIT-licensed at github.com/maskjelly/rushort; reproduction is ./bench.sh --repeats 3 --seconds 30.

references

  1. rushort source (MIT). github.com/maskjelly/rushort.
  2. Walton (2026). "How to build a 30M RPS CDN in 30 days with Rust and WASM." blog.railway.com/p/railway-cdn.
  3. Motivating post. x.com/aaryantwt/status/2099475672855204229.