One file.
Two machines.
A real measurement.
BitStream is a point-to-point network performance tester that lives entirely in one HTML file. Open it on both ends of a link, press start, and measure throughput, latency, jitter and packet loss over the actual path — with nothing installed on either machine.
- No install
- No server
- No dependencies
- No telemetry in the tool
- MIT licensed
How it works
Three steps, no infrastructure in between.
Traffic moves over a WebRTC data channel — SCTP over DTLS over UDP — directly between the two machines. On the same subnet there is no relay and no proxy in the path, so the bytes genuinely cross the link you are testing.
Open the same file on both machines
Double-clicking it is enough — file:// is a secure context, which is all
WebRTC needs. One machine becomes the server, the other the client. The server is started
first, matching the habit from iperf.
Carry two codes between them
The server generates a session code; the client answers with a reply code. Each is a compressed, checksummed blob you paste across — no signalling server, no account, no internet connection required. Both codes show a checksum so you can confirm the paste landed intact.
Check the link, then load it
A latency baseline runs first, reported the way ping reports it —
min, average, max and mean deviation, plus percentiles and the browser's own ICE
round-trip time. Then the big green button loads the path.
What it measures
Six numbers, each computed honestly.
Throughput
Application-layer goodput, measured at the receiving end rather than claimed by the sender. Reported per second and as an overall mean.
Latency
Round trips over the control channel as min / avg / max / mdev and p50, p95, p99, cross-checked against the browser's ICE connectivity-check RTT.
Jitter
RFC 3550 smoothed mean deviation of transit time. It works on the variation, so the unknown clock offset between two machines cancels out — no clock sync needed.
Packet loss
Counted against the sender's own message total, shipped over the control channel. The receiver cannot otherwise know how many messages were meant to arrive.
Reordering & duplication
Exact over a 65,536-packet window, using sequence numbers rather than sampling. Visible only in unreliable mode — the reliable channel repairs both by design.
Payload integrity
Received bytes verified against the exact bit pattern that was transmitted, so silent corruption surfaces instead of quietly inflating the throughput figure.
Controls
Set the variables that actually change the answer.
Transport mode, direction, duration, offered rate, message size, bit pattern and integrity checking. The client sets them and they apply to both ends automatically.
Two settings people get wrong
Fix the rate if you care about loss or jitter. At unlimited rate you are deliberately overrunning the path, so the loss figure tells you how far past capacity you pushed — not what the path's loss characteristics are. A token-bucket pacer holds whatever rate you set.
Bit patterns matter on links that compress. All-zeros will sail through a compressing link at a flattering rate. Use PRBS-31 or random for a fair measurement — or use the compressible patterns deliberately, when compression is exactly what you are trying to detect.
Limits
What it will not pretend to do.
Browsers have no access to raw sockets. Rather than approximate these and quietly mislead you, BitStream leaves them out — and says so in the interface and in every exported report.
-
Traceroute
Needs ICMP and TTL control. Not possible in a browser, and not
approximable. Use
tracerouteormtr. - ICMP ping The latency figures are application-layer round trips and carry a little browser scheduling overhead. Treat them as an upper bound.
- Port selection ICE chooses ephemeral UDP ports. You cannot pin the test to a specific port.
- QoS / DSCP marking Not exposed for data channels in any portable way.
- Path MTU discovery The size control sets an application message size, not the IP MTU. Larger messages are fragmented by SCTP.
And the one that matters most: the browser is often the bottleneck
A data channel costs CPU — SCTP framing, DTLS encryption and JavaScript overhead all sit between you and the wire. On a fast link that cost, rather than the link, is usually what you hit. BitStream watches for it: it compares the achieved rate against the offered rate, tracks event-loop delay, and counts how often the transmit buffer filled. When the sender could not keep the channel fed, the result is labelled sender-limited in the interface and at the top of the report — a floor on the path's capacity, not a measurement of it.
Output
A report you can paste into a ticket.
Every run exports to Markdown with ISO-8601 timestamps and the local UTC offset, the full configuration, both machines' user agents, the negotiated candidate pair, per-second interval tables, the browser's own counters as a cross-check, and a complete event log. Warnings sit at the top, ahead of the numbers they qualify.
Verification
It tests itself, in one tab.
A tool that needs two machines to be useful should still be checkable on one. Append a query string and the same file runs its own suites — no second machine, no network.
# packet and signalling codecs, sequence accounting, report fixture
bitstream.html?selftest=1
# 71 assertions driving both peers in one page over real data channels,
# across reliable, unreliable, rate-limited and bidirectional runs
bitstream.html?loopback=1
The page title becomes PASS or FAIL, so both suites can be driven headlessly in CI.
Measure the link, not the tooling.
One file, downloaded twice. That is the whole setup.
- Chromium, Firefox and Safari
- Works fully offline
- MIT licensed