Time to First Byte
Measure HTTP time to first byte and repeat until interrupted.
Requires Python 3.13 or newer. The runtime is the standard library only.
Install
pip install lupaxa-time-to-first-byte
time-to-first-byte --help
CLI
time-to-first-byte and ttfb call the same entry point.
time-to-first-byte --url https://example.com --count 5
ttfb -u https://example.com --delay 1 --timeout 5
python -m lupaxa.time_to_first_byte --version
The tool resolves the host, connects, negotiates TLS for HTTPS, sends
a GET, and stops at the first response byte. It follows up to 10
redirects by default and repeats every second until Ctrl-C unless
--count is set.
--timeout bounds socket operations after address resolution (default
5 seconds). DNS uses the system resolver and is not bounded by
--timeout. --timeout must be greater than 0. --delay and
--max-redirects must be 0 or greater. --count must be greater
than 0 when set. The URL must use HTTP or HTTPS.
A passing sample prints the original URL, sequence, final status, redirect count, and phase timings:
https://example.com seq=0 status=200 redirects=0 dns=4.25 ms connect=18.50 ms tls=24.10 ms ttfb=53.75 ms
An HTTP 4xx or 5xx response is still a pass when the server returns a first byte. The status is the HTTP response. Pass or fail is whether the measurement completed.
A failed sample prints the original URL, sequence, and reason:
https://example.com seq=0 error: connection timed out
At the end of --count, or after Ctrl-C, the command prints a
summary. ttfb min/avg/max uses passing samples only:
TTFB Results: Samples (Total/Pass/Fail): [5/4/1] (Failed: 20.00%) ttfb min/avg/max=41.20/48.35/57.80 ms
dns, connect, and tls on a passing line are the final hop. tls
is 0 for plain HTTP. ttfb includes every followed redirect and
measures the whole sample through the first byte of the final
response.
Flags
| Flag | Default | Description |
|---|---|---|
--url, -u |
required | HTTP or HTTPS URL |
--delay, -d |
1 |
Seconds between samples |
--count, -c |
run until interrupted | Number of samples |
--timeout, -T |
5 |
Socket timeout in seconds |
--max-redirects |
10 |
Maximum redirects to follow |
--version |
— | Print the package version and exit |
Exit Codes
| Code | When |
|---|---|
0 |
Help, version, Ctrl-C, or every sample in a finite run passed |
1 |
A sample failed, or runtime input validation failed |
2 |
Command-line usage or argument parsing failed |
Examples
Until Ctrl-C (one sample per second, then a summary):
ttfb --url https://example.com
Five samples (exit 0 when all pass, 1 when any fail):
time-to-first-byte --url https://example.com --count 5
Back-to-back samples (--delay 0 is valid):
ttfb --url https://example.com --delay 0 --count 10
Library
from lupaxa.time_to_first_byte import measure, run_measurements
one = measure("https://example.com", timeout=5.0, max_redirects=10)
print(one.ok, one.status, one.ttfb_ms, one.final_url)
summary = run_measurements("https://example.com", count=3, delay=0)
print(summary.total, summary.passed, summary.failed, summary.ttfb_avg_ms)
measure returns one TimingResult: ok, url, sequence,
dns_ms, connect_ms, tls_ms, ttfb_ms, status, redirects,
final_url, and detail. Connection, TLS, HTTP, and redirect
failures come back as ok=False rather than raised exceptions.
Invalid URLs, timeouts, delays, counts, and redirect limits raise
ValueError.
run_measurements returns a TimingSummary: total, passed,
failed, fail_percent, ttfb_min_ms, ttfb_avg_ms, ttfb_max_ms,
and results. count=None repeats until should_stop or forever.
Minimum, average, and maximum TTFB use passing samples only.
Development
make init
make python-install-dev
make python-check
Metadata
Release files for lupaxa-time-to-first-byte 0.1.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| lupaxa_time_to_first_byte-0.1.5.tar.gz | 9.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| lupaxa_time_to_first_byte-0.1.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.4 kB
Release files / lupaxa_time_to_first_byte-0.1.5.tar.gz
| Download URL | lupaxa_time_to_first_byte-0.1.5.tar.gz |
|---|---|
| Size | 9.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
de404e78b58f232230d201d51afde0ac0780fe613ca6e67f1269c500aee65b67
|
|
BLAKE2b-256 checksum How to use checksums |
dff357425abf20ea7735f608216543201f3e1baa1e7633805e716359eb7148e9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.
Transparency logRelease files / lupaxa_time_to_first_byte-0.1.5-py3-none-any.whl
| Download URL | lupaxa_time_to_first_byte-0.1.5-py3-none-any.whl |
|---|---|
| Size | 11.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
879fb3c9d2100b37a84d6dbaf1875090091466968941765ef5cd54ff033eee87
|
|
BLAKE2b-256 checksum How to use checksums |
41ed062a3599b3bab6871635a93f9f79df91b557a70c93f7291fbae2b0e049ab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.
Transparency log