This is a dependency-free Python tool for testing HTTP/HTTPS download and upload throughput. It is meant for cases where raw TCP/UDP tests look good, but HTTP transfers are slow.
- Python 3.9 or newer, or the bundled Codex Python runtime on this machine
- A second machine, VPS, or server outside the problem network if you want a real end-to-end test
On Windows, use .\http-speed-test.cmd from this folder. It will find python, py, or the bundled Codex Python runtime automatically.
On Linux, use sh ./http-speed-test.sh or run chmod +x ./http-speed-test.sh once and then use ./http-speed-test.sh.
Terminal 1:
.\http-speed-test.cmd server --host 0.0.0.0 --port 8080Terminal 2:
.\http-speed-test.cmd both http://127.0.0.1:8080 --download-size 500M --upload-size 100M --runs 3Loopback should be very fast. If loopback is also stuck below 10 Mbps, the bottleneck is likely local software, endpoint security, proxy settings, or the machine itself.
Run the server on a known-good machine:
.\http-speed-test.cmd server --host 0.0.0.0 --port 8080Then run the client from the affected machine:
.\http-speed-test.cmd both http://SERVER_IP:8080 --download-size 1G --upload-size 500M --runs 3 --streams 8 --progressIf this is over the public internet, allow inbound TCP 8080 on the server firewall or change --port to a port you can reach.
Use this on a Windows client to create C:\install\speed, check for Python 3.9+, install Python with winget if needed, download the tool files, and run a test against the server IP you provide.
powershell -NoProfile -ExecutionPolicy Bypass -Command "New-Item -ItemType Directory -Force -Path C:\install\speed | Out-Null; Invoke-WebRequest -UseBasicParsing https://raw.githubusercontent.com/shin2344234/http-speed-test-tool/main/install-and-run-speed-test.ps1 -OutFile C:\install\speed\install-and-run-speed-test.ps1; & C:\install\speed\install-and-run-speed-test.ps1 -ServerIp SERVER_IP"Multistream client test from the same one-liner:
powershell -NoProfile -ExecutionPolicy Bypass -Command "New-Item -ItemType Directory -Force -Path C:\install\speed | Out-Null; Invoke-WebRequest -UseBasicParsing https://raw.githubusercontent.com/shin2344234/http-speed-test-tool/main/install-and-run-speed-test.ps1 -OutFile C:\install\speed\install-and-run-speed-test.ps1; & C:\install\speed\install-and-run-speed-test.ps1 -ServerIp SERVER_IP -Streams 8"Or, if you already have the repo/files locally:
.\install-and-run-speed-test.ps1 -ServerIp SERVER_IPOptional parameters:
.\install-and-run-speed-test.ps1 -ServerIp SERVER_IP -Port 8080 -DownloadSize 1G -UploadSize 500M -Runs 3 -Streams 8Progress output is enabled by default. Use -NoProgress to suppress it. -Progress is also accepted if you want to be explicit.
To isolate one direction:
.\install-and-run-speed-test.ps1 -ServerIp SERVER_IP -Port 8080 -DownloadOnly
.\install-and-run-speed-test.ps1 -ServerIp SERVER_IP -Port 8080 -UploadOnlyThis script assumes it is running as the logged-in user. If Python is missing or older than 3.9, it uses:
winget install -e --id Python.Python.3.13 --scope user --silent --accept-package-agreements --accept-source-agreements --disable-interactivityOne-command deploy from GitHub and run in the foreground:
curl -fsSL https://raw.githubusercontent.com/shin2344234/http-speed-test-tool/main/install-and-run-linux-server.sh | shSet the port in the same one-liner:
curl -fsSL https://raw.githubusercontent.com/shin2344234/http-speed-test-tool/main/install-and-run-linux-server.sh | sh -s -- --port 9090For NinjaOne or other remote scripting, start the server in the background:
curl -fsSL https://raw.githubusercontent.com/shin2344234/http-speed-test-tool/main/install-and-run-linux-server.sh | sh -s -- --background --quietNinjaOne/background with a custom port:
curl -fsSL https://raw.githubusercontent.com/shin2344234/http-speed-test-tool/main/install-and-run-linux-server.sh | sh -s -- --port 9090 --background --quietIf the Linux machine has wget but not curl:
wget -qO- https://raw.githubusercontent.com/shin2344234/http-speed-test-tool/main/install-and-run-linux-server.sh | sh -s -- --port 9090 --background --quietCustom port or install directory:
curl -fsSL https://raw.githubusercontent.com/shin2344234/http-speed-test-tool/main/install-and-run-linux-server.sh | sh -s -- --port 8080 --install-dir "$HOME/.local/share/http-speed-test-tool" --background --quietThe Linux bootstrap script checks for Python 3.9+, installs Python 3 with the system package manager if needed, downloads the current tool files from GitHub, and starts the server. The default install folder is:
$HOME/.local/share/http-speed-test-toolTo stop a background server started by the bootstrap script:
curl -fsSL https://raw.githubusercontent.com/shin2344234/http-speed-test-tool/main/install-and-run-linux-server.sh | sh -s -- --stop --port 8080If you used a custom install directory or port:
curl -fsSL https://raw.githubusercontent.com/shin2344234/http-speed-test-tool/main/install-and-run-linux-server.sh | sh -s -- --stop --port 9090 --install-dir /opt/speedCopy http_speed_test.py and http-speed-test.sh to the Linux device, then run:
chmod +x ./http-speed-test.sh
./http-speed-test.sh server --host 0.0.0.0 --port 8080If Python is not installed:
sudo apt update && sudo apt install -y python3From the Windows client, test against the Linux server:
.\http-speed-test.cmd both http://LINUX_SERVER_IP:8080 --download-size 1G --upload-size 500M --runs 3 --streams 8 --progressFor a quick Linux-side sanity check:
./http-speed-test.sh both http://127.0.0.1:8080 --download-size 500M --upload-size 100M --runs 3You can point the download tester at any large direct file URL:
.\http-speed-test.cmd download "https://example.com/large-test-file.bin" --runs 3 --streams 8 --progressUse --cache-bust only when the server accepts arbitrary query parameters:
.\http-speed-test.cmd download "https://example.com/large-test-file.bin" --cache-bustThe included server accepts uploads at /upload:
.\http-speed-test.cmd upload http://SERVER_IP:8080/upload --size 500M --runs 3 --streams 8 --progressMost random public websites do not accept large POST bodies, so upload tests are best run against this tool's server or another endpoint you control.
If downloads work through port 80 but uploads fail after about 1 MB with a connection reset, the request is probably hitting a reverse proxy or web server in front of this tool. Common fixes are to run this tool directly on a high port like 8080 or 9091, or raise the proxy upload/body limit.
Client tests are single-stream by default. Add --streams 4, --streams 8, or --streams 16 to run multiple HTTP connections at the same time and measure aggregate throughput.
For tests against this tool's server, --download-size and --upload-size are total test sizes split across the streams. For direct arbitrary download URLs, each stream downloads the given URL.
Run the same test from:
- The affected machine on HTTP
- Another machine on the same network
- A phone hotspot or different ISP
- A machine outside the network back toward the affected site
- A browser download versus this CLI download
If only HTTP is below 10 Mbps while iperf/TCP/UDP are fine, likely suspects include HTTP inspection, antivirus web filtering, transparent proxying, QoS rules, MTU/MSS issues, WAN optimizer behavior, or a CDN/server-specific path.
.\http-speed-test.cmd --help
.\http-speed-test.cmd server --help
.\http-speed-test.cmd download --help
.\http-speed-test.cmd upload --help
.\http-speed-test.cmd both --helpSpeeds are reported as decimal Mbps. Size suffixes like 500M and 1G are decimal bytes; MiB and GiB are also supported.
buymeacoffee.com/sethwalker234 if you want to.