speedtest-go
This is a fork of showwin/speedtest-go that has been updated to use the latest Go version and dependencies.
The project includes both a CLI and a public API that enables internet speed testing using speedtest.net.
CLI
Installation
Linux, Windows, etc
Please download the compatible package from GitHub Releases.
Building Distribution Packages
Linux distribution packages (.deb, .rpm, .apk, Arch Linux) can be built locally using nFPM via the Makefile.
Prerequisites
Install nFPM before running these targets.
See the nFPM installation docs for all options, or use one of:
brew install goreleaser/tap/nfpm
go install github.com/goreleaser/nfpm/v2/cmd/nfpm@latest
echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | sudo tee /etc/apt/sources.list.d/goreleaser.list
sudo apt update
sudo apt install nfpm
Run using the Makefile
# Build a specific package format
make nfpm-deb # Debian/Ubuntu (.deb)
make nfpm-rpm # Fedora/RHEL (.rpm)
make nfpm-apk # Alpine (.apk)
make nfpm-arch # Arch Linux (.pkg.tar.zst)
# Build all package formats at once
make nfpm-all
Packages are output to the dist/ directory. The VERSION variable defaults to dev and must be set to a valid semver (e.g. 1.7.10) before building:
VERSION=1.7.10 make nfpm-all
Signed release versions of packages are also built and published to GitHub Releases.
Docker Build
To build a multi-architecture Docker image:
# Check if you already have a builder instance
docker buildx ls
# Only create a new builder if you don't have one
# If the above command shows no builders or none are in use, run:
docker buildx create --name mybuilder --use
# Build and push for multiple platforms
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t nickfedor/speedtest-go:latest --push .
Running the Container
Docker
Run the container with default settings (interactive shell):
docker run -it nickfedor/speedtest-go:latest
Run a speedtest with specific arguments:
# Run a basic speedtest
docker run nickfedor/speedtest-go:latest speedtest-go
# Run with specific server
docker run nickfedor/speedtest-go:latest speedtest-go --server 6691
# Run with multiple servers and JSON output
docker run nickfedor/speedtest-go:latest speedtest-go --server 6691 --server 6087 --json
# Run with custom location
docker run nickfedor/speedtest-go:latest speedtest-go --location=60,-110
Kubernetes
Here's an example Kubernetes pod specification that runs a speedtest:
apiVersion: v1
kind: Pod
metadata:
name: speedtest
spec:
containers:
- name: speedtest
image: nickfedor/speedtest-go:latest
# Base command to run bash
command: ["speedtest-go"]
# Or run with specific arguments
# args: ["--server", "6691", "--json"]
restartPolicy: Never
For a more complete deployment, you might want to use a CronJob to run periodic speedtests:
apiVersion: batch/v1
kind: CronJob
metadata:
name: speedtest
spec:
schedule: "0 */6 * * *" # Run every 6 hours
jobTemplate:
spec:
template:
spec:
containers:
- name: speedtest
image: nickfedor/speedtest-go:latest
command: ["speedtest-go"]
args: ["--json"]
restartPolicy: OnFailure
Usage
speedtest-go --help
A command-line tool to test internet download and upload speeds using speedtest.net servers.
Usage:
speedtest-go [flags]
speedtest-go [command]
Available Commands:
cities List predefined city labels
completion Generate the autocompletion script for the specified shell
help Help about any command
list List available speedtest servers
version Print version information
Flags:
--config string config file (default is $HOME/.speedtest-go.yaml)
--custom-url string Specify the url of the server instead of fetching from speedtest.net.
--debug Enable debug mode.
--dns-bind-source DNS request binding source (experimental).
-h, --help help for speedtest-go
--json Output results in json format.
--jsonl Output results in jsonl format (one json object per line).
-m, --multi Enable multi-server mode.
--no-download Disable download test.
--no-upload Disable upload test.
--ping-mode string Select a method for Ping (support icmp/tcp/http). (default "http")
--proxy string Set a proxy(http[s] or socks) for the speedtest.
--saving-mode Test with few resources, though low accuracy (especially > 30Mbps).
-s, --server ints Select server id to run speedtest.
--source string Bind a source interface for the speedtest.
-t, --thread int Set the number of concurrent connections.
--ua string Set the user-agent header for the speedtest.
-u, --unit string Set human-readable and auto-scaled rate units for output (options: decimal-bits/decimal-bytes/binary-bits/binary-bytes).
--unix Output results in unix like format.
Use "speedtest-go [command] --help" for more information about a command.
Version
speedtest-go version
# speedtest-go v1.8.0 (1559e47, 2026-05-02) go1.26.5 linux/amd64
Test Internet Speed
Simply use speedtest-go command. The closest server is selected by default. Use the -m flag to enable multi-measurement mode (recommended)
## unix like format output
# speedtest-go --unix
speedtest-go
speedtest-go v1.8.0 (1559e47, 2026-05-02)
✓ ISP: 124.27.199.165 (Fujitsu) [34.9769, 138.3831]
✓ Found 20 Public Servers
✓ Test Server: [6691] 9.03km Shizuoka (Japan) by sudosan
✓ Latency: 4.452963ms Jitter: 41.271µs Min: 4.395179ms Max: 4.517576ms
✓ Packet Loss Analyzer: Running in background (<= 30 Secs)
✓ Download: 115.52 Mbps (Used: 135.75MB) (Latency: 4ms Jitter: 0ms Min: 4ms Max: 4ms)
✓ Upload: 4.02 Mbps (Used: 6.85MB) (Latency: 4ms Jitter: 1ms Min: 3ms Max: 8ms)
✓ Packet Loss: 8.82% (Sent: 217/Dup: 0/Max: 237)
Test with Other Servers
If you want to select other servers to test, you can see the available server list.
$ speedtest-go list
Testing From IP: 124.27.199.165 (Fujitsu) [34.9769, 138.3831]
[6691] 9.03km 32.3365ms Shizuoka (Japan) by sudosan
[6087] 120.55km 51.7453ms Fussa-shi (Japan) by Allied Telesis Capital Corporation
[6508] 125.44km 54.6683ms Yokohama (Japan) by at2wn
[6424] 148.23km 61.4724ms Tokyo (Japan) by Cordeos Corp.
...
and select them by id.
$ speedtest-go --server 6691 --server 6087
speedtest-go v1.8.0 (1559e47, 2026-05-02)
✓ ISP: 124.27.199.165 (Fujitsu) [34.9769, 138.3831]
✓ Found 2 Specified Public Server(s)
✓ Test Server: [6691] 9.03km Shizuoka (Japan) by sudosan
✓ Latency: 21.424ms Jitter: 1.644ms Min: 19.142ms Max: 23.926ms
✓ Packet Loss Analyzer: Running in background (<= 30 Sec)
✓ Download: 65.82Mbps (Used: 75.48MB) (Latency: 22ms Jitter: 2ms Min: 17ms Max: 24ms)
✓ Upload: 27.00Mbps (Used: 36.33MB) (Latency: 23ms Jitter: 2ms Min: 18ms Max: 25ms)
✓ Packet Loss: 0.00% (Sent: 321/Dup: 0/Max: 320)
✓ Test Server: [6087] 120.55km Fussa-shi (Japan) by Allied Telesis Capital Corporation
✓ Latency: 38.694699ms Jitter: 2.724ms Min: 36.443ms Max: 39.953ms
✓ Packet Loss Analyzer: Running in background (<= 30 Sec)
✓ Download: 72.24Mbps (Used: 83.72MB) (Latency: 37ms Jitter: 3ms Min: 36ms Max: 40ms)
✓ Upload: 29.56Mbps (Used: 47.64MB) (Latency: 38ms Jitter: 3ms Min: 37ms Max: 41ms)
✓ Packet Loss: 0.00% (Sent: 343/Dup: 0/Max: 342)
Test with a virtual location
You can test speed from a virtual location by first listing servers in a specific city or coordinates, then selecting server IDs to test against.
$ speedtest-go cities
Available city labels (case insensitive):
CC CityLabel Location
(za) capetown [-33.9391993, 18.4316716]
(pl) warsaw [52.2396659, 21.0129345]
(sg) yishun [1.4230218, 103.8404728]
...
$ speedtest-go list --city=capetown
$ speedtest-go --server <server_id_from_list>
# Or with coordinates
$ speedtest-go list --location=60,-110
$ speedtest-go --server <server_id_from_list>
Memory Saving Mode
With --saving-mode option, it can be executed even in an insufficient memory environment like IoT devices.
The memory usage can be reduced to 1/10, about 10MB of memory is used.
However, please be careful that the accuracy is particularly low, especially in an environment of 30 Mbps or higher.
To get more accurate results, run multiple times and average.
For more details, please see saving mode experimental result.
⚠️This feature has been deprecated > v1.4.0, because speedtest-go can always run with less than 10MBytes of memory now. Even so, --saving-mode is still a good way to reduce computation.
Go API
go get github.com/nicholas-fedor/speedtest-go
API Usage
The code below finds the closest available speedtest server and tests the latency, download, and upload speeds.
package main
import (
"fmt"
"github.com/nicholas-fedor/speedtest-go/speedtest"
)
func main() {
var speedtestClient = speedtest.New()
// Use a proxy for the speedtest. eg: socks://127.0.0.1:7890
// speedtest.WithUserConfig(&speedtest.UserConfig{Proxy: "socks://127.0.0.1:7890"})(speedtestClient)
// Select a network card as the data interface.
// speedtest.WithUserConfig(&speedtest.UserConfig{Source: "192.168.1.101"})(speedtestClient)
// Get user's network information
// user, _ := speedtestClient.FetchUserInfo()
// Get a list of servers near a specified location
// user.SetLocationByCity("Tokyo")
// user.SetLocation("Osaka", 34.6952, 135.5006)
// Search server using serverID.
// eg: fetch server with ID 28910.
// speedtest.ErrServerNotFound will be returned if the server cannot be found.
// server, err := speedtest.FetchServerByID("28910")
serverList, _ := speedtestClient.FetchServers()
targets, _ := serverList.FindServer([]int{})
for _, s := range targets {
// Please make sure your host can access this test server,
// otherwise you will get an error.
// It is recommended to replace a server at this time
s.PingTest(nil)
s.DownloadTest()
s.UploadTest()
// Note: The unit of s.DLSpeed, s.ULSpeed is bytes per second, this is a float64.
fmt.Printf("Latency: %s, Download: %s, Upload: %s\n", s.Latency, s.DLSpeed, s.ULSpeed)
s.Context.Reset() // reset counter
}
}
The code will find the closest available speedtest server and analyze packet loss.
package main
import (
"fmt"
"github.com/nicholas-fedor/speedtest-go/speedtest"
"github.com/nicholas-fedor/speedtest-go/speedtest/transport"
"log"
)
func checkError(err error) {
if err != nil {
log.Fatal(err)
}
}
// Note: The current packet loss analyzer does not support udp over http.
// This means we cannot get packet loss through a proxy.
func main() {
// Retrieve available servers
var speedtestClient = speedtest.New()
serverList, _ := speedtestClient.FetchServers()
targets, _ := serverList.FindServer([]int{})
// Create a packet loss analyzer, use default options
analyzer := speedtest.NewPacketLossAnalyzer(nil)
// Perform packet loss analysis on all available servers
for _, server := range targets {
err := analyzer.Run(server.Host, func(packetLoss *transport.PLoss) {
fmt.Println(packetLoss, server.Host, server.Name)
// fmt.Println(packetLoss.Loss())
})
checkError(err)
}
// or test all at the same time.
packetLoss, err := analyzer.RunMulti(targets.Hosts())
checkError(err)
fmt.Println(packetLoss)
}
Summary of Experimental Results
Speedtest-go is a great tool because of the following five reasons:
- Cross-platform available.
- Low memory environment.
- We are the first FULL-FEATURED open source speed testing project based on speedtest.net, including down/up rates, jitter and packet loss, etc.
- Testing time is the SHORTEST compare to speedtest.net and sivel/speedtest-cli, especially about 2x faster than speedtest.net.
- Result is MORE CLOSE to speedtest.net than speedtest-cli.
The following data is summarized. If you got interested, please see more details.
Download (Mbps)
distance = distance to testing server
- 0 - 1000(km) ≒ domestic
- 1000 - 8000(km) ≒ same region
- 8000 - 20000(km) ≒ really far!
- 20000km is half of the circumference of our planet.
| distance (km) |
speedtest.net |
speedtest-go |
speedtest-cli |
| 0 - 1000 |
92.12 |
91.21 |
70.27 |
| 1000 - 8000 |
66.45 |
65.51 |
56.56 |
| 8000 - 20000 |
11.84 |
9.43 |
11.87 |
Upload (Mbps)
| distance (km) |
speedtest.net |
speedtest-go |
speedtest-cli |
| 0 - 1000 |
65.56 |
47.58 |
36.16 |
| 1000 - 8000 |
58.02 |
54.74 |
26.78 |
| 8000 - 20000 |
5.20 |
8.32 |
2.58 |
Testing Time (sec)
| distance (km) |
speedtest.net |
speedtest-go |
speedtest-cli |
| 0 - 1000 |
45.03 |
22.84 |
24.46 |
| 1000 - 8000 |
44.89 |
24.45 |
28.52 |
| 8000 - 20000 |
49.64 |
34.08 |
41.26 |
Contributors
See Contributors, PRs are welcome!
Issues
You can find or report issues in the Issue Tracker.
LICENSE
MIT