Vol. II · Issue 07 · JUL 2026 Methodology — Truth Series v3.7 · Jul 2026
// METHODOLOGY · v3.7

Every formula.
Every constant.
Every weight.

If you find a flaw in our scoring, file an issue on GitHub. We ship the patch the same week. This page documents the entire 9bench composite score, including the parts we can't measure perfectly.

1. What we measure

— GPU compute

WebGPU matrix multiplication

We run a 1024×1024 FP32 matrix multiplication compute shader on your GPU. The shader executes 2 × N³ floating-point operations per pass. Best-of-3 measurement with adaptive warm-up so laptop GPUs that idle at low power get a fair reading. Output is GFLOPS (billions of FP operations per second).

— CPU single + multi

SHA-256 hash chain

Single-core: SHA-256 hash chain on the main thread via Web Crypto API. Multi-core: same workload across N Web Workers where N = navigator.hardwareConcurrency. Output is hashes per second. Multi-core scaling efficiency is also reported.

— RAM bandwidth

TypedArray throughput

Sequential reads, sequential writes, and a random-access pointer-chase on a 256 MB Float32Array. Reports GB/s read, GB/s write, and ns latency. Browser sandboxing caps this at 30-50% of native — we never pretend otherwise.

2. The formulas

Every component score is a simple linear or logarithmic transform of the raw measurement. There is no proprietary "magic" — anyone can reproduce these numbers.

GPU score
round(GFLOPS × 3)

Calibration: a typical 2024 mid-range GPU (~500 GFLOPS in browser) scores ~1500. RTX 4070-class hits ~3000 in browser (well below native ceiling).

CPU single-core score
round(SHA_per_sec_single / 300)

Calibration: Apple Silicon high-end ~1300, modern x86 ~1000-1500.

CPU multi-core score
round(SHA_per_sec_multi / 600)

Multi-core counts cores divided by 600. Browser Web-Worker scaling is structurally below native (~3-5× speedup typical for 16-core instead of native ~12×).

RAM score
round(((read_GBs + write_GBs) / 2) × 60)

Average of read + write bandwidth × 60. Browser-sandbox-capped — see section 5 for limits.

3. Composite weighting

The 9bench overall score is a weighted geometric mean of the four component scores. Geometric mean prevents a single weak component from being masked by strong ones — the "no shortcut" version.

overall = exp(0.35 × ln(GPU) + 0.45 × ln(CPU·M) + 0.20 × ln(RAM))

We don't include CPU single-core in the composite because it correlates strongly with multi-core for in-browser SHA workloads. Including it would double-count.

When a component can't be measured — no WebGPU adapter, a parallel phase that doesn't report, a memory allocation the browser refuses — that component is dropped and the remaining weights renormalize over what was actually measured. Written in general form, over the set S of measured components with total weight W:

overall = exp( Σi∈S wi × ln(scorei) / W ), where W = Σi∈S wi

The two common cases fall straight out of it and produce exactly the same numbers as before, so no stored score has ever changed:

A run that measures less than 65% of the total weight is not scored at all. It is shown to you with whatever did measure, but it gets no composite, is never submitted, is in no percentile pool and is not on the leaderboard. Below that threshold the number would be a statement about our measurement failing rather than about your hardware.

Partial runs are labelled by basis everywhere they appear — page, share card and preview image — ranked only against runs measured the same way, and kept off the main leaderboard. An unmeasured component is never reported as a zero and never named as your bottleneck.

4. Tier brackets

Tiers are descriptive labels for sharing, not gospel. We use letter-tiers (S/A/B) for the top half because that's Reddit-shareable, and word-labels for the bottom half because no one shares "D-tier".

TierScoreDescription
S-tier ≥ 1386Enthusiast / workstation
A-tier ≥ 900 Power user
Solid daily driver ≥ 600 Comfortable for most work
Working machine ≥ 300 Office class
Patient & honest ≥ 0 It still gets the job done

5. What we cannot measure

⚠ Honest Disclaimer · Truth Series
Browsers sandbox memory access. The RAM number is relative, not native bandwidth. We could hide that and pretend our number is gospel. We don't. Read the methodology.

Browsers cap absolute throughput on RAM workloads via the JavaScript memory model (no SIMD-vectorized memcpy, no DMA, no direct mmap). Browser RAM scores typically run at 30-50% of native. We disclose this on every result page.

We also cannot measure: thermal throttling under sustained load, disk/SSD I/O, network bandwidth, GPU memory bandwidth (only compute), peak-vs-sustained turbo behavior. For those, install a native benchmark.

What we can measure: relative ranking across machines. 9bench is calibrated for cross-platform fairness — a 2024 MacBook Pro and a 2024 Windows desktop running the same browser produce comparable composite scores within ±5-10%.

6. Validation against native benchmarks

Until July 2026 this page claimed 9bench landed "within 3-10% of native benchmarks for CPU and GPU compute." That number was never measured. It was an estimate that got written down as a fact and then repeated on the landing page. This section replaces it with the only paired data we actually have, including the part that makes us look bad.

The test

Two laptops, same chassis model, same session, same day, both on mains power. Each ran 9bench once and Geekbench 7 once. n = 2 machines, one run each.

The numbers

MeasurementDevice ADevice BA / BAgrees?
9bench GPU (GFLOPS)372.8230.31.62×
Geekbench 7 OpenCL87,33471,5591.22×same order
9bench CPU single (h/s)468,274387,2971.21×
Geekbench 7 CPU single1,9322,0110.96×INVERTED
9bench CPU multi (h/s)1,293,243916,5991.41×
Geekbench 7 CPU multi9,67510,8160.89×INVERTED
Multi ÷ single (9bench)2.76×2.37×
Multi ÷ single (Geekbench)5.01×5.38×we understate

What agrees

The GPU ranking. Both benchmarks put Device A ahead; we simply show a wider gap. Our test is a single untiled 1024×1024 FP32 matmul with an arithmetic intensity of about 2 FLOP/byte, so it is limited by cache and memory bandwidth rather than raw FP32 throughput. Geekbench 7's GPU suite is a geometric mean over ML, raytracing and image workloads that lean on units scaling with SM count — its 1.22× is close to the 1.20× SM ratio. Two benchmarks measuring different things, agreeing on order.

For scale: 372.8 GFLOPS is 2.9% of the 4060 Laptop's theoretical FP32 peak, and 2.0% for the 4050. A naive-but-coalesced native CUDA kernel reaches roughly 5% of peak; cuBLAS reaches about 60%. Our GPU number is therefore around half a naive native kernel and a twentieth of an optimised one. It is a throughput probe, not a peak-FLOPS measurement.

What does not agree

Both CPU rankings inverted. 9bench ranked A above B on single-core and multi-core; Geekbench ranked B above A on both. Two separate causes, both in our code:

Note which way the barrier bias actually points: it penalises the machine with more threads, so on its own it should have put Device B ahead. The observed result is the other way. The barrier is a real defect, but the dispatch-bound workload is what produced this inversion.

Re-tested after the v3.6 estimator fix

Both machines were re-run on v3.6, same day, same conditions. Two of the three rankings are now correct. One is not.

A / B ratio9bench v3.69bench beforeGeekbench 7Result
GPU1.23×1.62×1.22×matches
CPU single-core0.88×1.21×0.96×order fixed
CPU multi-core1.14×1.41×0.89×STILL INVERTED

So the v3.6 note that the estimator fix would correct the ranking was itself too confident. It corrected two of three. The multi-core ranking needs the workload replaced, not the estimator — that is v4.0, and it does not ship until it has been validated against native references on at least five machines. Until then the multi-core number should be read as a measure of the browser's parallel crypto throughput, which is a real thing and reproducible, but is not a CPU ranking.

What this does NOT establish

If you have run both 9bench and Geekbench on the same machine, file an issue with both result links. Paired data is the only thing that turns this section into a real validation, and right now we have one pair.

7. FAQ

Is 9bench accurate?
It depends which number, and we now have data instead of an assertion. GPU: a real relative measure. On our one paired test the GPU ranking matched Geekbench 7's order, with a wider gap (9bench 1.62x, Geekbench 1.22x) because our untiled matmul is bound by cache and memory bandwidth. CPU: currently not a reliable ranking. On the same pair, 9bench put machine A ahead by 21% single-core and 41% multi-core; Geekbench put machine B ahead by 4% and 12%. Both inverted. Two causes: at a 64-byte payload most of the measured time is crypto.subtle dispatch rather than SHA-256, and the multi-core estimator reduces to thread count times the slowest worker's rate. RAM: browser-sandboxed, 30-50% of native, as always stated. n=2, one run per machine — enough to disprove a claim, not enough to calibrate one. Section 6 has the full table. The earlier answer here claimed 'within 3-10% of native for CPU and GPU compute'; that figure was never measured against a native benchmark and is retracted.
Does 9bench take money from chip vendors?
No. Zero. The 'Vendors paid us: 0' counter on the Landing page is hardcoded to 0 because that's a fact. r/hardware banned UserBenchmark for documented anti-AMD bias; we built 9bench to fill that gap with an open-source, vendor-neutral alternative.
Why does my RAM score look so low?
Browsers (V8, SpiderMonkey, JavaScriptCore) sandbox memory access for security. Float32Array reads and writes are not vectorized to the same degree as native code, and there is no SIMD pathway for arbitrary memory work. Typical browser RAM throughput is 30-50% of native. We could pretend our number is gospel; we choose to disclose this on every result page instead.
Does it run on iPhone / iPad / Android?
Partly. Safari 26+ on iOS/iPadOS 26 has WebGPU. On Android it depends on the GPU vendor and Android version, not just the Chrome version — many phones have it switched off. Those devices run the CPU + RAM tests and get a clearly-labelled CPU+RAM-only score, ranked in its own pool.
Why is it free?
Because it costs us $0 to run. The benchmark executes entirely in your browser. The only server cost is storing the optional submitted score in Cloudflare D1, which is essentially free at our scale. No tracking, no upsell, no premium tier.
How is this different from UserBenchmark?
UserBenchmark has documented anti-AMD bias (caught by independent reviewers in 2019, banned from r/hardware and r/AMD). 9bench takes zero money from chip vendors. The scoring formula is in this page and on GitHub. r/hardware can verify every weight.
Where is my data stored?
The benchmark runs locally in your browser. The test page has a consent box (default-on) — when checked, an anonymous summary is submitted to Cloudflare D1 after the test finishes. The submitted row contains: score breakdown, GPU name string, CPU core count, AI capability snapshot, a short 'Browser-Major / OS / Arch' UA fragment, timestamp, and a random 8-char hash ID. No IP address, no cookies, no fingerprints, no geolocation. Uncheck the box before clicking Start to run the benchmark without storing anything.
What does 'self-reported' mean on a GPU name?
Some browsers (Firefox in strict privacy mode, Tor, Brave Strict) hide GPU info from web pages. When that happens, 9bench shows 'Browser hides this — add manually' and lets you type your GPU. Self-reported entries are tagged so they cannot be confused with detected hardware.

8. License

9bench is MIT-licensed. You can fork it, ship your own variant, run it commercially. Truth-series tools should not be locked behind proprietary licenses. Source on GitHub.

Built independently. Sister project of Toololis. Author identity.

9. Changelog

A benchmark that changes its measurement silently cannot be trusted. Every change to how scores are measured or computed is documented here, including our own mistakes.

v3.2 — July 10, 2026

v3.7 — July 29, 2026

v3.6 — July 29, 2026

v3.5 — July 29, 2026

v3.4 — July 29, 2026

v3.3 — July 28, 2026

v3.1 — April 30, 2026

10. The v4.0 gate — pass criteria, published before the data exists

The v4.0 CPU workload (two WebAssembly kernels: a SHA-256 integer chain and a Mandelbrot f64 loop, both self-verifying against tables computed at build time by independent implementations) replaces the current workload only if all of the following hold. These criteria were published before shadow collection began and do not move after we see the numbers.

Failure branch, precommitted: any gate fails → the candidate is revised (revision counter bumps, the gate clock restarts for affected metrics) or v4.0 is dropped; the failure is published here with the numbers. Shadow collection hard-stops after 12 weeks regardless — a permanent 12-second parasite on your time would be its own honesty failure.

Anti-cherry-picking rule: every submitted pair meeting the hygiene criteria enters the analysis, and the raw pair table ships as CSV in the repository before the verdict. We cannot drop the pairs that make us look bad.

We need your paired references. If you can run 9bench and Geekbench 6/7 on the same machine: run /test/?v4solo=1 (cold machine, mains power, nothing heavy running), then file a validation-pair issue with the JSON block the solo run prints, your public Geekbench result link and version, your /r/ link from a normal run (same-machine provenance), the browser used, and the OS power mode. Most wanted right now: Apple Silicon (any M-series), Snapdragon/Dimensity Android, AMD Zen 4/5, and older 4-core machines.

▶ TEST MY HARDWARE View leaderboard