Static File Serving Benchmark (HTTP/1.1 + TLS): Implementation Guide
.br/.gz variants that sit on disk next to the originals is allowed, by a documented framework API (e.g. ASP.NET MapStaticAssets, nginx gzip_static / brotli_static, Caddy precompressed, Hono serveStatic({ precompressed: true })) where the framework has one, and otherwise by selecting the variant in the entry off Accept-Encoding. Those bytes already exist, so choosing one is a file read rather than compression - which is why this is allowed while compressing by hand is not. The response must carry the original file's Content-Type, the matching Content-Encoding, and must still follow the disk. TLS must come from a standard stack (OpenSSL, BoringSSL, rustls, SChannel, JDK JSSE, etc.) - no TLS session-ticket shortcuts that skip real handshakes.The Static Files over TLS profile is the Static Files workload transported over HTTP/1.1 + TLS on a dedicated port. It measures how much of a framework's plaintext static-serving throughput survives encryption.
Connections: 1,024, 4,096, 6,800
How it works
- The framework serves the same 20 files from
/data/static/as the plainstaticprofile - The framework listens on port 8081 with HTTPS, serving HTTP/1.1 only (ALPN advertises
http/1.1) - The load generator (wrk) requests the 20 files in a round-robin pattern using the same Lua rotation script as
static(requests/static-rotate.lua), overhttps:// - All requests include
Accept-Encoding: br;q=1, gzip;q=0.8 - CSS (5 files, 8–200 KB):
reset.css,layout.css,theme.css,components.css,utilities.css - JavaScript (5 files, 12–300 KB):
analytics.js,helpers.js,app.js,vendor.js,router.js - HTML (2 files, 55–120 KB):
header.html,footer.html - Fonts (2 files, 18–22 KB):
regular.woff2,bold.woff2 - SVG (2 files, 15–70 KB):
logo.svg,icon-sprite.svg - Images (3 files, 6–45 KB):
hero.webp,thumb1.webp,thumb2.webp - JSON (1 file, 3 KB):
manifest.json
Total payload: ~842 KB across 20 files (~743 KB compressible text + ~99 KB binary). Brotli-compressed total: ~219 KB.
Pre-compressed versions of all text files (.gz at level 9, .br at level 11) are available in the data/static/ directory alongside the originals.
Compression
Identical to the plain static profile: compression is optional and must come from standard middleware on production entries, while serving the pre-compressed .br/.gz files already on disk is allowed for every entry type. Tuned entries are unrestricted.
Port, ALPN, and certificates
- Port: 8081 (distinct from 8080 plaintext and 8443 which is dedicated to HTTP/2 / HTTP/3 profiles), shared with the
json-tlsprofile - ALPN: advertise
http/1.1only. HTTP/1.1-only clients (wrk) negotiate correctly and never upgrade to h2. - Certificates: the same PEM files used by
json-tls/baseline-h2/static-h2, mounted at/certs/server.crtand/certs/server.key. Frameworks typically read them via environment variables (TLS_CERT,TLS_KEY) or a hardcoded path, same pattern as the other TLS tests.
What it measures
- Everything Static Files measures
- TLS handshake cost amortized over keep-alive - connections are long-lived at 1,024–6,800 concurrent
- Record framing overhead on large payloads - multi-hundred-KB responses span many TLS records, unlike the small JSON bodies of
json-tls - Symmetric cipher throughput - AES-GCM / ChaCha20-Poly1305 on the hot path, dominated by bulk encryption of file bodies
Expected request/response
GET /static/reset.css HTTP/1.1
Host: localhost:8081
Accept-Encoding: br;q=1, gzip;q=0.8
HTTP/1.1 200 OK
Content-Type: text/css
Content-Encoding: br
(compressed file contents)
Or without compression:
HTTP/1.1 200 OK
Content-Type: text/css
(file contents)
Parameters
| Parameter | Value |
|---|---|
| Endpoint | 20 URIs under /static/* |
| Transport | HTTP/1.1 over TLS |
| Port | 8081 |
| ALPN | http/1.1 |
| Connections | 1,024, 4,096, 6,800 |
| Pipeline | 1 |
| Duration | 5s |
| Runs | 3 (best taken) |
| Load generator | wrk + requests/static-rotate.lua |
| Certificates | mounted at /certs/server.crt + /certs/server.key |