Code Monkey home page Code Monkey logo

speedtest-go's Introduction

speedtest-go

Full-featured Command Line Interface and pure Go API to Test Internet Speed using speedtest.net.

You can speedtest 2x faster than speedtest.net with almost the same result. See the experimental results. Inspired by sivel/speedtest-cli

CLI

Installation

macOS (homebrew)

$ brew tap showwin/speedtest
$ brew install speedtest

### How to Update ###
$ brew update
$ brew upgrade speedtest

Nix (package manager)

# Enter the latest speedtest-go environment
$ nix-shell -p speedtest-go

Other Platforms (Linux, Windows, etc.)

Please download the compatible package from Releases. If there are no compatible packages you want, please let me know on Issue Tracker.

Usage

$ speedtest --help
usage: speedtest-go [<flags>]

Flags:
      --help                   Show context-sensitive help (also try --help-long and --help-man).
  -l, --list                   Show available speedtest.net servers.
  -s, --server=SERVER ...      Select server id to speedtest.
      --custom-url=CUSTOM-URL  Specify the url of the server instead of fetching from speedtest.net.
      --saving-mode            Test with few resources, though low accuracy (especially > 30Mbps).
      --json                   Output results in json format.
      --unix                   Output results in unix like format.
      --location=LOCATION      Change the location with a precise coordinate (format: lat,lon).
      --city=CITY              Change the location with a predefined city label.
      --city-list              List all predefined city labels.
      --proxy=PROXY            Set a proxy(http[s] or socks) for the speedtest.
                               eg: --proxy=socks://10.20.0.101:7890
                               eg: --proxy=http://10.20.0.101:7890
      --source=SOURCE          Bind a source interface for the speedtest.
      --dns-bind-source        DNS request binding source (experimental).
                               eg: --source=10.20.0.101
  -m  --multi                  Enable multi-server mode.
  -t  --thread=THREAD          Set the number of concurrent connections.
      --search=SEARCH          Fuzzy search servers by a keyword.
      --ua                     Set the user-agent header for the speedtest.
      --no-download            Disable download test.
      --no-upload              Disable upload test.
      --ping-mode              Select a method for Ping (support icmp/tcp/http).
  -u  --unit                   Set human-readable and auto-scaled rate units for output 
                               (options: decimal-bits/decimal-bytes/binary-bits/binary-bytes).
  -d  --debug                  Enable debug mode.
      --version                Show application version.

Test Internet Speed

Simply use speedtest command. The closest server is selected by default. Use the -m flag to enable multi-measurement mode (recommended)

## unix like format output
# speedtest --unix
$ speedtest

    speedtest-go v1.7.8 @showwin

✓ 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 --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 --server 6691 --server 6087

    speedtest-go v1.7.8 @showwin

✓ 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

With --city or --location option, the closest servers of the location will be picked. You can measure the speed between your location and the target location.

$ speedtest --city-list
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 --city=capetown
$ speedtest --location=60,-110

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/showwin/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/showwin/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/showwin/speedtest-go/speedtest"
	"github.com/showwin/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

speedtest-go's People

Contributors

3mard avatar aareet avatar bluemanos avatar cbergoon avatar cgb avatar d1823 avatar danielealbano avatar drewstinnett avatar eric avatar euantorano avatar juev avatar kevynhuang avatar kogai avatar mikaelpeltier avatar mr-linch avatar ovaldi avatar pig98 avatar r3inbowari avatar redradrat avatar rilysh avatar rtrox avatar showwin avatar spiritlhls avatar suzuki-shunsuke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

speedtest-go's Issues

BUG: Import of this package will destroy logging

A simple import of the speedtest package will destroy logging of a parent applications as the following code shows...

package main

import (
        "log"
        _ "github.com/showwin/speedtest-go/speedtest"
)

func main() {
        log.Fatalln("This will never be shown!")
}

Running this code will NOT produce any output while removing the import of "github.com/showwin/speedtest-go/speedtest" will bring back logging. I was able to trace down the issue to line 174 of speedtest.go which globally sets the logging target to io.discard thus unexpectedly discarding ALL logging messages of the application. Furthermore, the wrapping New() function is called in line 193 of the same file on import.

Please remove the call to log.SetOutput(io.Discard) as this has sever side-effects to applications using your package, e.g. Telegraf.

The result of download and upload will be globally accumulating when every running

I test three server one by one, and here is result.

Start testing ServerID 18445...
Test ServerID 18445 is done
Latency: 7.112067ms, Download: 524.6603Mbps, Upload: 233.5331Mbps

Start testing ServerID 18447...
Test ServerID 18447 is done
Latency: 7.420043ms, Download: 1051.1059Mbps, Upload: 442.0036Mbps

Start testing ServerID 18452...
Test ServerID 18452 is done
Latency: 6.62287ms, Download: 1571.7269Mbps, Upload: 573.5561Mbps

As you can see the download and upload is accumulating, even I new client by speedtest.New() everytime.
Here is the code I ran.

package main

import (
	"context"
	"fmt"
	"os"
	"sync"
	"time"

	"github.com/showwin/speedtest-go/speedtest"
)

func speedtestAndCollectInfomation(s *speedtest.Server) error {

	fmt.Printf("Start testing ServerID %v...\n", s.ID)

	ctx, cancel := context.WithTimeout(context.Background(), time.Duration(60)*time.Second)
	defer cancel()

	if err := s.PingTestContext(ctx, nil); err != nil {
		return err
	} //end if

	if err := s.DownloadTestContext(ctx); err != nil {
		return err
	} //end if

	if err := s.UploadTestContext(ctx); err != nil {
		return err
	} //end if

	fmt.Printf("Test ServerID %v is done\n", s.ID)
	return nil
} //end speedtestAndCollectInfomation

func main() {

	serverIDs := []string{"18445", "18447", "18452"}
	for _, serverID := range serverIDs {

		wg := new(sync.WaitGroup)
		wg.Add(1)

		go func() {

			ctx, cancel := context.WithTimeout(context.Background(), time.Duration(10)*time.Second)
			defer cancel()
			defer wg.Done()

			speedtestClient := speedtest.New()
			s, err := speedtestClient.FetchServerByIDContext(ctx, serverID)
			if err != nil {
				fmt.Fprintf(os.Stderr, "%v\n", err)
				cancel()
				os.Exit(1)
			} //end if

			if err := speedtestAndCollectInfomation(s); err != nil {
				fmt.Fprintf(os.Stderr, "%v\n", err)
				cancel()
				os.Exit(1)
			} //end if

			fmt.Printf("Latency: %.2fms, Download: %.2fMbps, Upload: %.2fMbps\n\n", float64(s.Latency)/float64(time.Millisecond), s.DLSpeed, s.ULSpeed)
		}() //end go
		wg.Wait()
	} //end for
} //end main

The solution I found is call speedtest.GlobalDataManager = speedtest.NewDataManager() before new client.

func getSpeedtestClient() *speedtest.Speedtest {
	speedtest.GlobalDataManager = speedtest.NewDataManager()
	return speedtest.New()
} //end getSpeedtestClient

Like this, and the result is correct.

Start testing ServerID 18445...
Test ServerID 18445 is done
Latency: 7.37ms, Download: 504.11Mbps, Upload: 234.08Mbps

Start testing ServerID 18447...
Test ServerID 18447 is done
Latency: 6.91ms, Download: 511.65Mbps, Upload: 226.65Mbps

Start testing ServerID 18452...
Test ServerID 18452 is done
Latency: 6.43ms, Download: 515.23Mbps, Upload: 222.37Mbps

Is any other API I missed or it has a better solution?

Failed to fetch user info

I tried to used internet_speed plugin of telegraf and it failed with the following error:

2022-11-09T15:03:00Z E! [inputs.internet_speed] Error in plugin: fetching user info failed: EOF

The error comes from the FetchUserInfoContext method of the speedtest-go project.

I wonder if the problem is not related to the fact that the user-agent of the http request is not initialized.

The output of the official speedtest.net cli contains Packet Loss, is there a corresponding output for this project?


    😊 speedtest-go v1.6.0 @showwin 😊

✓ ISP: 114.116.111.1 (China Unicom) [34.7732, 113.722] 
✓ Found 20 Public Servers

✓ Test Server: [25858] 619.03km Beijing (China) by China Mobile Group Beijing Co.Ltd
✓ Latency: 4.46569ms Jitter: 73.696µs Min: 4.388614ms Max: 4.622087ms
✓ Download: 81.04Mbps (used: 96.61MB)
✓ Upload: 1.53Mbps (used: 1.83MB)

   Speedtest by Ookla

      Server: Unicom - Shenyang (id: 37235)
         ISP: Interserver
Idle Latency:   261.66 ms   (jitter: 0.28ms, low: 261.54ms, high: 262.36ms)
    Download:     7.87 Mbps (data used: 12.5 MB)                                                   
                383.41 ms   (jitter: 80.58ms, low: 255.74ms, high: 511.24ms)
      Upload:     3.24 Mbps (data used: 4.4 MB)                                                   
                431.47 ms   (jitter: 84.31ms, low: 263.31ms, high: 1440.69ms)
 Packet Loss:     0.0%
  Result URL: https://www.speedtest.net/result/c/f3e06f53-918b-4172-9d35-f77a08a0251e

The output of the official speedtest.net cli contains Packet Loss, is there a corresponding output for this project?

Request to add support for s390x architecture

Request to add support for s390x architecture

I was surprised to find out that the CLI introduction of speedtest.net does not support the s390x architecture when I built the shell automation speed test script.

Upload way off

Seems like the upload speed is way off (underlaying crash?). Server 7812 works fine. Can I help and debug?

Target Server: [5917] 21.17km Landskrona (Sweden) by Bredbandsson AB
Latency: 7.126748ms
Download Test: ................
Upload Test: ................

Download: 81.60 Mbit/s
Upload: 1928.76 Mbit/s

As per the resp, the `name` seems acutally `city`

Rename 'NAme' to 'City'?

type Server struct {
	URL      string        `xml:"url,attr" json:"url"`
	Lat      string        `xml:"lat,attr" json:"lat"`
	Lon      string        `xml:"lon,attr" json:"lon"`
	Name     string        `xml:"name,attr" json:"name"`
	Country  string        `xml:"country,attr" json:"country"`
	Sponsor  string        `xml:"sponsor,attr" json:"sponsor"`
	ID       string        `xml:"id,attr" json:"id"`
	URL2     string        `xml:"url2,attr" json:"url_2"`
	Host     string        `xml:"host,attr" json:"host"`
	Distance float64       `json:"distance"`
	Latency  time.Duration `json:"latency"`
	DLSpeed  float64       `json:"dl_speed"`
	ULSpeed  float64       `json:"ul_speed"`
}

Is there a possiblity for this tool to work with https://github.com/miquels/speedtest

I have been using https://github.com/miquels/speedtest in production for at-least 2-3 years now and it works great in web browsers.
However for speeds above 500 Mbps some clients browsers are not able to cope with the speed.
I have tested with your tool and it seem to work better for these clients then the browser.

I want to test it against the local speedtest server only and it uses port 4000 or 40001 with tls.
The speed test server is at:
https://speed.rimon.net.il/

and is publicly available.

--json flag is not working

It went wrong when I appended the --json flag either in ubuntu20.04 or win10.
My speedtest-go version is 1.1.2.

Complain about lack of lpthread/glibc on Openwrt 19.07.5 x86_64

Openwrt uses musl as its C library.
Download from release package→ fail to run.
Go API(openwrt golang 1.13 package along with gcc)→error due to "lack of -lpthread".
Manually sideload sgerrand/alpine-pkg-glibc (alpine linux also use musl c, so it theoretically works ) →works normally.

ADD --world option

speedtest to following 6 locations. (need to find stable server for each location)

  • Frankfurt (Germany)
  • Tokyo (Japan)
  • Sao Paulo (Brazil)
  • California (West USA)
  • (around) Oregon (East USA)
  • somewhere (Australia)

--no-upload not supported?

I installed today on a Mac.
speedtest --help doesnt show "no-upload" option
and, calling speedtest with --no-upload gets an error

--no-upload would be very useful. Will it be supported?

compare to speedtest.net and speedtest-cli, to prove speedtest-go is the BEST

have to prove

  • speedtest-go is more accurate than speedtest-cli (based on the result of speedtest.net)
  • get results faster than speedtest-cli and speedtest.net

like below:

location speedtest.net speedtest-go speedtest-cli
0km - 1000km (≒domestic) 25Mbps / 20sec 25 Mbps / 10sec 20Mbps / 30sec
1000km - 5000km (≒same continent) 50Mbps / 20sec 49 Mbps / 10sec 30Mbps / 30sec
5000km - 10000km (faraway) 50Mbps / 20sec 49 Mbps / 10sec 30Mbps / 30sec
10000km - 20000km (far enough away) 50Mbps / 20sec 49 Mbps / 10sec 30Mbps / 30sec

memo

the best number of connestions

speedtest.net says if speed is less than 4 Mbps, 2 connections is better. But in my try, 4 connections is better than 2 clearly.

number of connections first try (download) second try (download) first try (upload) second try (upload)
4 connections 2.99 Mbit/s 3.55 Mbit/s 3.47 Mbit/s 2.37 Mbit/s
2 connections 0.88 Mbit/s 1.32 Mbit/s 1.42 Mbit/s 1.48 Mbit/s

The testing methods can cause the program to Exit(1)

Hey,

I've noticed that many of the helper functions for testing methods such as {Upload,Download,Ping}Test call checkError(err). This function Exit(1)s the program if err is not nil.

I am using this library in a long running program and currently, a number of conditions out of the scope of the library and my program (e.g. network connectivity, DNS availability, even misbehaving speedtest servers) may cause the library to terminate my program.

Are you open to discussing a pull request which changes this behavour?

Use in commercial projects

I have a question regarding the use of this library. Since, this lib use speedtest.net's non-public API to get the list of servers, I am wondering if it will ethical or legal to use this in a commercial product?

Add cross compilation target/release for MIPS

Hi, I'm trying to use this tool from my dd-wrt box, which runs MIPS. I'm going to try and cross compile it and will submit a PR if I get it to work successfully, but it would be nice to have a MIPS release!

Latency discrepancy with real / Ookla's tool levering "bad" target server election

Hi,

Comparing Ookla's tool and speedtest-go, due to the latency calculation mismatches for the target server, we get a significant difference in the up/down results. For a given client and at nearly the same time, many rounds were run to test it, and the Ooklas's target election always brings better results (close to the real 1Gbps in this example). That still ignores another issue referred to below and that seems not solved.

support@host:~$ speedtest --selection-details

   Speedtest by Ookla

Selecting server:
      10162:  24.78 ms; CenturyLink - Portland, OR
      29938:  26.25 ms; FIBERFI - Portland, OR
      16252:  26.25 ms; allstream - Portland, OR
       6215:  30.11 ms; LS Networks - Portland, OR
      45243:  18.55 ms; OHSU - Portland, OR
       6531:  20.86 ms; SilverStarTelecom - Portland, OR
       1780:  19.48 ms; Comcast - Portland, OR
      53972:  23.44 ms; Dish Wireless - Portland, OR
      33992:  29.45 ms; Sherwood Broadband - Sherwood, OR
      49788:  47.15 ms; Mimo Connect Ltd - Hillsboro, OR
      Server: OHSU - Portland, OR (id: 45243)
         ISP: Comcast Cable
Idle Latency:    34.50 ms   (jitter: 6.83ms, low: 27.61ms, high: 42.97ms)
    Download:   838.22 Mbps (data used: 880.4 MB)                                                   
                 20.74 ms   (jitter: 4.59ms, low: 9.34ms, high: 70.42ms)
      Upload:    23.81 Mbps (data used: 12.5 MB)                                                   
                 43.22 ms   (jitter: 17.59ms, low: 20.63ms, high: 190.23ms)
 Packet Loss: Not available.
  Result URL: https://www.speedtest.net/result/c/***

Except for latency (let's ignore it here once its "wrong" value may be the root cause), comparing the output above vs. the below (both server 45243), the down/up results are not so close (maybe due to the other issue told above), but "acceptable" ones for this discussion:

support@host:~$ ./speedtest-go --version
1.5.0

support@host:~$ ./speedtest-go -s 45243
Testing From IP: ****

Target Server: [45243]     7.36km Portland, OR (United States) by OHSU
Latency: 302.542824ms
Jitter: 750.463579ms
Min: 37.912272ms
Max: 2.553466356s
Download Test: ...........
Upload Test: ...........
 
Download: 742.60 Mbit/s
Upload: 24.32 Mbit/s

But when we let speedtest-go choosing the target server, the discrepancy in the results is bigger:

support@host:~$ ./speedtest-go         
Testing From IP: ***

Target Server: [6531]     7.36km Portland, OR (United States) by SilverStarTelecom
Latency: 39.594061ms
Jitter: 7.799145ms
Min: 29.288382ms
Max: 54.47793ms
Download Test: ...........
Upload Test: ............
 
Download: 583.41 Mbit/s
Upload: 23.82 Mbit/s

Also, not sure if relevant here, but the list speedtest-go servers list is bigger, despite of somehow similar to the top ones.

support@host:~$ ./speedtest-go -l       
***
[ 6531]      7.36km 27ms 	Portland, OR (United States) by SilverStarTelecom 
[10162]      7.36km 60ms 	Portland, OR (United States) by CenturyLink 
[29938]      7.36km 88ms 	Portland, OR (United States) by FIBERFI 
[16252]      7.36km 62ms 	Portland, OR (United States) by allstream 
[ 6215]      7.36km 69ms 	Portland, OR (United States) by LS Networks 
[45243]      7.36km 66ms 	Portland, OR (United States) by OHSU 
[53972]      7.36km 113ms 	Portland, OR (United States) by Dish Wireless 
[ 1780]      7.36km 96ms 	Portland, OR (United States) by Comcast 
[33992]     16.57km 78ms 	Sherwood, OR (United States) by Sherwood Broadband 
[13314]     22.14km 53ms 	Canby, OR (United States) by DirectLink 
[49788]     23.25km 141ms 	Hillsboro, OR (United States) by Mimo Connect Ltd 
[37289]     23.25km 80ms 	Hillsboro, OR (United States) by City of Hillsboro 
[51770]     35.00km 66ms 	Sandy, OR (United States) by SandyNet 
[18533]     37.23km 92ms 	Woodburn, OR (United States) by Wave 
[33171]     38.38km 104ms 	Colton, OR (United States) by COLTON.COM 
[ 3652]     47.57km 54ms 	McMinnville, OR (United States) by Hunter Communications 
[ 1744]     57.33km 136ms 	Estacada, OR (United States) by Reliance Connects 
[25011]     71.47km 123ms 	Turner, OR (United States) by ViserFiber 
[11976]     73.84km 108ms 	Stayton, OR (United States) by Stayton Telephone 
[25719]     79.83km 101ms 	Monmouth, OR (United States) by Minet Fiber 
support@host:~$ speedtest -L
Closest servers:

    ID  Name                           Location             Country
==============================================================================
 10162  CenturyLink                    Portland, OR         United States
 29938  FIBERFI                        Portland, OR         United States
 16252  allstream                      Portland, OR         United States
  6215  LS Networks                    Portland, OR         United States
 45243  OHSU                           Portland, OR         United States
  6531  SilverStarTelecom              Portland, OR         United States
  1780  Comcast                        Portland, OR         United States
 53972  Dish Wireless                  Portland, OR         United States
 33992  Sherwood Broadband             Sherwood, OR         United States
 49788  Mimo Connect Ltd               Hillsboro, OR        United States

The point: is the latency calculation an issue and/or somehow can we automatically select what Ookla does so as the target server?

fetching server list failed: unable to retrieve server list error when running at :00 and :30 minutes of the hour

Hi,

I've noticed this error while running InfluxData's Telegraf, which is using your speedtest-go as upstream library for their internet_speed plugin. Whenever this plugin runs at exactly :00 or :30 minutes every hour, it always fails, producing this error:

fetching server list failed: unable to retrieve server list

This was also confirmed by running the binary itself using cron, so it's not just the plugin itself - see the discussion here.

wrong server list is returned

When using version 1.1.2, the --list command is not returning the correct server list. On the same host, just doing curl https://www.speedtest.net/speedtest-servers-static.php the list returns the proper servers (those close to me) but if I use the --list command, the closest server is 250km away. Which of course impacts the testing results.

This is somehow related to #37 which prevents me from running proper tests since I can't override for the servers closest to my location.

The test is using the pre-built binaries for linux x64 on a centos 7.7 machine. I can provide packet captures if needed,

One detail. This can't be always reproduced... which makes it even more confusing.

Crashes when latency can't be detected

version 1.6.3

When running a test, if it happens to pick servers it can't do a latency test for, it just dies.

✓ Test Server: [39292] 10.91km Ann Arbor, MI (United States) by University of Michigan
✗ Fatal: latency: , err: server connect timeout

Seems to happen when http ping is needed. Perhaps add a warning about that?

Can you please include the timestamp of the test

I have been using speedtest-cli for a while, and recently took speedtest-go for a spin. It is good and reports almost everything I want except the timestamp of the test.

Would you please consider including the timestamp as well?

Thanks.

SpeedTest GO Result divergent with the SpeedTest Ookla.

Hi, I was testing the speed of one network and I can see a huge difference between the test using the Speedtest go and the official Speedtest to the same server...

Test with Official Speedtest:

support@host:~$ speedtest -s 15869

Speedtest by Ookla

  Server: US Internet - Minneapolis, MN (id: 15869)
     ISP: Comcast Cable

Idle Latency: 28.74 ms (jitter: 1.20ms, low: 27.62ms, high: 29.86ms)
Download: 729.82 Mbps (data used: 1.3 GB)
101.70 ms (jitter: 25.78ms, low: 27.06ms, high: 279.96ms)
Upload: 38.96 Mbps (data used: 40.3 MB)
34.53 ms (jitter: 6.21ms, low: 23.25ms, high: 365.48ms)
Packet Loss: 0.0%
Result URL: https://www.speedtest.net/result/c/a1d28179-d892-4d84-976f-71fe560f9eca
support@host:$
support@host:
$

Test with speedtest-go 1.4.1 version:

support@host:~$ sudo ./speedtest-go --server 15869
Testing From IP: ..., (Comcast Cable) [**, **]

Target Server: [15869] 16.96km Minneapolis, MN (United States) by US Internet
Latency: 30.170765ms
Jitter: 3.393959ms
Min: 24.588512ms
Max: 37.256226ms
Download Test: ...........
Upload Test: ............

Download: 124.09 Mbit/s
Upload: 32.41 Mbit/s

support@host:$
support@host:
$

Using API wrong results

Recursive calls thru the api result in cumulative test speeds

./speedtest
test i: 1
Latency: 29.58471ms, Download: 85.848700, Upload: 6.527300
test i: 2
Latency: 49.067701ms, Download: 162.878500, Upload: 12.465000
test i: 3
Latency: 29.116814ms, Download: 241.038000, Upload: 16.620100
test i: 4
Latency: 30.173995ms, Download: 310.099500, Upload: 22.099200

  • 1st test correct as i only have a 100Mb pipe here

------- Example api used with loop --------------
package main

import (
"fmt"
"github.com/showwin/speedtest-go/speedtest"
)

func main () {
var i = 0
for i = 1; i < 5; i++ {
fmt.Println("test i:", i)
Speed()
}
}

func Speed() {
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()
	fmt.Printf("Latency: %s, Download: %f, Upload: %f\n", s.Latency, s.DLSpeed, s.ULSpeed)
}

}

improve speedtest algorithm

  • send requests in parallel
  • change to measure how much data can be down/up loaded in 20 ~ 30 sec
  • change next request file size dynamically depending on response speed

Defining a download/upload size

Hi, I just discovered this library and I got to say it works amazing.
And I couldn't find another one similar to this one, so congratulations.

I just wanted to drop here the idea of being able to define a size in KB/MB for the test, because there is situations when I just need a quick test, just to meassure an aproximate, and the current implementation doesn't allow us to change this (I think it calculates it itself in the warmup right?)

Don't get me wrong, the test is quick, less than a minute actually, but sometimes I just want a 10 or 15 second test (assuming the risk of being less accurate) just to know if the upload speed is closer to 1mbps or closer to 20mbps (just an example). I live in Argentina so yes, an upload of 1mbps is feasible, sadly.

Cheers!

Negative upload results when up BW is somehow high (~500Mbps)

Hi, looks like dafff30 tried to fix it but it seems we still have negative values for the upload test when the up BW is too high (~500 Mbps per the Speedtest CLI tool by Ookla - which, BTW, gives higher values for both up and down). Tested both in 1.1.5 and 1.3.0. Note: --saving-mode gives lower values (~50%), but positive ones.

support@host:~$ ./speedtest-go --version
1.3.0
support@host:~$ ./speedtest-go
Testing From IP: *.*.*.*, (CenturyLink) [*, *] 
Target Server: [52079]    89.06km Denver, CO (United States) by CenturyLink, Inc.
Latency: 2.5150499s
Download Test: ......
Upload Test: .
 
Download: 448.59 Mbit/s
Upload: -6.55 Mbit/s
support@host:~$ ./speedtest-go --saving-mode
Testing From IP: *.*.*.*, (CenturyLink) [*, *] 
 
Target Server: [52079]    89.06km Denver, CO (United States) by CenturyLink, Inc.
Latency: 2.510973709s
Download Test: ......
Upload Test: .
 
Download: 479.07 Mbit/s
Upload: 222.53 Mbit/s

--server option is not working

Whatever how many --server options I passed, speedtest-go always behaviors like without --server options.

speedtest-go version: 1.1.2

(API) Allow for caller to specify the size of upload/download tests

_ = downloadRequest(_context, s, 3)

It appears that server.DownloadTest and server.UploadTest use a hard coded image size (which essentially drives the bandwidth impact of these tests) to dlSizes[3] and ulSizes[3].

var (
dlSizes = [...]int{350, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000}
ulSizes = [...]int{100, 300, 500, 800, 1000, 1500, 2500, 3000, 3500, 4000} // kB
)

I am using the GO API to write a simple program that periodically runs speedtest on a regular basis. I'd like to reduce the size of each download/upload test to reduce overall bandwidth consumption since it will be run on an ongoing basis. Recognizing the is likely a tradeoff between test size/bandwith impact and accuracy, but it would be great if the developer could evaluate that tradeoff rather than rely on the hardcoded values currently provided.

Abstract Speedtest Implementation to Own Package

I have a use case for a speedtest within another project. Would you be interested in accepting PR that abstracts the implementation of the speedtest to its own package?

I will submit a PR shortly.

CMB

add test

  • add test speedtest/request_test.go
  • add test speedtest/server_test.go
  • add test speedtest/user_test.go
  • run test at CI

Out of memory on low memory devices

This project is so great!
But I found that it is difficult to run on low memory devices(64MB) due to "out of memory".
Is there any plan to solve this problem?
thank you!

Feature Defect: --server can't specify a server

Limited by the current API, we can only fetch servers in a specific area. It is not able to get the correct server information when we set --server which outside the service area.

For example:
In Tokyo Area, We got the following server:
[21569] 0.90km 0ms Tokyo (Japan) by i3D.net
[28910] 0.90km 0ms Tokyo (Japan) by fdcservers.net
[50686] 0.90km 0ms Tokyo (Japan) by GSL Networks
[38241] 0.90km 0ms Tokyo (Japan) by Enzu.com
[24333] 0.90km 0ms Tokyo (Japan) by Rakuten Mobile, Inc
[20976] 0.90km 0ms Tokyo (Japan) by GLBB Japan
[50467] 0.90km 0ms Tokyo (Japan) by Verizon
[56935] 0.90km 0ms Tokyo (Japan) by Contabo

If we use --server=3344, it won't match any servers. But in fact, 3344 exists. So, I think, we should change the exec parameter --server to --filter. Because it's more like a filtering action.

And change the implementation of the --server using a [new API] (https://www.speedtest.net/api/ios-config.php)( The API can find servers by ID all over the world) to specify a server. and add a function GetServerByID(id string)

@showwin What do you think?

Low upload speed

Hey, Thanks for the awesome lib it work great I'm using it in Prometheus custom exporter running the test every 5m so far work great only issue am having is low upload speed as compare to manual run using speedtest.net. Is anyone know hot fix or improve the upload speed.

# HELP test_speedtest_download Download speed (bit/s)
# TYPE test_speedtest_download gauge
test_speedtest_download{city="xxxx",country="xxxx",provider="xxxx"} 874.6208
# HELP test_speedtest_latency Latency (ms)
# TYPE test_speedtest_latency gauge
test_speedtest_latency{city="xxx",country="xxx",provider="xxxxx"} 9
# HELP test_speedtest_upload Upload speed (bit/s)
# TYPE test_speedtest_upload gauge
test_speedtest_upload{city="xxx",country="xxx",provider="xxxx"} 318.1458 (half the speed in web it was 800+)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.