speedtest Documentation

Self-hosted Speed Test for HTML5 and more. Easy setup, examples, configurable, mobile friendly. Supports PHP, Node, Multiple servers, and more

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy speedtest on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name speedtest -p 9123:9123 --restart always postgres:alpine
Configured Services & Ports
โš™๏ธ pg
image: postgres:alpine
โš™๏ธ speedtest-debian-pg
image: build locally
๐Ÿ”Œ Ports: 9123:8080
โš™๏ธ speedtest-alpine-pg
image: build locally
๐Ÿ”Œ Ports: 9124:8080
โš™๏ธ mysql
image: mysql:lts
โš™๏ธ speedtest-debian-mysql
image: build locally
๐Ÿ”Œ Ports: 9125:8080
โš™๏ธ speedtest-alpine-mysql
image: build locally
๐Ÿ”Œ Ports: 9126:8080
โš™๏ธ mssql
image: mcr.microsoft.com/mssql/server:2022-latest
โš™๏ธ mssql-init
image: mcr.microsoft.com/mssql/server:2022-latest
โš™๏ธ speedtest-debian-mssql
image: build locally
๐Ÿ”Œ Ports: 9130:8080
โš™๏ธ speedtest-alpine-mssql
image: build locally
๐Ÿ”Œ Ports: 9131:8080
โš™๏ธ speedtest-debian-sqlite
image: build locally
๐Ÿ”Œ Ports: 9127:8080
โš™๏ธ speedtest-alpine-sqlite
image: build locally
๐Ÿ”Œ Ports: 9128:8080
โš™๏ธ speedtest-alpine-sqlite-dual
image: build locally
๐Ÿ”Œ Ports: 9129:8080
โš™๏ธ test-container
image: alpine
docker-compose.yml
yaml (docker-compose.yml)
## this is a docker compose file used to test all scenarios
## do not use it in production
x-shared:
  speedtest-service: &speedtest-service
    environment:
      - PASSWORD=gimmeTheStats1337
      - [email protected]
      - ENABLE_ID_OBFUSCATION=true
      - MODE=standalone
      - REDACT_IP_ADDRESSES=true
      - TELEMETRY=true

services:
  ###################### POSTGRESQL ################################
  pg:
    image: postgres:alpine
    environment:
      POSTGRES_PASSWORD: Not4SecureProduction
      POSTGRES_USER: librespeed
    volumes:
      # mount init script from source to create database tables
      - ../../results/telemetry_postgresql.sql:/docker-entrypoint-initdb.d/01-init.sql

  speedtest-debian-pg:
    build:
      context: ../..
      dockerfile: Dockerfile
    environment: &env_vars_pg
      - PASSWORD=gimmeTheStats1337
      - DB_HOSTNAME=pg
      - DB_NAME=librespeed
      - DB_PASSWORD=Not4SecureProduction
      - DB_TYPE=postgresql
      - DB_USERNAME=librespeed
      - [email protected]
      - ENABLE_ID_OBFUSCATION=true
      - MODE=standalone
      - REDACT_IP_ADDRESSES=true
      - TELEMETRY=true
    ports:
      - 9123:8080

  speedtest-alpine-pg:
    build:
      context: ../..
      dockerfile: Dockerfile.alpine
    environment: *env_vars_pg
    ports:
      - 9124:8080

  ####################### MYSQL ##############################

  mysql:
    image: mysql:lts
    environment:
      MYSQL_ROOT_PASSWORD: Not4SecureProduction
      MYSQL_USER: librespeed
      MYSQL_PASSWORD: Not4SecureProduction
      MYSQL_DATABASE: librespeed
    volumes:
      # mount init script from source to create database tables
      - ../../results/telemetry_mysql.sql:/docker-entrypoint-initdb.d/01-init.sql

  speedtest-debian-mysql:
    # check at http://localhost:9125/results/sanitycheck.php
    build:
      context: ../..
      dockerfile: Dockerfile
    environment: &env_vars_mysql
      - PASSWORD=gimmeTheStats1337
      - DB_HOSTNAME=mysql
      - DB_NAME=librespeed
      - DB_PASSWORD=Not4SecureProduction
      - DB_TYPE=mysql
      - DB_USERNAME=librespeed
      - [email protected]
      - ENABLE_ID_OBFUSCATION=true
      - MODE=standalone
      - REDACT_IP_ADDRESSES=true
      - TELEMETRY=true
    ports:
      - 9125:8080
  speedtest-alpine-mysql:
    build:
      context: ../..
      dockerfile: Dockerfile.alpine
    environment: *env_vars_mysql
    ports:
      - 9126:8080

  ####################### MSSQL ##############################

  mssql:
    image: mcr.microsoft.com/mssql/server:2022-latest
    environment:
      - ACCEPT_EULA=Y
      - SA_PASSWORD=Not4SecureProduction1337
      - MSSQL_PID=Express
    healthcheck:
      test:
        ["CMD-SHELL", "/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P $$SA_PASSWORD -C -Q 'SELECT 1' || exit 1"]
      interval: 10s
      retries: 5
      start_period: 30s

  mssql-init:
    image: mcr.microsoft.com/mssql/server:2022-latest
    depends_on:
      mssql:
        condition: service_healthy
    environment:
      - SA_PASSWORD=Not4SecureProduction1337
    volumes:
      - ../../results/telemetry_mssql.sql:/docker-entrypoint-initdb.d/01-init.sql:ro
    command: >
      bash -c '
        echo "Waiting for MSSQL to be ready...";
        until /opt/mssql-tools18/bin/sqlcmd -S mssql -U sa -P "$$SA_PASSWORD" -C -Q "SELECT 1"; do
          sleep 1;
        done;
        echo "Running init scripts...";
        for f in /docker-entrypoint-initdb.d/*.sql; do
          echo "Executing $$f...";
          /opt/mssql-tools18/bin/sqlcmd -S mssql -U sa -P "$$SA_PASSWORD" -C -i "$$f";
        done;
        echo "Initialization complete!";
      '

  speedtest-debian-mssql:
    build:
      context: ../..
      dockerfile: Dockerfile
    environment: &env_vars_mssql
      - PASSWORD=gimmeTheStats1337
      - DB_HOSTNAME=mssql
      - DB_NAME=librespeed
      - DB_PASSWORD=Not4SecureProduction1337
      - DB_TYPE=mssql
      - DB_USERNAME=sa
      - [email protected]
      - ENABLE_ID_OBFUSCATION=true
      - MODE=standalone
      - REDACT_IP_ADDRESSES=true
      - TELEMETRY=true
    ports:
      - 9130:8080

  speedtest-alpine-mssql:
    build:
      context: ../..
      dockerfile: Dockerfile.alpine
    environment: *env_vars_mssql
    ports:
      - 9131:8080

  ################ SQLITE ####################################

  speedtest-debian-sqlite:
    # check at http://localhost:9125/results/sanitycheck.php
    build:
      context: ../..
      dockerfile: Dockerfile
    environment: &env_vars_sqlite
      - PASSWORD=gimmeTheStats1337
      - [email protected]
      - ENABLE_ID_OBFUSCATION=true
      - MODE=standalone
      - REDACT_IP_ADDRESSES=true
      - TELEMETRY=true
    ports:
      - 9127:8080

  speedtest-alpine-sqlite:
    build:
      context: ../..
      dockerfile: Dockerfile.alpine
    environment: *env_vars_sqlite
    ports:
      - 9128:8080

  speedtest-alpine-sqlite-dual:
    <<: *speedtest-service
    build:
      context: ../..
      dockerfile: Dockerfile.alpine
    environment:
      - MODE=dual

    volumes:
      - ./servers.json:/servers.json:ro
    ports:
      - 9129:8080

  ##############  TEST CONTAINER  ###############################################################
  test-container:
    image: alpine
    depends_on:
      - pg
      - mysql
      - mssql-init
      - speedtest-alpine-mysql
      - speedtest-alpine-pg
      - speedtest-alpine-mssql
    volumes:
      - ./test-script.sh:/test-script.sh
    command:
      - sh
      - /test-script.sh

LibreSpeed

No Flash, No Java, No Websocket, No Bullshit.

This is a very lightweight speed test implemented in Javascript, using XMLHttpRequest and Web Workers.

Try it

Take a speed test

Compatibility

All modern browsers are supported: IE11, latest Edge, latest Chrome, latest Firefox, latest Safari.
Works with mobile versions too.

Features

  • Download
  • Upload
  • Ping
  • Jitter
  • IP Address, ISP, distance from server (optional)
  • Telemetry (optional)
  • Results sharing (optional)
  • Multiple Points of Test (optional)
  • Connection stability test with latency charting, loss tracking, threshold alerts, and CSV export

Server requirements

  • A reasonably fast web server with Apache 2 (nginx, IIS also supported)
  • PHP 5.4 or newer (other backends also available)
  • MariaDB or MySQL database to store test results (optional, Microsoft SQL Server, PostgreSQL and SQLite also supported)
  • A fast! internet connection

Installation

Assuming you have PHP and a web server installed, the installation steps are quite simple.

  1. Download the source code and extract it
  2. Copy the project files to your web server's shared folder (ie. /var/www/html/speedtest for Apache), keeping the layout as it is in the repository. The modern UI loads its assets from frontend/, so that directory is copied as a whole rather than unpacked.
  3. Optionally, copy the results folder too, and set up the database using the config file in it.
  4. Be sure your permissions allow read and execute access where needed.
  5. Visit YOURSITE/speedtest/index.html and voila!

Installation Video

This video shows the installation process of a standalone LibreSpeed server: Quick start installation guide for Debian 12

More videos will be added later.

Android app

A template to build an Android client for your LibreSpeed installation is available here.

CLI client

A command line client is available here.

.NET client

A .NET client library is available in the LibreSpeed.NET repo (NuGet), maintained by MemphiZ.

Development

If you want to contribute or develop with LibreSpeed, see DEVELOPMENT.md for information about using npm for development tasks, linting, and formatting.

Design switch

LibreSpeed supports both the classic and modern UI. The root index.html acts as a lightweight switcher and redirects to index-classic.html or index-modern.html based on config.json (useNewDesign) or URL overrides (?design=new / ?design=old). For architecture and deployment details (including Docker behavior), see DESIGN_SWITCH.md.

Stability test

LibreSpeed includes a standalone connection stability test at stability.html, linked from both the classic and modern interfaces. It repeatedly measures ping over a selected duration and reports current, average, minimum, maximum, jitter, and failed request percentage values with a live chart.

The stability test can target the local LibreSpeed backend, one of the configured multiple points of test, or built-in external targets such as Google, Cloudflare, and Apple. It also supports optional latency threshold alerts and CSV export of the collected samples. Docker deployments copy stability.html and stability_worker.js into the web root and reuse the same server list configuration as the main UI.

Docker

A docker image is available on GitHub, check our docker documentation for more info about it.
The image is built every week to include an updated version of the ipinfo-DB used for ISP detection. Also this ensures, that the latest security patches in PHP are installed. Therefore we recommend to use the latest image.

Go backend

A Go implementation is available in the speedtest-go repo, maintained by Maddie Zhan.

Rust backend

A Rust implementation is available in the speedtest-rust repo, maintained by Sudo Dios.

Node.js backend

A partial Node.js implementation is available in the node branch, developed by dunklesToast. It's not recommended to use at the moment.


Donate with PayPal

License

Copyright (C) 2016-2024 Federico Dossena

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see https://www.gnu.org/licenses/lgpl.