.me framework — by sui.gn
Benchmarks, explained plainly · 7 min read
Article 02 EN · dark edition

It doesn't get slower.
It gets pickier.

real numbers, one laptop, Aug 2026
10,443things stored
grown from 453 across this run
1thing recomputed
every single time, unchanged
=
0.007ms p50
same speed at 10 records or 10,000

No round numbers, no cherry-picked demo. Every figure on this page came out of a cargo run --release or a vitest run, on the machine this was written on. This is the "for dummies" walkthrough of why those numbers look the way they do.

Section 01 / 04

What a benchmark actually asks

Not "is it fast." A specific, boring, answerable question.

Imagine your grocery list has 10,000 items on it because you've been adding to the same list for years. You cross out one carton of eggs because you bought it. How long does that take?

Obviously: the same half-second it always takes, whether the list has 10 items or 10,000. Crossing out eggs doesn't require re-reading the whole list. It only touches the one line that changed.

That's the entire idea a database benchmark is trying to catch people breaking. Most systems, under the hood, quietly start re-reading more of the list as it grows — a little slower at 10,000 items than at 10. .me's benchmarks exist to prove, with numbers, that it doesn't.

the size of your database
n
Everything you've ever stored. In the run above, n grew from 453 to 10,443.
the size of your change
k
How many things actually depend on what you just touched. In that same run, k stayed 1.

Every chart below is really just answering one question over and over: when you write, does the bill scale with k, or does it quietly scale with n instead?

Section 02 / 04

Two charts, one honest contrast

Irrelevant clutter costs nothing. Real connections cost something — on purpose.

Here are the two shapes that matter, from the same benchmark suite, plotted straight from the recorded runs — nothing smoothed out.

Chart A — bench-ok k held at 1
0 .02 .04ms 453 543 1,443 5,443 10,443 MEMORIES STORED →

1000+ irrelevant memories added, and the line doesn't climb. p95 latency for the one real update stays under 0.05ms the entire way — because nothing else was ever asked to recompute.

Chart B — bench-fanout k = fanout, on purpose
0 22 43ms 10 100 500 1,000 2,500 5,000 REAL DEPENDENTS (k) →

Now give a write 5,000 real dependents instead of 10. Latency climbs, from 0.12ms to 43ms. That's not a leak — that's .me correctly doing 5,000 real updates instead of pretending it didn't need to.

Put the two charts side by side and there's one sentence underneath both: you pay for what's actually connected to your change, never for what isn't.

Section 03 / 04

Two things that aren't free

Asking "why," and keeping a secret, both cost something. Here's exactly how much.

.me doesn't pretend everything is free. Two features have a real, measured cost — traceability and privacy. The only promise is that the cost stays small enough to leave on by default.

still sub-millisecond
explain(path) — asking where a value came from
0.0154ms0.0198ms
A 28% overhead on p95, measured over a real read/write loop. In plain terms: the receipt-printer adds noticeably to its own runtime, but the whole checkout is still done before you'd notice.
$ node benchmark.8.explain-overhead.test.ts baseline p95 0.0154ms with_explain p95 0.0198ms (+28.11%)
~21x slower, still <0.4ms
secret scope — reading something encrypted
0.0175ms0.3684ms
Reading a secret path costs about 21 times more than reading a public one, p95 — that's the real price of decryption, not a rounding error hidden somewhere. It's also still under half a millisecond.
$ node benchmark.9.secret-scope-impact.test.ts public p95 0.0175ms secret p95 0.3684ms (~21x)

The Rust port (this-me) measures the same two costs independently and lands in the same shape — traceable and private both stay affordable, never free.

Section 04 / 04

Tested past toy scale — and where it isn't yet

100,000 vectors is not a demo number. Neither is the ceiling below.

Everything above was one write touching a handful of dependents. The AI-facing side of .me — vector search over embeddings — gets tested at a size that actually resembles a real corpus: 100,000 vectors, on the realistic (chunk-coherent) profile.

methodp95 latencyrecall@10chunks / query
exact scan (baseline)77,129.34ms1.000
IVF sidecar index3,318.42ms1.00018.4

Same recall — perfect, 1.000 — at 23.2x the speed, by only checking the 18.4 chunks out of the corpus that could plausibly contain a match, instead of scanning all 100,000.

Where the edge actually is today: a single-process batch write path currently tops out around 137,300 items before it runs into laptop heap memory — not a query slowdown, a hard ceiling on one machine, one process, no sharding. Typical batch cost stays a flat 14–20ms per 100-item chunk right up until that wall. That number is the next thing being worked on, not a footnote being hidden.