Self-hosted service
librespeed/speedtest avatar
librespeed/speedtest

LibreSpeed: self-hosted speed tests without Flash, Java or Websockets

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

15,201 stars2,511 forksJavaScriptLGPL-3.0

At a glance

What is it?
LibreSpeed is a lightweight JavaScript speed test you host yourself, with a PHP backend, optional telemetry, and a separate connection stability test. Here is what the repository actually ships, and where it stops being the right tool.
Who is it for?
Adopt LibreSpeed if you need a measurement endpoint on infrastructure you control, with optional telemetry in your own database, and you can give it a fast web server. Do not adopt it if you want a managed third-party test or a Node.js backend today: the README states the Node.js implementation in the node branch is not recommended at the moment.
Can I use it commercially?
Yes, with conditions. LGPL-3.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

Who needs a speed test they can host themselves

The problem LibreSpeed solves is measurement ownership. A public speed test service measures the path between a user and that service's servers, not the path between a user and your network. If you run an ISP, a campus network, a data centre, or a branch office, that distinction decides whether a complaint about slow connectivity can be answered with your own data. LibreSpeed gives you an endpoint on your own hardware, so the number that comes back describes the link you are responsible for.

The audience is narrow and technical. The README lists server requirements that assume someone administers a web server: Apache 2, nginx or IIS, PHP 5.4 or newer, and optionally MariaDB, MySQL, Microsoft SQL Server, PostgreSQL or SQLite for storing results. The project describes itself as a very lightweight speed test implemented in Javascript using XMLHttpRequest and Web Workers, and it is distributed under LGPL-3.0-or-later. It is not a service you sign up for; it is a set of static files plus a backend you deploy.

One design decision is worth stating plainly. LibreSpeed measures bandwidth by pushing data through the browser, so the host's own connection is part of the instrument. A server on a 100 Mbit uplink cannot credibly measure a gigabit client. The README puts it as a requirement: a fast internet connection.

How the browser, the worker and the backend divide the work

The architecture separates the user interface from the measurement loop. The top-level repository layout shows speedtest.js alongside speedtest_worker.js: the first drives the page, the second runs inside a Web Worker so that measurement traffic does not block rendering. That is why the README can claim no Websocket requirement. Data moves over XMLHttpRequest, the same transport the browser already uses for ordinary requests, which is also why the compatibility list reaches back to IE11.

A second layer sits between the user and those two files. The root index.html is described as a lightweight switcher that redirects to index-classic.html or index-modern.html, choosing between them based on config.json and the useNewDesign key, or on URL overrides such as ?design=new and ?design=old. The modern interface loads its assets from frontend/, which is why the installation instructions insist on copying that directory as a whole rather than unpacking its contents.

On the server side, the backend/ directory holds the PHP code that serves the test payload and, when telemetry is enabled, records results. The results/ directory contains the PHP files and fonts used to render a shareable result image, and its own config file is where the database connection is set up. For deployments with more than one vantage point, server-list.json and the example pages under examples/ show how a single page can point at several test servers. The stability test follows the same pattern with stability.html and stability_worker.js, and the README notes that Docker deployments copy both into the web root and reuse the same server list configuration as the main UI.

Installing LibreSpeed on Apache and running a first test

The README describes a manual installation that assumes PHP and a web server are already present. Download the source and extract it, then copy the project files into your web server's shared folder, for example /var/www/html/speedtest for Apache, keeping the repository layout intact. The modern UI loads its assets from frontend/, so that directory is copied as a whole. Permissions need to allow read and execute access where required. After that, visiting YOURSITE/speedtest/index.html should show the test interface.

If you would rather not manage PHP by hand, the repository ships a Dockerfile based on php:8-apache. The package.json scripts wrap the build:

bash
npm run docker:build

That script runs docker build with the tag librespeed-speedtest against the repository root. The Dockerfile installs the iconv, gd, pdo, pdo_mysql, pdo_pgsql and pgsql extensions, copies backend/ and frontend/ into /speedtest, and sets defaults including WEBPORT=8080, MODE=standalone, TELEMETRY=false and USE_NEW_DESIGN=false. The Dockerfile's own environment defaults are what a first container run uses:

bash
ENV WEBPORT=8080

After the container starts, the test page is reachable on port 8080 of the host. Running a test from that page exercises the download, upload, ping and jitter measurements the README lists as features. Telemetry stays off until you set TELEMETRY to true and configure a database, so a default container stores nothing.

For development work rather than deployment, DEVELOPMENT.md covers npm tasks. The scripts in package.json include npm run lint for eslint over speedtest.js, speedtest_worker.js and stability_worker.js, npm run format for prettier, npm run validate to run both checks, and npm run test:e2e for Playwright. Note that npm test itself prints that no automated tests are configured yet and exits successfully, so it is not a signal of anything.

The stability test is a separate tool with its own targets

Bandwidth numbers hide the thing users actually complain about: intermittent latency. LibreSpeed addresses that with stability.html, a standalone page linked from both interfaces. According to the README it repeatedly measures ping over a selected duration and reports current, average, minimum, maximum, jitter, and failed request percentage values, with a live chart. It also supports optional latency threshold alerts and CSV export of the collected samples.

The target selection is the interesting part. The stability test can point at the local LibreSpeed backend, at one of the configured multiple points of test, or at built-in external targets such as Google, Cloudflare, and Apple. That third option is a real difference from the main test: you can chart latency to a third party without running a bandwidth test against them, which keeps the traffic small. The CSV export matters for anyone who needs to attach evidence to a ticket rather than quote a single figure.

This is also where the release history is informative. The connection stability test with latency charting, loss tracking, threshold alerts and CSV export appears in the feature list for the current release line, and v6.3.0 is dated 2026-09-12, with v6.2.1 on 2026-08-12 and v6.2.0 on 2026-07-23. The stability tooling is recent work, not a long-settled component, so treat its behaviour as something to check against your own targets before you depend on the alerts.

Where LibreSpeed is the wrong instrument

The most concrete limitation is stated by the project itself. The README says a partial Node.js implementation is available in the node branch, developed by dunklesToast, and then adds that it is not recommended to use at the moment. Teams that standardised on Node and hoped to avoid PHP should read that as a closed door for now. The supported paths are the PHP backend in this repository, the speedtest-go repository maintained by Maddie Zhan, and the speedtest-rust repository maintained by Sudo Dios, all of which are separate projects with their own maintenance.

A second limitation is environmental. The server requirements include a fast internet connection, and nothing in the software can compensate for a slow host. Testing a 500 Mbit client from a host with a 100 Mbit uplink produces a number that describes the host. The same applies to a container running on an oversubscribed virtual machine.

A third is that the browser is an imperfect measurement device. XMLHttpRequest and Web Workers were chosen for compatibility, and the README's compatibility list includes IE11, which tells you the code path is conservative. That is a reasonable trade for reach, but it means the test is not a substitute for a dedicated throughput tool when you need precise, repeatable figures at line rate. Use it to characterise what a real user on a real browser experiences, not to certify a circuit.

Finally, telemetry is off by default and requires a database. If you enable it, you are storing test results and, depending on the optional settings the Dockerfile exposes, potentially IP address information. The defaults ENABLE_ID_OBFUSCATION=false and REDACT_IP_ADDRESSES=false are worth reviewing before you turn telemetry on.

LibreSpeed against a public speed test service

The obvious alternative is a public service such as the ones people type into a search box. The difference in approach is who owns the endpoint. A public service gives you a large, well-provisioned server network and zero deployment work, and its results are comparable across users because everyone measures against the same infrastructure. LibreSpeed gives you an endpoint on your own hardware and nothing else: comparability across the internet is gone, because your server is the only one in the picture.

That trade is the whole point. If you want to know whether a customer's connection to your network is healthy, a public test answers a different question, since it measures the path to that provider's servers. If you want a number you can compare against a global baseline, LibreSpeed is the wrong side of the trade and you should use the public service.

Within the self-hosted space, the alternative is a different backend rather than a different product. The README points to speedtest-go and speedtest-rust as separate repositories with separate maintainers, and to the node branch inside this repository. Choosing between them is mostly a question of which runtime you already operate and are willing to patch. The frontend, the examples and the stability page belong to this repository; the Go and Rust implementations are their own codebases.

Licence, maintenance and what upgrading costs

LibreSpeed is licensed under LGPL-3.0-or-later, and the README carries the standard copyright notice for Federico Dossena covering 2016 to 2024. The practical consequence of a weak-copyleft licence is that you can deploy the test alongside your own application without publishing that application, but modifications to the library itself carry obligations. That is a general description of the licence family, not legal advice; read the licence text if your distribution model is unusual.

The repository is not archived, and the last push was on 2026-09-12, the same day as the v6.3.0 release. Releases arrive at a steady cadence: v6.2.0 on 2026-07-23, v6.2.1 on 2026-08-12, v6.3.0 on 2026-09-12. For a self-hosted deployment the upgrade cost is low but not zero. Because the frontend and the backend are separate trees, an upgrade means replacing both, and any local edits to config.json, settings.json or the results configuration have to be reapplied. The Docker route reduces this to pulling a new image.

The README makes one maintenance argument for the image directly: it is built every week to include an updated version of the ipinfo-DB used for ISP detection, and to ensure the latest security patches in PHP are installed, which is why the project recommends using the latest image. If you build from source instead, you take on the PHP patching yourself. The package.json engines field requires Node.js 14.0.0 or newer, but that applies to the development tooling, not to running the test.

Editorial conclusion

Adopt LibreSpeed if you need a measurement endpoint on infrastructure you control, with optional telemetry in your own database, and you can give it a fast web server. Do not adopt it if you want a managed third-party test or a Node.js backend today: the README states the Node.js implementation in the node branch is not recommended at the moment. Before rolling it out, verify that your web server serves frontend/ as a whole directory, that the results database config in results/ matches your chosen engine, and that the host's own uplink is faster than the connections you intend to measure.

Frequently asked questions

What is LibreSpeed and who is it for?

It is a self-hosted speed test implemented in JavaScript with XMLHttpRequest and Web Workers, with a PHP backend and optional results storage. It is aimed at people who administer their own web server and want to measure connectivity against their own infrastructure.

How do I install LibreSpeed?

The README describes copying the project files into your web server's shared folder, keeping the layout intact and copying frontend/ as a whole, then visiting YOURSITE/speedtest/index.html. A Dockerfile based on php:8-apache is also provided, and npm run docker:build builds an image from it.

Does LibreSpeed need a database?

No. The README lists MariaDB or MySQL as optional for storing test results, with Microsoft SQL Server, PostgreSQL and SQLite also supported. The Dockerfile's default TELEMETRY=false means a default container stores nothing.

Is there a LibreSpeed CLI client?

The README points to a separate command line client in the librespeed/speedtest-cli repository, and also lists an Android client template, a .NET client library, and Go and Rust backends as separate repositories.

Can I run LibreSpeed on Node.js instead of PHP?

The README states that a partial Node.js implementation exists in the node branch and that it is not recommended to use at the moment. The documented alternatives are the separate speedtest-go and speedtest-rust repositories.

Official sources

  1. librespeed/speedtest on GitHub
  2. License: LGPL-3.0
  3. Project website
  4. README
  5. Releases
For maintainers

Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/librespeed-speedtest.svg)](https://hysenlabs.com/projects/librespeed-speedtest)
Community notes

Community notes