Browser-side background removal benchmarks
Koutuxia's free background removal downloads the BiRefNet_lite model into the visitor's browser and runs it there, so images are not uploaded to our server. The trade-off is that speed is decided entirely by that machine: whether WebGPU is available, whether WASM can use several threads, and how large the image is all change the result. So this page gives a distribution rather than a single number — measured on devices in actual use and split by execution backend and device class, not a marketing figure from one fast machine.
Telemetry from real devices
Last 90 days, 17 samples, most recent 2026-09-08.
Combinations with fewer than 30 samples are still listed, greyed out — hiding them would leave readers unable to tell "no data here" from "we dropped this one".
| Phase | Backend | Device | CPU cores | Samples | p50 | p95 | of which inference p50 |
|---|---|---|---|---|---|---|---|
| Model first download | wasm-st | Mobile | 8-11 | 1(too few samples) | 68.15 s | 68.15 s | — |
| Model first download | webgpu | Mobile | 8-11 | 1(too few samples) | 15.64 s | 15.64 s | — |
| Model cache hit | wasm | Mobile | 8-11 | 1(too few samples) | 478 ms | 478 ms | — |
| Model cache hit | wasm-st | Mobile | 8-11 | 1(too few samples) | 294 ms | 294 ms | — |
| Model cache hit | webgpu | Desktop | 4-7 | 1(too few samples) | 354 ms | 354 ms | — |
| Model cache hit | webgpu | Mobile | 8-11 | 1(too few samples) | 198 ms | 198 ms | — |
| Runtime load | wasm | Mobile | 8-11 | 1(too few samples) | 17.88 s | 17.88 s | — |
| Runtime load | wasm-st | Mobile | 8-11 | 2(too few samples) | 5.75 s | 5.85 s | — |
| Runtime load | webgpu | Desktop | 4-7 | 1(too few samples) | 9.67 s | 9.67 s | — |
| Runtime load | webgpu | Mobile | 8-11 | 2(too few samples) | 24.29 s | 33.96 s | — |
| First cutout | wasm-st | Mobile | 8-11 | 2(too few samples) | 44.06 s | 44.86 s | 43.32 s |
| First cutout | webgpu | Desktop | 4-7 | 1(too few samples) | 13.28 s | 13.28 s | 12.87 s |
| First cutout | webgpu | Mobile | 8-11 | 2(too few samples) | 12.16 s | 12.30 s | 11.41 s |
Baseline (fixed sample set, measured)
Baseline measurement pending: this column has to come from a real run on a named machine, so until that run happens it stays empty rather than holding an estimate.
Sample set
模型固定 768²/512² 输入,耗时随解码与前处理的像素量走、与画面内容无关;合成图把分辨率这一个变量固定住,且任何人都能用仓内脚本生成同样的字节。
自制合成图(CC0)。不含人像,不含任何第三方素材。 · scripts/benchmarks/make-samples.mjs
- s1: 640×480 (0.31 MP)
- s2: 1280×960 (1.23 MP)
- s3: 1920×1440 (2.76 MP)
- s4: 3000×2000 (6 MP)
- s5: 4032×3024 (12.19 MP)
Method and limits
- ·The timers live in src/lib/matting/birefnet-local.js, on the same code path a real cutout takes — there is no separate benchmark mode, so what is measured is what happens after a user presses the button.
- ·Model first download covers the fetch through local gunzip. What crosses the network is 39 MiB of gzip, decompressed locally to 47 MiB, so that row reflects the visitor's network as much as their hardware. Model cache hit is the time to read it back from the Cache API on a later visit.
- ·Runtime load is the ONNX Runtime session creation, including graph optimisation and moving weights into GPU or system memory. When WebGPU session creation fails and the engine falls back to WASM, the failed attempt is not counted — only the one that ends up serving the user.
- ·First and later cutouts are reported separately: the first one also pays for WebGPU pipeline compilation and first-kernel JIT, which is a different thing from the steady state. Collapsing them into one figure misleads both kinds of reader — someone cutting a single image reads it as too fast, someone cutting ten in a row reads it as too slow. "Of which inference" is the session.run segment alone; the remainder is decode, preprocessing and compositing, which scale with image resolution.
- ·p50 and p95 are computed over the raw samples in the window, not by averaging daily percentiles — an average of percentiles carries no statistical meaning.
- ·Samples are self-reported by visitor browsers, with no authentication and no de-duplication: one person cutting ten images contributes ten rows. This page measures the distribution of "how long one cutout takes", not how many people use the tool, and readers should know that limit.
- ·Timing does not depend on image content: the model takes a fixed 768² (WebGPU) or 512² (WASM / low-memory devices) input, and every image is resized to it first. What varies with resolution is decode and preprocessing, not the inference itself.
- ·Device attributes are bucketed in the browser before they are sent (8 cores becomes "8-11"), and the raw values never leave it. So this table can separate orders of magnitude, not specific machine models.
How this page's data is collected
Telemetry sends timing numbers and coarse device buckets only: desktop or mobile, a CPU-core bucket, a memory bucket, an input-resolution bucket, the execution backend, and the model version. It does not send images, any feature derived from an image, filenames, the raw User-Agent, the referrer, or an IP address, and it carries no cookies — there is no field in a sample that points at a person. The privacy policy has the full description.
Privacy policy →Reading telemetry setting…
Download the raw summary
Both formats carry the same content, including the greyed-out rows. Licensed CC BY 4.0; please cite the source and the date you pulled it.