Public
R2 vs S3 blob latency report, served from blob itself
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.

blob-bench

A live latency report comparing Val Town's old blob storage (R2) with the new scoped blob storage (S3) — and a dogfood of the new store, because the report itself is served from blob.

Live: the index.ts HTTP endpoint.

What it shows

  • Median latency for get/set across 1KB / 100KB / 1MB payloads, old vs new.
  • Full distribution (p50/p90/p99/max) — where R2's slow tail really shows.
  • "Load this report from R2 vs S3" — the snapshot is stored in both backends under the same key, so you can load it from either and feel the difference.
  • Re-run benchmark — runs a fresh benchmark and saves it to both stores.

How it's wired

filerole
blob.tsthe only place the two std clients are imported: main.ts (S3) + global.ts (R2)
types.tsSnapshot / Row / Stat
stats.tspercentiles + summarize()
bench.tsrunBenchmark() — times set/get on both stores, interleaved, with warm-ups
store.tspersist a snapshot to both stores; load latest/by-id (timed); list runs
view.tsxserver-rendered UI (Hono JSX + Tailwind)
client.tsminimal browser JS: the R2-vs-S3 race + re-run progress
index.tsHono routes: /, /data, POST /runs, /source

Method

Old and new requests are interleaved each iteration (so drift hits both equally), one warm-up per cell is discarded, and percentiles are linear-interpolated. Snapshots persist in blob under blob-bench/runs/<id>.json plus a latest.json pointer, written to both backends.