Skip to content

Ivyson/speed-test

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

speedcli

I built this to monitor my team's own servers, four of them spread across the country. When a server goes down or starts throttling, running this CLI tells us which one and how bad it is.

I didn't want to use someone else's speed test app. Most of them run on TypeScript or Node.js, which means pulling in thousands of npm packages or shipping telemetry we can't audit. With Rust, every dependency is frozen in Cargo.lock, and the final product is a single executable with no runtime. It either runs or it doesn't, and nothing changes under your feet unless you rebuild it deliberately.

It still relies on Netflix's Fast.com infrastructure. I scrape fast.com, extract a token from the page's JavaScript, and hit their internal API (api.fast.com/netflix/speedtest/v2) for target server URLs and location data. If Fast.com changes their frontend, the token extraction breaks, and the tool needs an update.

This isn't designed for anybody else. It's for me and the people managing these servers with me. If it's useful to you too, great, but it's not packaged for distribution.

How the test works

Once the targets are retrieved, the CLI opens N parallel connections (set with -w, defaults to 3) and starts pulling data. Every second it measures how many bytes moved in that interval (not a cumulative average from the start), converts to Mbps, and checks whether the reading has settled. If the last few readings are within 10% of each other, it stops early instead of running the full duration (configurable via --max-duration, defaults to 8 seconds). Same process for uploads, except it sends 5 MB chunks in each POST.

If no worker manages to complete a single request after three attempts each, the test aborts early instead of spinning until the duration timer expires. On a dead network this drops the wait from 8 seconds to about 3.

The terminal output is kept simple on purpose. No progress bars, no TUI spinners. Terminal rendering competes with the async runtime for CPU, and on a short speed test every cycle matters. A flickering progress bar can subtly nudge the results. These run on servers anyway -- no one needs pretty output on the servers. The colored text is just to match my terminal rendering.

Retry behaviour

If the network is down during setup or either test phase, the tool shows a red progress bar and retries up to N times (set with --max-retries, defaults to 3). After that it gives up and exits with an error. No more infinite spinning or silent 0.0 Mbps results.

Caching

The token and server list are cached to ~/.cache/speedcli/targets.json and reused for about 50 minutes. Subsequent runs start testing almost immediately instead of initiating another TCP handshake. Use --clear-cache to force a fresh fetch.

Usage

speedcli -h
Usage: speedcli [OPTIONS]

Options:
  -w, --workers <WORKERS>            The number of workers/threads to use to benchmark your speed (Should not be more than 5).
      --clear-cache                  A boolean value to clear the cache used by speedcli
      --max-duration <MAX_DURATION>  Maximum duration in seconds for each test phase [default: 8]
      --max-retries <MAX_RETRIES>    Maximum retries per test phase before giving up [default: 3]
      --json                         Output results as JSON for machine parsing
      --download-only                Run only the download test
      --upload-only                  Run only the upload test
  -h, --help                         Print help
  -V, --version                      Print version

Output:

{
  country : ZA,
  approximated_city : Pretoria,
  public_ip : 192.7.8.12, # realistically, it will show your public IP and not Private,  this is just for demo
  connected_servers : 3
}

Benchmarking Your internet speed..

Download: 142.3 Mbps
Upload: 45.1 Mbps

With --json:

{
  "download": 142.3,
  "upload": 45.1,
  "country": "ZA",
  "city": "Pretoria",
  "public_ip": "192.7.8.12",
  "connected_servers": 3
}

What's next

The interval-based speed readings fixed the false 0.0 Mbps upload bug that appeared when using many workers on a congested server. The next step is to make the chunk size tuneable. On very fast connections, 5 MB chunks mean fewer round-trips per second, which can under-report the true speed. A dynamic chunk size that adapts mid-test should give better accuracy without adding complexity on the user's side.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages