How to Self-Host a Speed Test with LibreSpeed (Test Your Own Network, Not the Internet)

Speedtest.net measures your broadband. It can't tell you why Jellyfin stutters in the bedroom, whether the new mesh node helped, or what the VPN costs you. LibreSpeed is the same test — download, upload, ping, jitter — served from your own server, so any phone or laptop measures its link to the server. Slow result on the sofa and fast one next to the router: it's the Wi-Fi, not the ISP.
Quick reference
| Task | What |
|---|---|
| Folder | ~/docker/librespeed/compose.yaml |
| Web | http://server-ip:8089 |
| What it measures | the link between that device and the server |
| Keep results | TELEMETRY: "true" + a password for the stats page |
| Command-line numbers | iperf3 -s on the server, iperf3 -c server-ip on a client |
| Broadband itself | speedtest-exporter into Grafana (tutorial 90) |
1. The container
mkdir -p ~/docker/librespeed && cd ~/docker/librespeed
nano compose.yaml
services:
librespeed:
image: lscr.io/linuxserver/librespeed:latest
container_name: librespeed
ports:
- "8089:80"
environment:
PUID: 1000
PGID: 1000
TZ: Europe/London
TELEMETRY: "true"
PASSWORD: ${STATS_PASSWORD}
TITLE: "Home speed test"
volumes:
- ./config:/config
restart: unless-stopped
docker compose up -d
sudo ufw allow from 192.168.1.0/24 to any port 8089
Open http://192.168.1.50:8089 on any device and press Start.
2. Reading it
- Download / Upload: throughput between this device and the server. On gigabit Ethernet expect 900+ Mbps; good Wi-Fi 6 near the router 500–800; a far corner on 2.4 GHz, 30–60. The server's own NIC and disk aren't the limit at these numbers.
- Ping: round trip. Under 2 ms wired, 3–10 ms on Wi-Fi. Spikes mean interference or a congested access point.
- Jitter: variation in ping. High jitter is what makes video calls stutter even when bandwidth looks fine.
Walk the house with a phone running the test and you have a coverage map in five minutes.
3. Keep results
With TELEMETRY on, every run is stored; http://192.168.1.50:8089/results/stats.php with the password lists them with device, time and numbers. Test each room, change something (channel, node placement), test again, compare.
4. Over the VPN
Run it from outside through WireGuard or Tailscale and you measure the tunnel's real throughput — usually your home upload speed, which is the honest answer to "why is Jellyfin slow at Mum's".
5. iperf3 for raw numbers
For a precise wired or Wi-Fi figure without a browser:
sudo apt install iperf3 -y # on the server and the client
iperf3 -s # server
iperf3 -c 192.168.1.50 -t 20 # client: 20-second test
iperf3 -c 192.168.1.50 -R # reverse direction
iperf3 -c 192.168.1.50 -u -b 100M # UDP at 100 Mbps: shows loss and jitter
Windows and Android have iperf3 builds too. It's the standard tool for proving a cable or a switch port is bad (tutorial 117).
6. The broadband itself
For the ISP side, run speedtest-exporter and graph it in Grafana (tutorial 90) — a test every hour, for a month, is the evidence an ISP complaint needs.
Troubleshooting
Results far below the link speed on a wired PC. A gigabit NIC negotiating at 100 Mb/s (ethtool enp3s0 | grep Speed), a bad cable, or an old switch.
The server's CPU spikes during a test. Normal on a Pi; the test is CPU-bound there and may under-report. Use iperf3 on a Pi.
Stats page empty. TELEMETRY not set at first start; recreate the container.
Phone shows half the speed of a laptop in the same spot. Phones have smaller antennas and often fewer streams. That's real, and it's what the phone will get.
Wrapping up
One container, a bookmark on every device, a walk round the house. You find out exactly where the Wi-Fi gives up, what the VPN delivers, and whether that new access point earned its money — with the ISP out of the picture entirely.
