Processor and graphics card specifications are live

Reference·Methodology

Measurement identity 2026.09.18

How SystemCheck measures your PC.

The record of how every number on this site is produced, what each one is derived from, and what it cannot tell you.

Forensic scoring v3Standard, Deep and Extended runsProvisional calibration

What this page is for

SystemCheck makes measurement claims, so it owes you the arithmetic behind them. This page is the reference: what each stage runs, how long it runs for, what is sampled and at what rate, how those samples become a decay figure and a grade, and where the measurement stops. Everything below describes the code that actually executes in your browser. Where a figure is an assumption, a placeholder, or a provisional constant, it is named as one. If you have a hardware monitor open beside the run, you should find nothing here that claims more than the browser can see.

Specification at a glance

Each stage’s workload in general terms, how long it runs, what is discarded at the start, how it is sampled and what is left out. Every figure in this table is read from the constants the stages run on.

CPU
A floating-point WebAssembly kernel in Web Workers, one per logical processor the browser reports, up to 32, with a JavaScript fallback. Length: 60 s Standard, 150 s Deep, 600 s Extended. Warm-up: 1.5 s. Sampling: 250 ms windows. Left out: Warm-up, and every window that overlaps time the tab was hidden or without focus.
Memory
Array copies in Web Workers, one stream then up to six, and a dependent-load walk for latency. Length: 5 s one stream, 8 s all streams, then the latency walk. Warm-up: The ramp at the start of each phase. Sampling: 250 ms windows. Left out: The ramp, and every window that overlaps time the tab was hidden or without focus.
GPU raster
A WebGL2 raster scene at a fixed 1600 by 900 render target, on a camera path that repeats every 10 s. Length: 50 s Standard, 3 loops of 30 s Deep and Extended. Warm-up: 3 s. Sampling: One-second windows of frames timed to GPU completion. Left out: Warm-up, and every window that overlaps time the tab was hidden or without focus.
Soft shadows (Deep)
One procedural scene at a fixed 1600 by 900, soft and hard shadow modes in alternating segments. Length: 6 segments of 9 s after the warm-up. Warm-up: 6 s. Sampling: One-second windows. Left out: Warm-up, and windows without focus; a segment that loses more than half its windows takes its pair out.
Path tracing
A WebGL2 raymarched scene at a fixed 960 by 540, frames back to back. Length: Until the run's fixed deadline (less the hot re-test on Deep and Extended). Warm-up: The first sample, which pays for shader compilation. Sampling: Each sample timed to GPU completion. Left out: The first sample, and every sample that overlaps time the tab was hidden or without focus.

The stages

There are three kinds of run. A Standard run is three minutes from launch to report and runs four stages in this order: CPU, memory, GPU, and path tracing. A Deep run is nine minutes and runs eight: the screen, CPU, memory, the GPU pass looped three times, CPU and GPU loaded together, soft shadows, path tracing, and a hot re-test of the CPU. An Extended run is sixteen and a half minutes: the Deep run’s eight stages with a ten-minute CPU stage. The stage numbers below follow the Standard run; the Deep and Extended runs are described in their own section.

Stage 1

CPU sustained throughput, 60 seconds

One Web Worker per logical processor runs a floating-point kernel, compiled to WebAssembly, in time-boxed chunks. The main thread attributes the finished work to fixed 250 ms windows, four samples a second, and keeps the whole series. On a Deep run the stage lasts two and a half minutes.

Stage 2

Memory bandwidth and latency, about 20 seconds

Workers stream 24 MiB arrays to measure bandwidth with one thread and then with up to six, and a single worker walks a random 64 MiB chain of dependent loads to measure the memory round trip against a 128 KiB cache walk. The six-stream bandwidth is scored; latency and scaling are reported.

Stage 3

GPU raster at a fixed 1600 by 900, 50 seconds

One lit model renders at a fixed internal resolution of 1600 by 900 pixels, whatever the window size, on a camera path that repeats every 10 seconds. Frames are timed to GPU completion in batches of a few frames, so the figure is the chip's frames per second at that resolution, not the display's refresh. On a Deep run it loops three times, 30 seconds each.

Stage 4

Path tracing under continuous load, to the end of the run

A WebGL2 raymarched scene with one reflection bounce, cone-traced shadows and ambient occlusion (the stage keeps the name path tracing; see its section for what the work is) runs frames back to back at a fixed 960 by 540 pixels, so the GPU is loaded for the whole stage. On a Standard run it is the last stage and runs until the run reaches three minutes; on a Deep run it runs until 30 seconds before the deadline, when the fixed hot re-test starts. Samples per second is the measurement.

Stage 1, CPU sustained throughput

The stage runs for 60 seconds on a Standard run and 150 seconds on a Deep run. At the start, SystemCheck reads the number of logical processors the browser reports and clamps it to between 1 and 32, then creates one Web Worker per processor. Each worker loops a floating-point kernel that computes a square root, a sine, and a cosine per iteration and accumulates the result into a sink so the engine cannot optimise the loop away. Since revision 2026.09.17 the kernel is WebAssembly, with the sine and cosine worked out by the kernel itself rather than by the browser, so the figure follows the processor and not the browser’s JavaScript engine. Each worker checks the kernel’s answer before trusting it; where WebAssembly is missing or wrong, the stage runs the earlier JavaScript kernel and the report says so, and those figures are not compared with WebAssembly ones. Workers run in 90ms chunks and yield an 8ms slice between chunks, which is what keeps the progress readout alive while every core is loaded.

Each worker reports every chunk with its start, end and iteration count, and the main thread, ticking every 150ms, attributes that work to fixed 250ms windows in proportion to overlap. That gives four samples a second, about 240 across a 60-second stage. It also records, for diagnostics only, how far each tick drifted from its scheduled time, on a scale of our own (100 on time, falling 0.35 points per millisecond late) that is not shown as a figure and not scored: it is a measure of scheduling pressure, not of the CPU itself.

The first 1.5 seconds are discarded as warm-up, which covers worker start and engine tier-up but not the boost window that follows, because that is part of the signal. From what remains, SystemCheck reports the peak and the valley of the per-second means, the sustained rate as the mean of the whole post-warm-up pool, and a consistency figure equal to one minus the coefficient of variation across the per-second means, expressed out of 100.

The throughput shown while the stage runs is the same unit as the report: counted kernel iterations, in millions per second across all workers (M iter/s), with the per-thread figure beside it. Before revision 2026.09.7 the live tile multiplied the count by 68, an estimate of the floating-point operations one iteration performs; that constant was an assumption, not a measurement, and it is gone. Compare the figure against your own earlier runs, and do not compare it against another benchmark that counts operations differently.

Stage 2, memory bandwidth and latency

The stage runs for about 20 seconds and sits second so that both CPU-side measurements happen before the GPU stages warm the chassis. Up to six Web Workers are created, clamped to the number of logical processors. Each worker owns two 24 MiB double-precision arrays and copies one into the other in a loop, which the engine executes as a plain memory copy.

Bytes read plus bytes written are counted per 80ms chunk and the main thread attributes them to fixed 250ms windows. For the first five seconds one worker streams alone; for the next eight, all of them do. Each phase reports the mean of its last 60% of samples, past the ramp. The working set, 48 MiB per thread and 288 MiB in total, is far past any last-level cache, so the figure is the memory system rather than the cache.

The ratio between the two bandwidth figures is the part that carries a reading. A memory system with headroom gives added threads more bandwidth; one that is already filled by a single thread does not. Below 1.35× the report says the bandwidth scales like a memory system one thread already fills, and that the memory system rather than the cores looks like the ceiling; it names no hardware, because a browser cannot see what is fitted or how it is wired, and a single JavaScript thread is itself limited in how many loads it keeps in flight. The 1.35 and 2.2 lines are ours, not taken from a standard. The report does not claim to know the channel count, clock, timings or capacity, because no browser API exposes them. A hidden tab stops the stage’s clock, and bandwidth windows that overlap the hidden time are not counted; the globe drawn behind the stage holds still while the phases measure, so it does not compete for the bandwidth.

Latency is measured last, with every stream stopped so the walk is uncontended. One worker fills a 64 MiB array of 32-bit indices with a single-cycle random permutation (Sattolo’s algorithm, so the walk visits every element with no short loops) and then follows it for three million steps. Every load depends on the previous one, so the processor cannot prefetch or overlap them, and the time per step is the round trip to memory including translation misses.

Four rounds are taken and the median reported, because the first round pays the translation warm-up. The same walk through a 128 KiB array gives the cache round trip for contrast. Of the memory figures, only the six-stream bandwidth is scored (since revision 2026.09.8, as a tenth of the score, between provisional bounds given under the score below). Latency and scaling are reported and not scored: the dependent-load walk is timed by the JavaScript engine’s own loop, and scaling depends on how many loads one engine thread keeps in flight, so a Chromium, Firefox and Safari figure for the same machine differ by the engine rather than by the memory, and neither belongs in a number that is compared across them.

Stage 3, GPU raster at a fixed resolution

The stage runs for 50 seconds on a Standard run, and as three 30-second loops on a Deep run. One model renders at a fixed internal resolution of 1600 by 900 pixels with a device pixel ratio of 1, independent of the window, and the result is scaled to fit the screen. The camera follows the same path on every machine and repeats every 10 seconds. After the warm-up the stage waits for the graphics chip to finish once every few frames, a one-pixel read-back about every 100 ms and never fewer than 4 frames apart, and divides each batch’s time by its frame count, so a frame time is the time the GPU took to finish its frames, not the time the browser took to queue them. Until revision 2026.09.13 it waited after every frame, and on the validation laptop that wait was held to the display’s refresh: the stage read 60 frames a second while the chip needed 4 to 5 ms a frame. Where the browser exposes a GPU timer query, a GPU-side time is recorded alongside; where it does not, the report says so, and nothing about the frame rate changes. The first 3 seconds are excluded, which covers shader compilation and driver warm-up. The stage tries three scenes in order and records which one loaded; a run that fell back to a second scene is a different workload and the report says it is not comparable with runs on the primary.

From what remains: the scored figure is the peak frames per second at 1600 by 900, the median of the best five one-second windows. The sustained figure, the frames counted divided by the active time, is printed beside it under its own name so the peak is never read as the whole stage. Mean and 95th percentile frame times cover the whole stage. Stability is the share of one-second windows within 85% of the median window.

If frame times sit at the timer’s resolution or exactly at a display refresh interval, the report says the frame rate is at a floor: the GPU may be faster than the figure shows, so the figure is a lower bound. The frame-time class recorded during the stage (a VRAM badge, before revision 2026.09.7) is a load label derived from frame time, not a memory reading. If the scene cannot run and a video stands in, every figure shown during the stage is labelled an example, not a measurement, and the result is flagged so nothing scores it. The tab being hidden pauses the stage and its clock, and the hidden time is reported. Results from before revision 2026.09.3 used an adaptive supersampling index instead and are not comparable.

Stage 4, path tracing under continuous load

Path tracing follows the GPU stage on a Standard run, and the combined stage on a Deep run, without a pause, because a pause lets the machine cool. It requires WebGL2 with floating-point render targets. On the name: the stage is called path tracing, and the work is a raymarched scene with one reflection bounce, cone-traced shadows and ambient occlusion. A fragment shader sphere-traces a signed-distance-field scene, a chrome ball rolling through a course of pillars and gates in a white studio, one primary ray per pixel per frame, shades the hit with a key light, a fill light and a sky term, traces one cone toward the key light for a soft shadow, probes along the normal for ambient occlusion, and follows one reflection for the ball and the floor. Every term is evaluated once per pixel per frame; there are no random light paths, and the only chance in a frame is a sub-pixel jitter for antialiasing. That is a Whitted-style raymarcher, not a Monte Carlo path tracer. The name stays because it is the name people know the stage by; the figure it produces is real GPU work, one 960 by 540 frame of it per sample. Each sample is written with the depth its ray reached; the display pass, which is never timed, lays the frames on each other by reprojection, since the camera and the ball move deterministically and every pixel of the last frame can be placed on this one, so the picture converges without smearing what moves. Since revision 2026.09.7 the scene is stepped by the stage’s own clock, 1.2 units of roll per second, so a slow chip and a fast one trace the same course over the same seconds and only the number of frames differs; before it the scene advanced one step per sample, so a fast GPU rendered views a slow one never reached. Since revision 2026.09.10 every pixel does the same work whatever it shows: the marches, the shadow cone and the occlusion probes run fixed counts on every pixel, so the cost of a frame does not follow what the camera sees. The stage has a fixed length, so the run keeps its fixed length on every GPU, and within it samples run back to back: the GPU is loaded for the whole stage rather than for one sample every so often. Results from before revision 2026.09.4 traced a still scene of two spheres; its per-sample cost was matched when the scene changed, and reports across that revision are not compared.

The internal resolution is fixed at 960 by 540 pixels, independent of the window and of the device pixel ratio, so a high density display does not quietly change the workload. Each sample pass is timed to GPU completion with a sync point, and GPU-side time is recorded where the browser exposes a timer query. The on-screen image is refreshed at most about 30 times a second, and that display pass is not part of the timing.

Samples per second is the samples measured divided by the active time, after the first sample, which pays for shader compilation. Consistency is one minus the coefficient of variation across the per-sample times, and it is null, not a number, when nothing was timed. Fewer than 20 measured samples and the result is not trusted. A hidden tab pauses the stage and its clock, and the hidden time is reported. Results from before revision 2026.09.3 paced the tracer to about 150 samples and are not comparable.

Soft shadows: a Deep stage and a test of its own

Soft shadows run as the sixth stage of the Deep run, after the combined load, and as a standalone test on the soft shadows page. The workload and arithmetic are the same in both, and neither affects the score. A stage the browser reports as hidden when it begins does not run, and the report says the stage did not measure. It renders one procedural scene at a fixed 1600 by 900 with a light that has size, and each frame draws a 2048 by 2048 depth map from that light and then the scene. In percentage-closer soft shadow mode each pixel takes 16 samples of the depth map to find the average blocker depth, estimates the penumbra width from it, and filters with 32 more samples rotated per pixel. In hard-shadow mode it takes one sample.

After a 6-second warm-up the two modes run six 9-second segments, three each, in the order PCSS, hard, hard, PCSS, PCSS, hard, on a camera path with a 9-second period, so both modes see the same views and a machine that warms up slows both. Frames render off screen and are timed to GPU completion; the picture on screen is refreshed about 30 times a second and that time is excluded from the figures. The PCSS frame rate is the median of the best five one-second windows in the PCSS periods; the soft-shadow cost is one minus the PCSS rate over the hard-shadow rate, stated as a lower or upper bound when either mode sits at a timer or display-refresh floor; stability and decay are computed over the PCSS periods the same way as the GPU stage.

The standalone tests

Six tests run on their own pages and nowhere else. None is a stage of the Standard, Deep or Extended run, none contributes to the score, and none moves the measurement revision; each imports the run’s own code where it reuses it, so a figure that shares a unit with a stage is in that stage’s unit. Each reports a fallback flag when it could not run the way it is described, and an interrupted flag when the tab was hidden for more than a second, and every constant below is read from the same file the test runs from.

Recovery: speed after an idle break

The CPU stage’s workload runs on every logical core for 15 seconds, stops for 45 seconds of nothing (no workers, a countdown drawn four times a second), then runs again for 15. The reference is the mean of the first phase’s last 5 seconds; the burst figure is the mean of the second phase’s first 5; recovery is the burst over the reference as a percentage, and above 100 is reported as measured, because a power budget that resets on idle gives exactly that. The time to settle is the first one-second bin of the burst at or above 95% of the burst’s own final level, the mean of its last 5 seconds, and it is reported only when that level held still, its bins within 10% of their mean. The noise floor is the reference’s median sample-to-sample change after its 1.5-second warm-up, as a share of its mean; a recovery gap inside 2.5 times that floor is called within noise and reads as recovered. The verdict lines are ours: recovered at 95% or above, held back below 70%, partly between. The 45-second break is our choice and shorter than a real one, so a machine that needs longer to cool reads as not recovered here, which is a true statement about 45 seconds. The test cannot see temperature or a firmware clamp; it sees the speed that came back. The idle break runs on an active clock, so a hidden tab stops the countdown while the machine keeps cooling, and the result says so.

Storage: the browser’s file path

A 64 MiB file is written into the Origin Private File System, the private store the browser keeps for this site, through a synchronous access handle inside one worker: 16 chunks of 4 MiB filled with a fixed pseudo-random pattern, so a store that shortcuts empty pages cannot make the write look free, then one flush, then the same 16 chunks read back, then 2,000 reads of 4 KiB at offsets from a fixed-seed generator, and that is one pass. Passes repeat on the same open file until at least 30 seconds of active time have passed and at least 3 passes are complete, the rule every test here follows so that a figure is a median and not a moment; then the file is deleted. Every time is taken inside the worker around the call alone, so the message hops are in no figure. Within a pass, sequential write is the file’s bytes over the chunk times plus the flush, because until the flush returns the bytes may still be in a buffer, and the flush’s own time is stated beside it; sequential read is the bytes over the chunk times; random read is reads per second with the mean microseconds per read. Each reported figure is the median of the passes, with the spread between passes (max minus min over the median) and the pass count beside it, and the first pass stated on its own because it includes the file’s first allocation; it is in the median like any other pass. Megabytes are decimal. The spread of the per-chunk rates in the median pass, max minus min over the mean, is stated so a cache filling part way through shows. What it cannot see is the drive: the figure is the browser’s path, behind its own layer and the operating system’s cache, and a read this soon after a write is usually served from that cache. A browser without a synchronous handle reports not supported; a quota refusal is reported and not retried.

The storage page has a second mode, sustained write, chosen before the run. One file is written in 32 MiB chunks for up to 2 minutes of active time or until a cap, each chunk filled with its own seeded pattern and timed around the write alone, with a flush every 256 MiB whose time is shared across the chunks it flushed. The cap is the lesser of 8 GiB and 80% of the free space in the browser’s own storage estimate, stated before the start; nothing beyond the quota the browser already grants is requested. The curve is the per-chunk rate over the bytes written. The baseline is the median of the first GiB; the cache size estimate is the bytes written before the rate fell below 50% of that baseline and stayed there for at least 3 chunks, both our lines, so one slow chunk is not a cliff. The post-cache rate is the median from the fall to the end, and the ratio is the baseline over it. A curve that never falls is reported as no cache cliff within the size written, which is common and fine. Most TLC and QLC drives write first into a fast SLC cache, and the fall is where it fills. After the write every 8th chunk is read back and compared word by word with its pattern; a mismatch would point to a faulty drive or path. The path includes the operating system’s cache, so the first figures can be flattering. The browser’s private store is on the system drive, so this mode tests the system drive; a fake-capacity stick or card is tested by writing to it directly with a native tool such as H2testw, F3 or GRC ValiDrive, all free.

Responsiveness: the page’s thread under load

Three probes run on the page’s own thread for 10 seconds idle and then for 30 seconds beside the CPU stage’s workload on every logical core but one, the one left free being the thread measured; every test here runs at least 30 seconds, so a figure is a median over a run and not a moment. Every 50 ms a setTimeout(0) and a MessageChannel message are posted and the delay until each callback runs is recorded; the two are pooled and their median and 95th percentile (nearest rank) reported. Every 200 ms a synthetic pointer event is dispatched and the time to the next animation frame recorded, its 95th percentile reported. Every animation frame interval is recorded, and the share over 1.5 times the display’s nominal interval, taken as the median of the idle phase’s intervals, is the missed-frame figure. Each loaded figure is shown beside its idle one. The verdict reads the loaded p95 delay: under 50 ms is responsive, our line, about three frames at 60 Hz; 200 ms and over is unresponsive, borrowing Google’s Interaction to Next Paint good line; between is hesitant. The input figure is read against that 200 ms line as a comparison point, stated as a published line for real interactions rather than one this figure was defined by. A phase needs 20 pooled pings before a percentile is reported. What it cannot see is which process took the time: a delay is the browser’s scheduling, the operating system’s and every other program’s summed. If workers could not start and the load ran on the page’s thread, the probes measured a thread measuring itself, and the result is a fallback and not comparable.

WebGPU compute: a shader with its count stated

A WGSL compute shader loads one 32-bit float per invocation, performs 256 fused multiply-adds that each depend on the last, and stores it back, in workgroups of 256 over 4,194,304 elements: 4,194,304 x 256 x 2 = 2,147,483,648 floating-point operations per dispatch, counting a fused multiply-add as two. Each dispatch is submitted alone and timed from the submit to the promise of queue.onSubmittedWorkDone, the browser’s own fence, after 3 warm-up dispatches that are timed and dropped, for 30 seconds of active time (the owner’s rule that no test runs under 30 s, so a figure is a median and not a moment). The dispatches are cut into windows of one second of their own summed times; each window’s GFLOP/s is operations times its dispatches over their time, the headline is the median window, and the spread between windows (max minus min as a share of the median) is stated beside it; a trailing fragment under half a second is dropped. The mean over every dispatch at once is a second figure; dispatches per second is the same sum the other way; consistency is one minus the coefficient of variation of the dispatch times, out of 100. A 64 MiB buffer, filled first, is then copied to another 20 times with the same fence, and the copy figure counts each copy’s bytes once, in decimal gigabytes. The adapter name is what adapter.info reports, joined from its description, vendor, architecture and device fields, and is null when it reports nothing; it is never looked up or inferred. What the figure includes is the browser’s submission and completion overhead on every dispatch, which on a fast chip is most of a two-billion-operation dispatch, so the figure is what a page gets and sits well under a rated peak; the page says so and subtracts nothing. A browser without navigator.gpu reports not supported; an adapter that reports itself as a fallback adapter ran the shader on the processor, and the result is flagged as such. A result needs 10 timed dispatches.

CPU stability: answers known in advance

One Blob worker per logical core, capped at 32, cycles through three tasks whose answers are fixed by arithmetic, for 5 minutes of active time by default or 60 seconds in the quick run, never under the owner’s 30-second rule. The integer task is a xorshift128+ stream (shifts 23, 17 and 26) of 400,000 outputs from one of four fixed seeds, folded into a 64-bit checksum by rotate-left-one then XOR in two 32-bit halves, and checked in the tests against a separate 64-bit BigInt implementation. The float task sums sqrt(k + seed) / (k + seed + 0.5) for k from 1 to 200,000 in that order in double precision; IEEE 754 and ECMAScript round addition, division and square root exactly one way, so the sum is compared bit for bit. The prime task is the Lucas-Lehmer test of 2^p - 1 with BigInt for p of 67, 127, 521, 607, 1277 and 1279, whose answers are known from the list of Mersenne primes (67 and 1277 composite, the rest prime), with the low 64 bits of the final residue compared too. The answers are computed once on the page’s own thread at the start and must equal the ones stored in the code, or the run does not start; each worker’s results are then checked on the page’s thread, so a wrong answer is attributed to the worker, the task and the seed. No error passes and any error fails; there is no tolerance, because a correct processor never gets one wrong. A mismatch means an instability, with an overclock or undervolt set too aggressively, heat, or failing hardware as possibilities the test cannot tell apart. Throughput, checks per second per thread over each second of active time, is a secondary curve, with its median reported. A browser cannot reach AVX-512 or the heaviest vector paths a native torture test uses, so a pass here is not a pass of Prime95’s small FFTs; Prime95 and y-cruncher are the native references. The durations are our line. A hidden tab pauses the workers and the clock, and the result says so.

GPU artefacts: exact answers checked

Three parts on one WebGPU device, each with an answer that has one right value. Compute: each of 4,194,304 32-bit words starts from a fixed seed XOR its index times 0x9e3779b9 and goes through 64 rounds of xorshift32 (shifts 13, 17, 5) plus 0x6d2b79f5; a second shader reduces the buffer on the chip to its wrapping 32-bit sum and its XOR, and only those eight bytes are read back. The same checksum is worked once in JavaScript with the same unsigned arithmetic, and the known-answer tests check that reference against an independent BigInt implementation. The buffers are cleared before every dispatch, so a shader that did not run cannot repeat the last answer. Dispatches repeat for 30 seconds of active time, the floor every test here keeps; a dispatch whose checksum differs is a compute error, and the first is named. Memory: storage buffers of 256 MiB, or the device’s binding limit if smaller, are allocated one at a time inside an out-of-memory error scope until 2 GiB or the first refusal, and the result says “tested N MiB of the memory this browser allowed”, never the card’s size. Each of 2 passes writes three patterns into every buffer with a compute shader (a walking one, 1 shifted by the address plus the pass; the word’s own address, inverted on odd passes; a seeded xorshift word), writing every buffer before reading any so the words are read from memory and not a cache, then a second shader re-derives each word and counts mismatches on the chip. Render: 2,000 alpha-blended triangles placed and coloured by a hash of their index, with no time input, are drawn 600 times to an offscreen 512 by 512 RGBA8 texture; each frame is hashed on the chip (every pixel mixed with its index, then summed and XORed) and compared with the first frame. The chip is compared with itself and never with a stored image, because two drivers may draw the same scene legitimately differently. The verdict line is ours and it is zero: any error in any part fails, and the failure copy names overheating, an overclock, failing memory and a driver fault as possibilities, not a diagnosis. A shader or pipeline the browser refuses ends the run as an error, never as a failed chip. What it cannot see is memory the browser does not hand a page, and any fault the driver or the browser corrects or hides before the page reads the result.

The deep run

The standard CPU stage is 60 seconds: long enough to catch a sustained-power budget expiring, which on Intel parts happens after a boost timer of 28 seconds at stock and 56 seconds on some boards, and short enough to sit through. It is too short for cooling to saturate. Reviewers who measure that run Cinebench for ten minutes or longer, and a laptop typically settles two to three minutes in.

The deep run is exactly nine minutes across eight stages, ordered to build heat and then price it: the screen, the CPU stage, memory, the GPU pass looped three times, CPU and GPU loaded together, soft shadows, path tracing, and a hot re-test of the CPU on the warmed machine, set against the cold stage. Path tracing runs until 30 seconds before the deadline, so it absorbs whatever the earlier stages lost; the hot re-test is a fixed 30 seconds on every machine and starts the instant path tracing ends, with no transition screen, because seconds with nothing running are seconds the machine cools. The re-test is compared with the cold stage’s settled level, and the two are called matched when the difference sits inside the run’s own noise gate: 2.5 times the larger sample-to-sample jitter of the two stages, and never under 1%. Both figures are our lines. Before revision 2026.09.7 the re-test ran to the deadline, followed a transition screen, and was called matched inside a flat 1%.

The combined stage runs one CPU thread fewer than the solo stage on machines with four or more logical cores, to leave a core for the frame loop, and the report says so: the CPU comparison is per thread, combined throughput over the threads it ran against solo throughput over the threads the solo stage ran, so the reserved core is not booked as a cost of combined load. The GPU comparison is solo frame time over combined frame time, shown as measured; over 100% means the combined pass ran faster, which noise or a warmed shader cache can produce.

The soft-shadow stage runs six nine-second segments after its 6-second warm-up, 60 seconds in all, in the order PCSS, hard, hard, PCSS, PCSS, hard. A machine that warms during the stage slows the later segments; a strict alternation starting on PCSS put the soft mode first in every pair and read its cost low. In this order each mode is first in one pair and second in the next, so a steady drift cancels, and the cost inside each pair is computed too: the spread between the three pairs is printed as the figure’s error bar in place of any claim that it is exact.

The CPU stage runs for two and a half minutes. The settled level is the median of the means of three 20-second windows in the last minute, and the spread of those three is reported with it, so a level that was still moving is not presented as settled. The moment the machine reached that level is the end of the last ten-second bin that sat above it by more than the run’s own noise gate: 3%, or two and a half times the sample-to-sample jitter, whichever is larger.

The GPU pass runs three times, and the stability figure is the worst loop over the best. For reference, 3DMark’s stress test uses the same form with 97% as its pass mark over 20 loops; three loops is not the same test, so the figure is not a pass or a fail. All three kinds of run are free to run, and every figure any of them measures, the settled level and loop figures included, is in the free report.

What is free and what is paid follows one line: anything measured is free, and anything that explains or prescribes is in the full report. The free report holds every figure with its interval, the score and its parts, the curve with its named shape, what the speed did in plain words, a verdict for each use with the reason for the first, the findings as observed, and the fix plan’s length with its first step. The cause of the curve and what its shape means, the plain-words explanation, the reason behind each later use, every step after the first with how to do it, a prescription for each finding and the retest target are in the full report. Those words are withheld on the server, so a locked report, its export, its PDF, its share card and its emailed link carry none of them.

If the tab goes to the background during the CPU stage, the run pauses: the clock stops, the workers stop, and both resume when the tab returns. The pause is stated on the report, because the machine cooled while it waited.

Every run is a fixed length from launch to report: three minutes, nine, or sixteen and a half. Every stage but path tracing has a set duration, and path tracing runs until the run’s deadline (less the fixed hot re-test on a Deep or Extended run), so time lost earlier shortens it instead of lengthening the run. A run that paused for a background tab ends late by the length of the pause. The screen stage times the interval between animation frames, which the browser paces to the display’s refresh rate: that is compositor delivery to the tab, not a reading of the panel. It reports the rate three ways, the raw median of the intervals, the densest-cluster estimate the motion test uses, and the median snapped to the catalogue panel rate it is within 3% of, and says whether they agree; it reads the colour gamut and HDR support the browser reports, and a gamut the browser does not report is recorded as not reported, never as a narrow panel.

Repeatability

One run is one sample. From the report, the CPU stage can be run again, up to two more times, and the report then shows every run side by side with a spread: the difference between the highest and lowest sustained throughput as a percentage of their mean. Under 3% is reported as tight, under 8% as moderate, and anything above as noisy, with the plain statement that a single run on this machine cannot be read more precisely than that spread.

Run 1 remains the scored run. The repeats start with the machine already warm from the full run, so a second run that comes in lower on a cooling-limited machine is expected, and the report says which case applied: later runs consistently lower is consistent with heat that did not clear between runs, and runs that jump in both directions point at something else competing for the cores. The spread is the honest error bar on everything else on the page, and it is the one figure here that no single measurement can produce.

How repeatable is it

We ran the Standard run ten times back to back on one Intel Core i5-1245U laptop, on mains power, in Chrome on Windows, with 90 seconds of rest between runs. The spread from run to run, as a coefficient of variation: CPU sustained throughput 2.8%, memory bandwidth 14.1%, memory latency 5.8%, the path-traced samples per second 13.2%, and GPU sustained frames per second 21.2%, or 3.9% with one outlying run left out. The overall score varied by 3.4%. The CPU curve’s shape did not repeat: its decay ranged from 0 to 29%, and half the runs read “Shape unclear”, under revision 2026.09.14. Under revision 2026.09.15 the same ten recorded runs read eight of ten as “Plateau, then a step down”, with a boost step that varied far less than the old decay did and a settled decay inside the noise in nine of them. That is one machine, one browser and one power state, and the full table is in our validation notes.

Since revision 2026.09.16 each stage’s headline figure in the full figures table carries a 95% interval in brackets, such as 42.4 M ops/s (41.6 to 43.2). It is the spread within this run: how far the figure would be expected to move if this run’s own windows were drawn again. It is not the spread between runs, nor between machines. Neighbouring windows are not independent (a slow quarter second tends to be followed by another), so the interval comes from a moving-block bootstrap: runs of consecutive windows, about the cube root of their number long and longer when the series is more strongly correlated, never fewer than two, are drawn again 1000 times from a fixed seed, and the middle 95% of the resulting figures is the interval. Where there are too few values for that (the memory latency rounds, the three soft-shadow pairs, three storage passes) the brackets say “range” and give the lowest and highest value measured, which is not a confidence interval. On the ten runs above, each run’s CPU interval was 1.0 to 3.3 M ops/s wide around a sustained figure near 42.4, and only six of the ten contained the ten-run mean. The difference between runs on one machine is larger than the noise inside one run, so to know what a machine does from one run to the next, use the repeat runs described under Repeatability, not the brackets.

Your raw data

The free report has an Export data control. It saves the run as JSON, or the windows alone as CSV, built in the browser from what the page already holds: every CPU and memory window with its time on the stage’s clock, the windows left out and why, the spans without focus, the time hidden and without focus, each stage’s spread, the run-quality notes, the browser, operating system, renderer and isolation state the page could read, and the measurement revision. The GPU stage’s one-second windows carry no time of their own, so they are exported without one rather than with a time we would have to invent. Nothing from the paid half is in the file, and nothing is sent anywhere to make it.

How decay is calculated

Decay is the percentage by which throughput fell from an early window of a run to a closing window of the same run. It is not a comparison against another machine, a specification sheet, or a previous session. For the CPU stage, SystemCheck takes the level the machine settled at, the average from 10 to 20 seconds into the stage, averages the last 20% of the post-warm-up samples less the very last one, and expresses the difference as a percentage of the settled level. The boost before that is a separate figure, the boost step: the best second in the first 10 seconds against the settled level, with the time the boost ended. Many laptops run at a higher speed for a few seconds before settling, and that is not the same thing as losing speed under long work, so it is reported beside decay and not scored. Runs from before revision 2026.09.15 have one decay figure, the first five seconds after the warm-up against the last 20%, which included the boost.

For the GPU stage it compares the frame rate over the first full 10-second camera period after the warm-up against the last full period, so both windows draw the same views. Both figures are noise-gated: a drop smaller than two and a half times the measurement’s own sample-to-sample change reads 0%, with the ungated figure kept alongside. Both are floored at zero: a machine that speeds up over a run reports 0% decay rather than a negative number. A GPU stage too short for two separate camera periods reports that its decay is not matched.

A high decay figure is evidence that the system could not hold its opening output. It is not proof of heat. Power policy, background load, driver behaviour, and browser heuristics all produce the same shape. The bands below are the ones the thermal throttling guide publishes, and they are the only bands this site uses.

Under 8%
Little was given up over the run. Most of what you see is ordinary boost settling, and on the validation laptop the noise gate alone reaches about 7%.
8% to 15%
Common on laptops, small-form-factor builds, and air-cooled desktops under a heavy all-core load.
Above 15%
A large share of the opening output was given up. The figure alone does not say why: the shape of the curve is what points towards power policy, heat or background load.
Above 30%
Worth investigating. Blocked airflow, a failed fan or degraded thermal paste are common causes, and thin laptops with a low sustained power budget can reach it by design.

How the grade is computed

The score is provisional. Its weights and bounds were chosen from the ranges we expect machines to measure, not fitted to a measured population, and they will change once enough runs on real machines exist to fit them. Until then the report prints a Provisional label beside every score, with the kind of run it came from, and the scoring version on every report says which set produced it.

The overall score is a weighted combination of six components measured in this run, each scored from 0 to 100: CPU performance, CPU retention, GPU performance, GPU retention, path tracing, and memory bandwidth. It is not a ranking of product names. The CPU carries the largest share because most work is CPU-bound, and because this site exists to measure what a machine keeps under sustained load; that way a fast graphics card cannot carry a slow processor that gives up its speed to a high score. GPU retention carries least, because a GPU pass of 30 to 50 seconds is too short to heat a graphics cooler through. Memory has counted since revision 2026.09.8, with a small share: bandwidth is what every other stage leans on once its working set leaves the cache, and no more than that, because the figure passes through the browser sandbox and says nothing about capacity.

The four performance components are normalised on a logarithmic curve between a provisional floor, which scores 0, and a provisional ceiling, which scores 100, set wide enough that a software renderer or a phone still scores above zero and the fastest parts we expect have headroom. A logarithmic curve means doubling a figure adds the same number of points wherever you start. The two retention components are 100 minus the decay. The exact weights and bounds are not printed here: they are provisional, they will be refitted, and the scoring version on every report says which set produced it. Every measured figure that goes into the score is printed on the free report and in its export, so the inputs can always be checked.

Standard, Deep and Extended scores use the same CPU window. A Deep run’s CPU stage lasts two and a half minutes and an Extended run’s ten, and decay measured over that length is not the same figure as decay over a minute. So CPU retention is always scored from the first 60 seconds of the stage, by the method described under decay: the settled level from 10 to 20 seconds against the last 20% of that minute, noise-gated. The decay across the whole Deep stage stays on the report as a diagnosis.

GPU retention is not window-matched in the same way: a Standard run scores the decay of its one 50-second pass, and a Deep run the decay of its first 30-second loop. The GPU result does not keep per-second data that would let both be cut to the same 30 seconds, so the two are close but not identical, and GPU retention carries the smallest share. When the GPU frame rate sits at a timer or refresh floor, GPU performance is scored as the lower bound it is and GPU retention is left out of the score rather than credited: a capped frame rate says nothing about the chip holding its output. Retention health is likewise null, not 100, when neither retention component counted.

A component whose stage fell back, did not run, or ran with the tab in the background is left out, and its weight is spread over the components that did measure. The report marks such a score as partial and says how many components counted. A single-core CPU run is not scored for CPU performance, and a CPU stage that paused for a background tab is not scored for retention, because the machine cooled during the pause. GPU results from before revision 2026.09.3 have no fixed-resolution frame rate and are not scored for GPU performance. The memory component counts only when its stage ran fully: a stage that fell back, or paused for a hidden tab, is reported and left out, and a run from before the stage existed is scored on the other five and marked partial.

The grade follows the score, with two limits. A partial run cannot grade above B. Decay of 15% or more caps the grade at B, and 30% or more caps it at C; a machine that gives up 30% or more, in the scored minute or across a Deep stage, is labelled “Slows heavily under load” rather than with any positive word. Every grade word carries “provisional”, because the bands are chosen and not fitted.

S
The top band of the score, all six components measured, and no counted decay of 15% or more. Labelled Excellent (provisional).
A
The second band, all six components measured, and no counted decay of 15% or more. Labelled Strong (provisional).
B
The middle band. Labelled Good (provisional). It is also the highest grade for a partial run, or for a run with 15% to 30% decay.
C
The fourth band. Labelled Modest (provisional). It is the highest grade for a run with 30% decay or more.
D
The lowest band, or nothing in the run measured. Labelled Limited (provisional).

Curve shapes and confidence

The report reads the shape of the CPU curve, and on the unlocked report the GPU curve, and gives it one of the names below with a confidence. A name describes a shape. It is consistent with some causes and not others, and the full report lists the common look-alikes for each, but the shape never proves a cause: that needs a tool that can read the sensors. How a curve is assigned to a shape is SystemCheck’s own work and is not published; the measured windows it reads are in the free report’s export, so anyone can plot the same curve and look at it.

Held
The closing level stays close to the opening plateau, inside the run's own noise.
Plateau, then a step down
A level stretch, then a fall concentrated in one transition, then a lower level.
Gradual slide
A fall spread across the run rather than taken in one step.
Oscillating
The level rises and falls repeatedly rather than settling.
Dipped, then recovered
A fall partway through, then a return to near the opening level.
Erratic
Movement with no consistent direction or rhythm.
Not enough samples
Too few clean windows to read a shape at all.

Every reading carries one of three confidence levels. They depend on how long the series is, how noisy it is against itself, and how clearly the shape stands out from that noise.

High
A long, quiet series whose shape sits well clear of the measurement's own noise.
Moderate
The shape is there, but the series is shorter or noisier, or the shape only just clears the noise. Repeat the run before acting on it.
Low
The report names no shape and no cause, and reads Shape unclear. Too few windows, or a change that the noise could explain.

Conditions that invalidate a figure

Some conditions make a figure mean something other than what it says. The run detects these and acts on them rather than printing the figure as if nothing happened.

  • A hidden tab. Every stage stops its clock while the tab is hidden, because the machine cools while it waits. A stage hidden for more than a second is left out of the score, and the hidden time is printed.
  • A window without focus. Windows and samples that overlap a span without focus are left out of every figure, because the operating system may move an unfocused window’s work to slower cores. The report states the time left out.
  • A fallback. A stage that could not run its real workload (no GPU context, no workers, a lost context, a missing render target) is flagged. Placeholder values never reach the score, and the score is marked partial.
  • A frame rate at a floor. Frame times at the timer’s resolution or at a display refresh interval make the GPU figure a lower bound; its retention is left out of the score and its curve is not classified.
  • A single-core CPU run. If workers cannot start, the kernel runs on the page’s own thread, and the figure is labelled single-core and not scored for CPU performance.
  • A second scene. A GPU stage that fell back to another scene is a different workload, and the report says it is not comparable with runs on the primary.
  • A different revision or backend. Reports from different measurement revisions, or from different GPU backends, are not compared.

Why the resolution is fixed

The GPU raster stage renders at 1600 by 900 and path tracing at 960 by 540, whatever the size of the window and the pixel density of the screen, and the picture is scaled to fit. A frame rate is only comparable between two machines if both drew the same number of pixels: rendering at the window size would give a small laptop screen less work than a large monitor, and a high density display would quietly multiply it. A fixed render target makes the work per frame the same on every screen, so the figure describes the graphics chip rather than the display it is attached to. Changing either resolution is a measurement revision.

What a browser cannot see

In every case below the reason is the same: no browser API exposes the value. This is not a decision about scope or a feature held back for a later release. A web page has no path to the sensors, and any site that prints a temperature from a browser benchmark is estimating it.

Temperature
No browser API exposes any thermal sensor. Not the CPU package, not the GPU die, not the VRM, not ambient.
Power draw
Package power, board power, and voltage are unavailable to a web page. There is no equivalent of a hardware monitoring rail in the browser sandbox.
VRAM
Neither WebGL2 nor WebGPU reports installed or allocated video memory. The frame-time class the GPU stage records (called a VRAM badge before revision 2026.09.7) is a load label derived only from median frame time, and it is not a memory reading.
Clock speeds
No API returns the current or boost frequency of any core. Throughput is measured directly instead, which is the thing the clock was a proxy for.
Fan RPM
Fan controllers sit behind the embedded controller and the operating system. Nothing about them reaches a browser tab.
Battery health
The Battery Status API exposes charge level and charging state only. Design capacity, full-charge capacity, wear, and cycle count are not exposed, so SystemCheck reports charge drawn across the run and nothing more.
Throttle flags
The processor records why it lowered its clock (a power limit, a temperature limit, a current limit), and the operating system can read those reasons. A page cannot. That is why a curve shape is described as consistent with a cause and never named as one.
Drive health
SMART data, wear level, error counts and power-on hours belong to the drive and the operating system. The browser's private file store sits behind both, so the storage test measures the browser's file path, not the drive.
Drivers and firmware
The browser reports a renderer string and nothing about the driver version, its date or the firmware. A driver change can move a result by more than a hardware difference, and the run cannot see it.

The one hardware identifier a browser does expose is the GPU renderer string, read through the WebGL debug renderer extension. SystemCheck cleans it by unwrapping the ANGLE prefix and stripping device identifiers, graphics API tokens, and shader model suffixes, then checks it for software renderer signatures such as SwiftShader and llvmpipe. That string is what the vendor and browser chose to report. It is a label, not a probe.

The free companion scripts on the device test page read some of what the browser cannot, on Windows and macOS: battery design and full charge capacity, wear and cycle count, drive health and SMART status where the system exposes it, the graphics driver version and date, memory modules, firmware and the power plan. They are plain-text scripts you can read before running, and the file they write is read in your browser and never uploaded. For clocks, package power, fan speed, temperature over time and throttle reasons during a run, use a hardware monitor alongside the run.

What SystemCheck v1 does not measure at all

The Standard, Deep and Extended runs do not touch storage or the network. Storage has a standalone test, described above: it writes and reads a 64 MiB file in the browser’s private file store and reports sequential write, sequential read and 4 KiB random reads, with a sustained-write mode that looks for a cache cliff. It measures the browser’s file path behind the operating system’s cache, not the drive itself, and it reads no SMART data. The network is measured only by the separate internet test in the device lab, never by the run. Memory is measured for bandwidth and dependent-load latency only: there is no capacity reading, no error test, and no check of the modules themselves. If you arrived here after running what you thought of as a PC stress test, it is reasonable to assume your drive was exercised and your RAM was tested for faults. Neither happened. A healthy grade here is not evidence that a failing drive or a faulty memory module is fine.

There is no crowd baseline. A completed run is stored on our server as its measured figures, the processor you picked and the graphics string the browser reported, with no address and nothing that identifies you, so that a calibration set can be built and a percentile can one day be honest; today SystemCheck still compares your run against nobody.

The only baseline is your own earlier run: the last five reports are kept in your browser, on this device, and when you run the same processor again the report shows the two side by side, curve over curve, with the change per figure. A change inside the run-to-run spread is reported as no change. Your address is attached to a stored run only when you ask for an emailed link or buy an unlock.

Measurement revision

Every report is stamped with the measurement revision that produced it, the scoring version, and the GPU backend the run used. The current stamp reads measurement identity 2026.09.18, forensic scoring v3, with the backend named alongside it. That stamp exists because a score is only meaningful inside the revision that generated it. Change a stage duration, a sample gate, a normalisation bound, or a weighting, and every previous number shifts underneath you even though both are printed as plain figures out of 100.

So two reports from different revisions are not directly comparable, and neither are two reports from different GPU backends at the same revision. Before comparing any two runs, check that the revision line matches and the backend matches. If either differs, the comparison is directional at best and should be described that way.

Fallbacks and partial runs

Each stage has a safety path so a failure cannot leave you on a frozen screen. Those paths matter to you, because two of them substitute fixed placeholder values for measurements, and one of them reaches the score.

Stage 4 fallback

If floating-point render targets are unavailable, if the WebGL context is lost, if no sample arrives within 6 seconds of starting, or if the stage runs eight seconds past its length, the tracer is replaced by a pre-rendered video, every figure shown while it plays is labelled an example and not a measurement, and the result carries no figures: zero samples per second and a null consistency (before revision 2026.09.7 it carried invented placeholders, 6.8 samples per second and a consistency of 90 or 100). The report prints “not measured” in the path-tracing row. It is flagged, and scoring refuses to trust it: path tracing is left out of the score, the score is marked partial, and the grade cannot go above B. So a fallback Stage 4 cannot inflate your score.

Stage 3 fallback

If the scene cannot obtain a GPU context, if assets fail to load, if no progress tick arrives within 6 seconds, if the stage exceeds its 50 second backstop, or if the stage throws and the error boundary recovers it, Stage 3 shows a video with every figure labelled an example, not a measurement, and substitutes a fixed result: 16.7ms average frame time, 96% stability, and 6% decay. That result carries a fallback flag, and scoring refuses to trust it: both GPU components are left out, the score is marked partial and cannot grade above B, and the GPU cannot be named as the weakest link.

A fallback Stage 3 therefore cannot inflate your score, and the report prints “not measured” for its frame rate. If Stage 3 showed a video rather than a rotating lit model, or if you saw a recovery screen, repeat the run.

Stage 2 fallback

If Web Workers cannot be created, if a 24 MiB or 64 MiB allocation fails, or if the latency walk never reports, the memory stage ends with a result flagged as not measured. Nothing is substituted: the report prints “not measured” for every memory figure and the memory section says the stage could not complete. The memory component is left out of the score, its weight is spread over the other five, and the score is marked partial; no other figure on the report changes.

Skips, aborts, and partial runs

Skipping Stage 4 at the prompt records no path-tracing result at all, so path tracing is left out of the score and the run is graded as partial. Aborting any stage discards every partial result from that run rather than carrying half a session into a summary, because the score compares the stages against each other. If Stage 1 cannot create Web Workers it runs the same kernel single-threaded on the main thread, which produces an honest but much lower figure; the report labels it single-core and lists it under run quality.

Confounders we cannot control

Everything in this section moves your result without appearing anywhere in it. None of it is detectable from inside a browser tab. Publishing these first is the only honest way to hand you a number and ask you to act on it.

Browser thermal and power heuristics

Browsers reduce timer resolution, rendering rate, and background work under their own pressure signals, and those signals are neither documented nor readable from the page. A drop measured in the closing seconds may be the browser managing itself rather than the silicon backing off. Nothing in the run can distinguish the two. Treat a single run as a description of the whole stack, browser included.

Background-tab throttling

If the tab loses focus, requestAnimationFrame stops and timers are clamped. Every stage pauses rather than measure that: the CPU stage stops its clock and its workers, and the GPU and path-tracing stages stop their clocks, until the tab returns. The hidden time is reported, because the machine cooled while it waited, and a stage hidden for more than a second is left out of the score. Keep the tab in the foreground for the whole run.

Operating system scheduling

The scheduler decides which of your cores the workers land on, whether they get performance or efficiency cores, and how often they are preempted. Hybrid CPUs are especially sensitive: an identical machine can post a materially different sustained figure depending on where the workers were placed. Repeat the run and compare the spread rather than trusting one number.

Other load on the machine

Game launchers, update services, browser extensions, hardware monitoring tools, and other open tabs all compete for the same cores and the same GPU. This depresses throughput and can look like a cooling problem. SystemCheck detects it on the CPU: every worker times its own batches of work, and a batch several times slower than the fastest is the thread being paused by the operating system for something else. A run that loses 3% or more of its working time that way is flagged in the report. Quiet runs measured 0.2 to 0.5%, and a four-thread foreign load 14.7%. Pauses shorter than the browser's timer resolution (1 ms in Firefox and Safari) and load on the GPU alone are not seen, so close everything you can before a run you intend to keep.

Battery versus mains power

On battery, most laptops apply a lower sustained power limit, a lower boost ceiling, and a more aggressive fan curve, and Windows power plans do the same on mains. SystemCheck records charging state and charge drawn, so you can see which case applied, but it cannot read the power policy itself. A battery run and a mains run on one machine are two different measurements.

Thread and isolation limits

The CPU stage creates one Web Worker per logical processor reported by the browser, clamped to a maximum of 32. That figure is itself a browser estimate and some browsers deliberately round it down for fingerprinting reasons. SystemCheck does not use WebAssembly or SharedArrayBuffer, and the site does not send COOP and COEP headers, so cross-origin isolation is unavailable and none of the shared-memory threading paths apply. If worker creation is blocked outright, by a strict content security policy or a hardened browser, the stage silently falls back to running the same kernel single-threaded on the main thread. The number that produces is genuine, but it is a single-core figure, and the report labels it as one and lists it under run quality.

Driver and browser version

The JavaScript engine, the ANGLE translation layer, and the GPU driver all change between releases, and each of them can move a result by more than the hardware difference you are trying to see. A 15% gap between two browsers on one machine is entirely possible and says nothing about the hardware. Record your browser and driver version alongside any baseline you intend to compare against later. The before and after comparison records the browser family and how the GPU was timed, and it does not judge a change between runs in different browsers, or GPU figures timed by different methods. Once a machine has at least three earlier comparable runs in this browser, a figure far outside their usual spread is listed under run quality, worked out on the device from the runs it remembers.

Thermal state at the start of the run

A machine that has been idle for an hour starts cold and has more headroom to lose, which raises measured decay. A machine that has just finished a game starts hot and may show almost no decay because it had already given up its headroom before the run began. This is the single largest source of run-to-run disagreement, and it is invisible in the output. Standardise your starting state, then compare runs that began the same way.

The practical consequence of the list above is that a single run is a sample, not a verdict. Run the test three times from a consistent starting state, keep the tab in front, and compare the spread. If three runs agree closely, the number describes your machine. If they do not, the disagreement is itself the finding, and it usually points at background load or a starting thermal state rather than at the hardware.

Corrections policy

Methodology changes get versioned, dated, and disclosed. Any change that alters what a stage runs, how long it runs, what is sampled, how decay is derived, or how the stages are weighted increments the measurement revision, and every report generated afterwards carries the new stamp. Reports generated before a change keep the revision they were produced under, so a saved report stays interpretable in the terms that created it, and this page will continue to describe how superseded revisions worked rather than quietly rewriting history.

If a figure published here turns out to be wrong, the correction gets written into this page and dated, not deleted. If a defect is found in a stage, the defect gets described alongside which revisions it affected and what it did to the score. This policy is written now, while nothing is in dispute, because a corrections policy published after the first disputed number is not worth reading.

Revision 2026.09.18, October 2026

A correction to how long path tracing runs. Every stage pauses while its tab is hidden, but the run’s end was fixed by the clock at launch, so time spent in another tab came out of path tracing, which could shrink to its 20-second minimum. The run now counts the time the tab was hidden before path tracing and moves its end later by that much, so path tracing gets the length it would otherwise have had. When path tracing still runs at its minimum, because earlier stages overran, the report says so. No figure is worked out differently by this change, and path-tracing figures compare across this revision.

In the same revision the CPU stage stopped playing a fire video behind the measurement and shows a still frame instead. Decoding video uses the processor the stage is measuring. Measured on one laptop in Chrome, in three pairs of runs with and without the video, the video cost about 5 to 6% of the sustained CPU figure and about 10% of the peak, and every run without it read higher than every run with it. Machines without hardware AV1 decode were not measured, so the cost on other machines is unknown and may differ either way. The overall score differed in only one of the three pairs. CPU figures and the score are not compared across this revision. Three pairs on one machine make the size indicative, not exact.

Revision 2026.09.17, October 2026

A correction to the CPU stage. Its kernel was JavaScript that asked the browser for each sine and cosine, so its speed was partly the speed of the browser’s own JavaScript engine: the same processor read differently in two browsers, and could move with a browser update. The kernel is now WebAssembly and does the same work for each counted operation, a square root, a sine and a cosine, with the sine and cosine computed by the kernel itself. Durations, windows, warm-up, decay and the curve are unchanged. The operations per second are on a new scale, so CPU figures and the score are not compared across this revision. Where a browser cannot run WebAssembly the stage uses the old kernel, the report says so, and those CPU figures are not compared with WebAssembly runs. Measured side by side on one laptop in one browser, the CPU figure now reads several times higher on the same machine, because the work no longer waits on the browser’s own maths functions. The score’s CPU scale moved with it, so the same machine scores much the same on either kernel, but the figures themselves are not comparable across the change. That scale is provisional until it is confirmed on a desktop and in a second browser.

Revision 2026.09.16, October 2026

Each stage’s headline figure now carries the spread inside its run: a 95% interval from a moving-block bootstrap over the windows the figure was taken from, or the lowest and highest value where there are too few values for one. No figure changed, and reports from either side of this revision are compared as before. The interval is narrower than the difference between runs on the same machine, and the page above says so.

Revision 2026.09.15, October 2026

Two corrections to the CPU stage. First, a laptop that runs at full boost for a few seconds and then drops in one move to a level it holds is now named as a plateau and a step down. Before, a boost that short could fall just outside what the classifier accepted as a plateau, and the flat line after it was then read as a slide, as erratic or as unclear more or less by chance: ten runs of one laptop gave six different names, and now eight of the ten give the same one. Second, CPU decay is now measured from the level the machine settled at after its boost, and the boost is reported as its own figure, the boost step, with the time it ended. The old figure compared the first seconds with the end, and on a machine whose boost ended inside those first seconds it moved with exactly when the boost ended; on the same laptop it read anywhere from 0 to 29%. The settled decay is what CPU retention is scored from and what the decay bands read, so a machine that boosts briefly and then holds steady scores higher on CPU retention than it did. Reports from before this revision keep their single decay figure and are not compared with reports from after it.

Revision 2026.09.14, October 2026

Focus loss is now left out of the two stages revision 2026.09.13 did not cover. The memory stage records the spans without focus on the same clock as its quarter-second bandwidth windows, and every window that overlaps one is left out of the single-stream and six-stream figures and their spread, as a hidden window was; the report states the time and the windows left out. The soft shadow stage leaves out each one-second window that overlaps a span without focus, inside its segment, and a segment that loses more than half its windows takes its whole pair of segments out of the cost. The order is soft, hard, hard, soft, soft, hard, and each pair holds one segment of each mode next to each other in time, so dropping a whole pair keeps the two modes balanced; dropping single windows from one mode would not. The remaining pairs give the cost and its spread, and with no complete pair the cost reads not measured. A run that kept its focus reads exactly as before. The standalone sustained write, which is not part of the run, now asks the browser to keep the site’s storage as persistent when the visitor presses Start, never on load, then sizes the write from the browser’s estimate after that request, and the result says whether storage was persistent. Reports from before this revision are not compared with reports from after it.

Revision 2026.09.13, October 2026

Five method corrections. First, the curve classes describe a shape and what it is consistent with, not a cause: a browser cannot tell a power limit expiring from a window that lost focus and had its work moved to efficiency cores, a switch from mains to battery, or a background scan, and the full report now lists those look-alikes for each class. Second, the window’s blur and focus are recorded on each stage’s own clock, and every CPU window, GPU window and path tracing sample that overlaps a span without focus is left out of every figure, as hidden time was; the report states the time left out. Third, the GPU raster and soft shadow stages read a pixel back once every N frames after warm-up, N chosen so a sync lands about every 100 ms at the warm-up rate and never fewer than 4, and divide each batch’s time by its frame count. Reading back after every frame measured the round trip through the browser’s GPU process as much as the GPU, so the scored frame rate rises on fast chips; the per-frame figure is kept as the per-frame round trip, for information. Interleaved on the validation laptop on mains, three pairs, the old method held the stage at 58 to 63 frames a second sustained, the display’s refresh, while the chip’s own time per frame was 4 to 5 ms; the new one read 132 to 253, in line with the chip. GPU raster figures from before this revision measured the refresh on machines like it and are not compared with figures from after. A discrete GPU has not yet been measured. Fourth, each stage with windows reports the coefficient of variation of those windows, its spread inside one run. Fifth, an Extended run: the Deep run with a ten-minute CPU stage; the curve reader was adjusted so a long stage is read at the same resolution as a short one, which leaves 60 and 150 second runs reading exactly as before. Reports from before this revision are not compared with reports from after it.

Revision 2026.09.12, October 2026

The soft shadow stage, standalone and as stage 6 of the Deep run, runs a 6-second warm-up and six 9-second segments in the same order, 60 seconds in all, where it ran a 3-second warm-up and six 10-second segments; the camera period follows the segment. Its scene is drawn in the site’s light theme, a light ground and sky and accent pillars, by changing colours only: the background is the frame’s clear rather than a drawn pass, and the passes, the shadow map, the samples, the light, the geometry, the camera path and the resolution are unchanged. Interleaved on the validation laptop on mains, four pairs, the hard-shadow rate did not move (41.1 against 40.9 frames a second sustained) but the soft-shadow rate read about 10% lower in this revision (21.1 against 18.8) and the cost a few points higher. Colour costs no pass, and a build with the light scene on the old schedule confirmed it: the new schedule alone read about 10% lower on the soft-shadow rate and 7% on the hard one, likely because a 9-second segment spends more of its time just after a change of mode. The responsiveness test, which is not part of the run, now measures 10 seconds idle before its 30 seconds under load. Reports from before this revision are not compared with reports from after it.

Revision 2026.09.11, September 2026

The tool’s floor holds still while a stage measures. The board of tiles behind every screen of the tool lights tiles in the accent one after another, and until this revision it kept doing so under the stages, out of sight behind them. Each lit tile repaints a large tilted layer every frame, and that work competes with whatever the stage is timing. Interleaved on the validation laptop, with the old animation forced back on for half the runs: path tracing read 21 samples a second with the floor moving against 32 with it still, while the graphics chip’s time per sample barely moved (10.0 against 9.6 ms), so the floor took time between samples rather than cost within them; the GPU raster stage scored 38 to 40 frames a second against 50 to 53, and its sustained rate 30 against 46. The same check found the same cost under the standalone WebGPU compute test, which also lost its own animated picture: its picture is now drawn from the measurement’s ticks, never on a clock of its own. No stage’s work changed. The graphics figures of every earlier revision were held down by this on a chip of this kind, by about a third for path tracing and a quarter for GPU raster, and reports from before this revision are not compared with reports from after it.

Revision 2026.09.10, September 2026

Every pixel of a path tracing sample does the same work. Until this revision each march in the shader stopped at its first hit, so a pixel of sky and a pixel on the ball cost different amounts and the cost of a frame followed what the camera saw as the ball rolled through the course. On an integrated chip whose clock chases its load that made the per-sample figure wander: four runs of one build on the validation laptop read 7.6, 6.7, 7.2 and 6.0 ms of GPU time per sample, a quarter apart, with within-run consistency of 0, 1, 0 and 26. Now the primary march, the reflection march, the shadow cone and the occlusion probe each run a fixed count on every pixel: a ray that has hit stands still for its remaining steps with the distance field still evaluated, and a sky pixel shades the far point of its ray and keeps the sky. So that the picture survives a short fixed march, the floor plane is met by arithmetic instead of stepped toward, the hit tolerance grows with distance (under half a pixel at any range), and no step crosses a pillar cell. The counts were matched to the early-exit shader’s mean cost by interleaved A/B on the same machine, recorded in the validation notes, so samples per second keeps its scale; but a frame’s cost is now level across the course, and reports across the revision are not compared. The scene, its materials and the display pass are unchanged. What the change did not do, on that laptop: the run-to-run spread did not narrow in the same session, and both builds fell together as the machine cooled, so on an integrated chip the larger part of the wander is the clock following temperature and other load, not frame content. The figure is now one fixed amount of work per pixel, which it was not before.

Revision 2026.09.9, September 2026

The GPU stage’s curve is classified. The stage now records its frame rate in each one-second window after warm-up, and the report reads that series with the same bins, noise gates and classes as the CPU curve: held, a plateau then a step, a gradual slide, oscillating, dipped and recovered, erratic, or too short. A Standard run reads its 50-second pass; a Deep run reads its first 30-second loop, the loop GPU retention is scored over, and with fewer windows its reading is rarely better than moderate confidence. A frame rate sitting at a display-refresh or timer floor is not classified, because the curve is then the floor’s. The GPU shape, its cause and the two curves read together are part of the unlocked report; the free half is unchanged. Separately, the CPU stage records each thread’s rate per window and the report states the spread between threads, the coefficient of variation of the threads’ mean rates, as information only. Processors with performance and efficiency cores widen that figure by design, so no verdict is drawn from it until it has been measured across such machines. No stage runs anything different and no score moved.

Revision 2026.09.8, September 2026

The memory stage is scored. Its six-stream bandwidth is a sixth component of the score, normalised on the same logarithmic curve as the others between provisional bounds, and counted only when the stage ran fully. The five earlier weights were scaled down by the same factor to make room; their ratios to one another are unchanged. Memory latency and scaling stay reported and not scored, because both depend on the JavaScript engine as much as on the memory. No stage changed what it runs or how, but a score is a different combination from here on, so reports across the revision are not compared.

Revision 2026.09.7, September 2026

A batch of corrections from the test audit. What a stage measures changed in six places, so reports across the revision are not compared. The path tracing scene is stepped by elapsed time rather than by sample count, so every machine traces the same course over the same seconds; the per-sample cost is the same work per frame, but the frame set differs from the old one on any chip not near 60 samples per second, and an A/B against the old scene has not yet been run on a GPU. The soft-shadow segments run in ABBA order so warming cancels, and the cost carries a spread instead of the word exact. The Deep hot re-test is a fixed 30 seconds that starts the instant path tracing ends, with path tracing absorbing the run’s slack, and it is called matched inside the run’s own noise gate rather than a flat 1%. The memory stage stops its clock while the tab is hidden and drops windows that overlap the hidden time, and the globe behind it holds still while the phases measure. The screen stage records the raw median and the densest-cluster estimate beside the snapped rate. GPU retention at a timer or refresh floor is left out of the score instead of credited with 100, and retention health is null when neither retention component counted.

Corrections to copy in the same revision, none of which changed a measurement. The run-quality note about GPU timing said Firefox read lower because its frames were timed by reading a pixel back; every browser is timed that way, and a timer query only adds a GPU-side figure, so the note now says that. The path tracing stage was described as a Monte Carlo path tracer; it is a raymarched scene with one reflection bounce, cone-traced shadows and ambient occlusion, and the stage keeps its name with that said plainly. The soft-shadow module described itself as not part of the main run; it is stage six of the Deep run. The live CPU tile multiplied iterations by an assumed 68 operations each; it shows counted iterations. The responsiveness tile had no source and is gone. The GPU load label was called VRAM; it is a frame-time class. The video that stands in for a GPU stage that cannot run showed canned figures as if measured; they are labelled examples. The proxy that stands in for a path tracer that cannot run reported a consistency of 90; it reports null. The memory reading named modules and channels a browser cannot see; it says how the bandwidth scales and names no hardware. The combined stage runs one thread fewer than the solo stage, which the copy did not say; the comparison is now per thread and says so, and the GPU hold is shown as measured rather than clamped at 100. Six different decay cut-offs across four modules are one set (8, 15 and 30 percent), and the noise gate constant is one exported value. The validation notes claimed two 60-second hot runs where the code ran one. The run-mode source cited a document that did not exist.

Revision 2026.09.6, September 2026

The path tracing light of the scene is now exact within each frame: cone-traced soft shadows and ambient occlusion replace one random light sample per frame, so a frame is clean on its own and the picture no longer depends on averaging. The work per frame is the same order; reports across the revision are not compared.

Revision 2026.09.5, September 2026

Each path tracing sample now stands alone with its depth, and frames are combined by reprojection in the untimed display pass rather than by a running mean inside the accumulation pass. A sample does one texture read fewer and is otherwise the same work; the figure keeps its scale.

Revision 2026.09.4, September 2026

The path tracing scene changed from a still scene of two spheres to a chrome ball rolling through a course of pillars and gates, advancing one step per sample, with a running mean over the last few samples in place of accumulation over the whole stage. The per-sample cost of the new scene was matched to the old one on the same machine before it shipped, measured in alternating blocks, so the samples-per-second scale and the score derived from it hold; the scene is nonetheless a different workload, and reports across the revision are not compared.

Revision 2026.09.3 and scoring v3, September 2026

The GPU raster stage now renders at a fixed 1600 by 900 with every frame timed to GPU completion, and reports frames per second at that resolution. Before it, the stage reported a raster index derived from an adaptive supersampling factor, which could read ten to fifty times higher than the pixels actually drawn. Path tracing now runs under continuous load at a fixed 960 by 540; before it, the tracer was paced to about 150 samples, so the GPU sat idle between samples. Both GPU stages now pause with a hidden tab, the combined stage leaves a core free for the render loop, and CPU decay is noise-gated.

Scoring v3 replaced v2 at the same time. Under v2 the score was mostly GPU and path tracing: CPU speed added little, and its floor sat above what most machines sustain, so it added nothing on most of them. Decay was measured over the whole CPU stage, so a Deep run and a Standard run of one machine were not comparable, and a grade of B was labelled Solid even at 40% decay. Scores from v2 and v3 are not comparable, and neither are revisions before 2026.09.3.

Limits and interpretation