Speedtest Tracker

Tracks internet connection speed over time on a dashboard

Monitoring & Status ★ 6k stars Easy setup MIT

Speedtest Tracker runs periodic internet speed tests and records download, upload, and ping results on a dashboard so you can spot connection degradation. It supports notifications when speeds drop below thresholds.

Key features

  • Scheduled speed tests
  • Historical charts
  • Threshold notifications
  • Multiple test servers

Pros & cons

Strengths

  • Documents ISP performance
  • Easy Docker setup

Trade-offs

  • Single-purpose tool
  • Test variability

Speedtest Tracker replaces

Last reviewed Sep 13, 2026 · 806 words

Schedule Speedtest Tracker once an hour, pin it to one test server, and run it from a wired host. Skip any of those three and the chart you eventually show your ISP will be noise they can dismiss in one sentence. Get them right and you have a year of timestamped download, upload, and latency figures that turn "the internet feels slow in the evenings" into a graph with a 40 percent dip between 19:00 and 23:00, which is a very different conversation to have with support.

Every 60 minutes, not every 5

The temptation is to test constantly. Resist it. Each run moves several hundred megabytes through the connection, so a 5-minute schedule eats bandwidth you might be paying for, competes with whatever else is on the line, and produces results that swing with your own household traffic rather than the ISP's capacity. Hourly, or every 30 minutes if you are actively documenting a fault, gives 24 to 48 points a day, which is enough to see a daily pattern in a week and a degradation trend in a month. The schedule is a cron expression in the container environment, and offsetting it from the top of the hour (minute 6 rather than minute 0) avoids colliding with every other cron job on the network.

The compose file, including the step everyone misses

services:
  speedtest-tracker:
    image: lscr.io/linuxserver/speedtest-tracker:latest
    ports:
      - "8080:80"
    environment:
      - PUID=1000
      - PGID=1000
      - APP_KEY=base64:REPLACE-WITH-GENERATED-KEY
      - APP_URL=http://192.168.1.10:8080
      - DB_CONNECTION=sqlite
      - SPEEDTEST_SCHEDULE=6 * * * *
      - SPEEDTEST_SERVERS=12345
    volumes:
      - ./config:/config
    restart: unless-stopped

APP_KEY is the Laravel application key, and the container will not start without a valid one. Generate it with echo -n 'base64:'; openssl rand -base64 32 and paste the result as one string. The default login is [email protected] with password password; change both on first sign-in. SQLite is fine for a single-household install; the PostgreSQL and MySQL options exist for people who want to point Grafana at the data, and there is a built-in InfluxDB export for the same purpose.

Pin a server or the chart is noise

Left to itself, the Ookla client that runs under the hood picks the nearest server each time, and "nearest" changes with routing. Two different servers 40 km apart can differ by 100 Mbps on a gigabit line simply because of their own load. List available servers with speedtest -L from inside the container, or use the ID shown in the dashboard's results, and fix SPEEDTEST_SERVERS to one or two well-provisioned ones. Consistency matters more than peak numbers here: a slightly lower but stable figure is the baseline you want, because a baseline is what a degradation is measured against.

Alerts that catch a slow week, not a slow hour

Threshold notifications fire when download, upload, or ping crosses a value you set, and they can go to Discord, Telegram, ntfy, Gotify, email, or a generic webhook. Set the threshold at about 70 percent of the speed you pay for rather than 95 percent, because single-test variance of 10 to 20 percent is normal even on a healthy line, and an alert that fires daily gets muted within a week. The useful pattern is a loose per-test alert plus a monthly glance at the chart, which is where the real story lives. If you already run Uptime Kuma for reachability, the two complement each other well: one tells you the line is up, the other tells you what it is worth.

What the graph cannot tell you

A speed test measures the path from this host to that server. If the container runs on a laptop over Wi-Fi, you are measuring your access point. Run it on a wired box, ideally the one closest to the router. It also cannot separate ISP throttling from a saturated test server, an overloaded home router, or your own backups running at 02:00, which is another argument for the hourly cadence and a fixed server. For LAN throughput, which is a different question, LibreSpeed self-hosts the test server end so both sides are yours. The homelab monitoring post covers where this tool sits among the rest.

What I'd do

One container on a wired always-on host, hourly at minute 6, one pinned server, SQLite, and an ntfy alert at 70 percent of the advertised speed. Leave it for 3 months before drawing conclusions. When the evening dip shows up on the chart, and on most residential lines it does, export the CSV and attach it to the support ticket. That export is the whole reason to run this instead of visiting Speedtest.net by hand.

Compare Speedtest Tracker

1 head-to-head comparisons.

Similar monitoring & status apps