HTTP/3 (QUIC) Test Server & Benchmarking Platform
Three Prongs. One Binary. Every Packet.
Triton is a pure Go toolkit for observing, testing, and benchmarking HTTP/3 and QUIC behavior. The project is designed around a single binary with four primary operating modes:
server: runs protocol-aware test endpointsprobe: inspects and measures remote targetsbench: compares HTTP/1.1, HTTP/2, and HTTP/3 behaviorcheck: runs reusable profile-based verification flows for CI and recurring checks
This repository is not yet the full RFC-complete final product described in the specification, but it already contains a working CLI, a test server, probe/bench flows, QUIC building blocks, and a minimal in-repo H3 loopback stack with handler dispatch.
Current product positioning is pragmatic: real HTTP diagnostics and real HTTP/3 behavior are supported through quic-go, while the in-repo custom QUIC/H3 stack remains lab-only research.
Canonical reference: SUPPORTED.md
Lab-only transport reference: EXPERIMENTAL.md
If any section below conflicts with current running behavior, prefer SUPPORTED.md first, then ARCHITECTURE.md, then the code.
Treat the following as the implementation truth for this repository today:
- Supported server path:
- HTTPS/TCP test server
- optional real HTTP/3 listener via
quic-go - optional embedded dashboard
- Supported client paths:
https://...probe and bench targetsh3://...probe targets using real HTTP/3 viaquic-gohttps://...+h3bench runs using real HTTP/3 viaquic-go
- Lab-only path:
triton://...experimental in-repo UDP H3 transporttriton labinternal/quic/*andinternal/h3/*
Important caveat for probe output:
- Basic checks such as handshake timing, TLS metadata, latency, throughput, and stream sampling are implemented directly.
- Several advanced probe dimensions are still heuristic or contract-based rather than packet-level QUIC truth. That includes
0rtt,migration,qpack,loss,congestion,retry,version,ecn, andspin-bit. - If you need packet-level QUIC validation, do not treat those advanced fields as RFC-grade transport telemetry yet.
This section is intentionally future-looking. It describes target-state goals rather than a promise that every item below already exists in the shipped product surface.
Triton is intended to become a documentation-first, comparison-driven QUIC and HTTP/3 laboratory with:
- a custom QUIC + HTTP/3 engine aligned with RFC 9000, RFC 9001, RFC 9114, and RFC 9204
- deep visibility into packets, frames, streams, timing, loss, and transport behavior
- embedded dashboard, API, benchmarking, and analysis surfaces in one binary
- educational and scriptable tooling for protocol research, performance testing, and debugging
Core principles from the specification:
- Protocol correctness
- Observable by default
- Comparison-driven output
- CLI-first automation
- Educational protocol visibility
Server mode exposes test and benchmark endpoints.
By default, triton server starts the HTTPS/TCP server on :8443 and the dashboard on 127.0.0.1:9090. The in-repo UDP H3 transport is experimental and now requires both --listen and --allow-experimental-h3.
Experimental UDP H3 is also loopback-only by default; binding it on a non-loopback interface now additionally requires --allow-remote-experimental-h3 or server.allow_remote_experimental_h3: true.
Running real HTTP/3 (--listen-h3) and experimental UDP H3 (--listen) together now requires explicit mixed-plane opt-in via --allow-mixed-h3-planes or server.allow_mixed_h3_planes: true.
Remote dashboard binding is blocked by default; use --allow-remote-dashboard only when you intentionally want non-loopback access, and pair it with dashboard auth.
When remote dashboard access is enabled, provide explicit --cert and --key; runtime-generated self-signed fallback is no longer accepted for that mode.
If you want to work with the experimental Triton UDP H3 stack directly, prefer triton lab instead of mixing it into the normal server command.
For the explicit research-only boundary around that surface, see EXPERIMENTAL.md.
Examples:
triton server
triton server --listen-tcp :8443 --dashboard-listen 127.0.0.1:9090
triton server --listen :4433 --allow-experimental-h3 --listen-tcp :8443
triton server --listen-h3 :4434 --listen-tcp :8443
triton labMain endpoints currently available:
GET /GET /pingGET /echoGET /download/:sizePOST /uploadGET /delay/:msGET /streams/:nGET /headers/:nGET /redirect/:nGET /status/:codeGET /drip/:size/:delayGET /tls-infoGET /quic-infoGET /migration-testGET /.well-known/triton
The capability document at /.well-known/triton now reflects the active runtime configuration, including real HTTP/3 availability, whether the experimental Triton UDP H3 path is enabled, the current deployment/stability profile, and build metadata.
Probe mode measures and analyzes a target.
Examples:
triton probe --target https://example.com --format json
triton probe --target triton://loopback/ping --format json
triton probe --target h3://localhost:8443/ping --insecure --allow-insecure-tls --format jsonSpecification-level probe goals include:
- handshake timing
- 0-RTT resumption
- migration
- concurrent streams
- throughput
- latency percentiles
- MTU / ECN / retry / version negotiation
- TLS / ALPN / certificate analysis
- QPACK behavior
- congestion and loss behavior
- spin bit, GREASE, Alt-Svc, and H3 settings
Current probe output includes richer analysis sections for response throughput, sampled latency percentiles, stream-concurrency summaries, and a test_plan plus support matrix that explicitly marks advanced checks as full, partial, or unavailable. The advanced fields are intentionally caveated: the current qpack value is an estimated header-block-size approximation, current loss and congestion values are inferred from repeated request failures and latency spread, current version and retry values are inferred from observed H3 protocol/alpn and handshake visibility, current ecn and spin-bit values are inferred from observable protocol metadata and sampled RTT stability, current 0rtt is resumption timing rather than true early-data proof, and current migration is an endpoint-capability check rather than live path rebinding. The deeper spec items such as true 0-RTT, live migration, packet-level loss analysis, congestion-window telemetry, Retry packet observation, QUIC version negotiation telemetry, packet-mark ECN visibility, packet-level spin-bit observation, and real QPACK inspection are still not fully implemented.
Bench mode produces cross-protocol comparisons.
Examples:
triton bench --target https://example.com --duration 3s --concurrency 4
triton bench --target https://example.com --protocols h1,h2,h3 --insecure --allow-insecure-tls
triton bench --target triton://loopback/ping --protocols h3 --duration 2s
triton probe --target triton://127.0.0.1:4433/ping --format jsonSpecification-level benchmark goals include:
- TTFB
- connection setup time
- request throughput
- download and upload bandwidth
- stream concurrency impact
- head-of-line blocking comparison
- migration and loss resilience
- memory and resource profiles
Current implementation note:
h1andh2bench runs work against normal HTTPS targetsh3bench runs work against normal HTTPS targets using real HTTP/3 and also againsttriton://...targetsh3://host:port/pathprobe targets use a real HTTP/3 client over QUICtriton://host:port/pathtargets use Triton's experimental UDP H3 transport- bench output now includes sampled latency percentiles (
p50,p95,p99), error-rate/error-summary data, and average request phases such as connect, TLS, first-byte, and transfer time - bench results now also include a computed
summaryrollup that classifies protocols as healthy/degraded/failed and highlights the best and riskiest protocol in the run - multi-protocol bench runs preserve partial protocol failures in the result summary when at least one protocol completes successfully
Check mode turns probe and bench into a reusable verification workflow.
Use it when you want one command that:
- loads named probe and bench profiles from config
- runs one or both checks against the same target family
- emits a combined verdict for CI or recurring operational gates
- optionally writes a combined report file
Examples:
triton check --profile production-edge
triton check --probe-profile production-edge --bench-profile staging-api --report-out reports/check.md
triton check --profile production-edge --summary-out reports/check-summary.json --junit-out reports/check-junit.xml
triton check --config triton.yaml --target https://example.comCurrent implementation note:
checkreuses the same underlyingprobeandbenchengines- threshold failures still persist results, but the command exits non-zero
- shared profile names let one command resolve both
probe_profiles.NAMEandbench_profiles.NAME
When there is a conflict between the long-term architecture vision below and the running code, prefer SUPPORTED.md, then ARCHITECTURE.md, then the generated audit docs under .project/.
The list immediately below is target-state architecture context from the specification, not a claim that all layers are complete in the current supported runtime.
The specification organizes Triton into these major layers:
- UDP socket layer
- custom QUIC engine
- TLS 1.3 integration
- HTTP/3 frame layer
- analytics engine
- embedded dashboard
- REST API + CLI
What exists in this repository today:
- CLI command routing
- config loading and validation
- filesystem-backed result persistence
- HTTPS test server with self-signed certificate generation
- dashboard asset/API scaffold
- tested QUIC packet helpers
- tested QUIC frame parsing and serialization
- stream manager and connection state skeleton
- loopback QUIC listener/dialer
- minimal H3
HEADERS + DATAlayer http.Handlerdispatch over the in-repo H3 loopback path
triton version,triton server,triton probe,triton bench,triton check- self-signed TLS certificate generation
- persisted probe and benchmark result storage under
triton-data/ - dashboard status and result listing API
- HTTP test endpoints over the HTTPS/TCP fallback path
- QUIC varint, packet number, and header parsing
- QUIC frame support for:
PADDINGPINGACK/ACK_ECNRESET_STREAMSTOP_SENDINGCRYPTONEW_TOKENSTREAMMAX_DATANEW_CONNECTION_IDRETIRE_CONNECTION_IDPATH_CHALLENGEPATH_RESPONSEHANDSHAKE_DONE
- stream lifecycle, reassembly buffer, and manager
- connection state transitions and frame dispatch
- loopback QUIC handshake-like path
- loopback stream payload exchange
- minimal H3 request/response dispatch
triton://loopback/...probe path using the in-process QUIC/H3 scaffold
- full RFC-complete QUIC transport
- crypto key schedule and packet protection
- real TLS-over-QUIC handshake
- QPACK encoder/decoder
- production-grade HTTP/3 server/client
- full analytics/qlog pipeline
- real network simulation and advanced benchmark runners
- ACME and advanced certificate automation
- dashboard real-time protocol visualization
0rtt: resumption timing and support signaling, not true 0-RTT early-data validationmigration: endpoint contract probing, not live path migrationqpack: estimated header-block-size analysis, not dynamic-table inspectionloss: request-error and timeout signal approximation, not packet-loss telemetrycongestion: latency-spread approximation, not congestion-window telemetryretry,version,ecn,spin-bit: observational approximations rather than packet-level transport visibility
go build ./cmd/tritongo run ./cmd/triton server
go run ./cmd/triton server --listen :4433 --allow-experimental-h3go run ./cmd/triton probe --target https://example.com --format jsongo run ./cmd/triton probe --target triton://loopback/ping --format jsongo run ./cmd/triton bench --target https://example.com --duration 3s --concurrency 4 --format jsongo run ./cmd/triton check --profile production-edge
go run ./cmd/triton check --profile production-edge --report-out reports/check.md
go run ./cmd/triton check --profile production-edge --summary-out reports/check-summary.json --junit-out reports/check-junit.xmltriton versiontriton server [flags]Important flags:
--config--listen(experimental Triton UDP H3 listener)--allow-experimental-h3--allow-remote-experimental-h3--allow-mixed-h3-planes--listen-h3(real HTTP/3 listener viaquic-go)--listen-tcp--cert--key--dashboard--dashboard-listen--allow-remote-dashboard--dashboard-user--dashboard-pass--max-body-bytes--access-log--trace-dir
triton lab [flags]lab runs the experimental Triton UDP H3 listener in isolation. It enables the experimental path, defaults the listener to 127.0.0.1:4433 when unset, and disables the normal HTTPS/dashboard surfaces so experimental work stays separated from the standard server profile.
triton probe --target <url> [flags]Important flags:
--config--target--format--tests--full--0rtt--migration--timeout--streams--insecure--allow-insecure-tls--trace-dir
Probe target schemes:
https://...uses the standard HTTP client path with HTTP/1.1 or HTTP/2 negotiationh3://...forces real HTTP/3 over QUICtriton://...uses Triton's in-repo experimental transport and typically expectstriton server --listen ... --allow-experimental-h3
triton bench --target <url> [flags]Important flags:
--config--target--format--duration--concurrency--protocols--insecure--allow-insecure-tls--trace-dir--profile--report-out--report-format- threshold flags such as
--threshold-max-error-rate
triton check [flags]Important flags:
--config--profile--probe-profile--bench-profile--target--format--report-out--report-format--summary-out--junit-out--skip-probe--skip-bench
The current mux is shared across HTTPS server mode and minimal H3 loopback tests.
curl -k https://localhost:8443/pingcurl -k https://localhost:8443/echo -X POST -d "hello"curl -k https://localhost:8443/status/204 -icurl -k https://localhost:8443/download/1024 --output /dev/nullAn example configuration is available at triton.yaml.example.
The intended configuration model from the specification includes:
- server listen addresses
- TLS settings
- dashboard settings
- QUIC transport settings
- rate limiting and logging
- probe defaults
- benchmark defaults
- storage retention and result limits
Current precedence model:
- CLI flags
- environment variables
- config file
- defaults
Recognized environment variable examples:
TRITON_SERVER_LISTENTRITON_SERVER_LISTEN_H3TRITON_SERVER_LISTEN_TCPTRITON_SERVER_TLS_CERTTRITON_SERVER_TLS_KEYTRITON_SERVER_DASHBOARD_USERTRITON_SERVER_DASHBOARD_PASSTRITON_SERVER_MAX_BODY_BYTESTRITON_SERVER_ACCESS_LOGTRITON_SERVER_TRACE_DIRTRITON_DASHBOARD_ENABLEDTRITON_PROBE_TIMEOUTTRITON_PROBE_ALLOW_INSECURE_TLSTRITON_PROBE_DEFAULT_STREAMSTRITON_PROBE_TRACE_DIRTRITON_BENCH_DEFAULT_DURATIONTRITON_BENCH_INSECURETRITON_BENCH_ALLOW_INSECURE_TLSTRITON_BENCH_TRACE_DIR
Current filesystem storage uses gzip-compressed JSON under triton-data/.
Structure:
triton-data/
├── benches/
├── certs/
└── probes/
Used today for:
- saved probe results
- saved benchmark results
- generated self-signed certificates
The embedded dashboard is currently a lightweight scaffold that serves:
- static UI assets
/api/v1/status/api/v1/config/api/v1/probes/api/v1/probes/:id/api/v1/benches/api/v1/benches/:id/api/v1/traces/api/v1/traces/:name
The UI now renders status/config snapshots plus typed summaries for recent probes, benches, and trace files instead of showing only raw JSON blobs, including a top-level overview panel, build/version status context, probe test-plan/skipped-test hints, 0rtt / migration probe summary hints, support-coverage pills, richer benchmark summary pills plus bench health rollups, and selected trace detail with preview and raw/meta links.
The dashboard also supports in-page filtering, sorting, offset-based pagination, and result limits for probe, bench, and trace lists via query-driven API calls.
List endpoints (/api/v1/probes, /api/v1/benches, /api/v1/traces) now accept q, sort, limit, and offset query parameters, and probe/bench list endpoints also support view=summary to omit heavier raw fields while keeping typed dashboard summaries.
It now includes a compare/trend panel that contrasts recent probe coverage and bench health/best-protocol latency across the latest runs.
Current hardening features:
- optional HTTP Basic Auth via
server.dashboard_user/server.dashboard_pass - remote dashboard binding requires explicit opt-in via
server.allow_remote_dashboardor--allow-remote-dashboard - remote dashboard binding also requires dashboard auth credentials
- remote dashboard binding also requires explicit
server.certandserver.key - experimental UDP H3 requires explicit opt-in via
server.allow_experimental_h3or--allow-experimental-h3 - non-loopback experimental UDP H3 binding additionally requires
server.allow_remote_experimental_h3or--allow-remote-experimental-h3 - enabling both
server.listen(experimental UDP H3) andserver.listen_h3(real HTTP/3) requiresserver.allow_mixed_h3_planesor--allow-mixed-h3-planes - defensive security headers on dashboard and HTTPS server responses
- bounded request body reads for
/echoand/upload - benchmark TLS verification enabled by default;
--insecureis now opt-in probe.insecure/bench.insecurenow also require explicitallow_insecure_tlsopt-in for lab use- request ID propagation and JSON access logs
- optional access log file output via
server.access_logor--access-log - qlog trace file output for real HTTP/3 connections via
server.trace_dir - client qlog trace output for real H3 probe and bench runs via
probe.trace_dir/bench.trace_dir
Long-term specification goals include:
- real-time SSE updates
- connection timeline views
- protocol comparison charts
- packet/frame inspection
- benchmark visualization
High-level current tree:
cmd/triton/ CLI entrypoint
internal/appmux/ Shared Triton HTTP handlers
internal/bench/ Benchmark scaffolding
internal/cli/ CLI parsing/output
internal/config/ Config defaults and loading
internal/dashboard/ Embedded dashboard scaffold
internal/h3/ Minimal H3 layer and loopback service
internal/probe/ Probe orchestration
internal/quic/ QUIC transport, packet, frame, connection, stream, wire helpers
internal/server/ Server orchestration and certificate management
internal/storage/ Filesystem persistence
The repository currently includes tests for:
- config validation
- storage save/load
- server endpoint behavior
- QUIC varint and packet number helpers
- QUIC header parsing
- QUIC frame parsing/serialization
- stream reassembly and manager behavior
- connection state transitions and frame dispatch
- loopback QUIC listener/dialer
- minimal H3 frame and header handling
- H3 handler dispatch
- Triton mux over H3 loopback
Run everything:
go test ./...Coverage note:
- generated coverage artifacts such as
coverage,coverage_review, andcoverage.outare local-only verification outputs and should not be committed
Specification targets:
- Linux
amd64,arm64 - macOS
amd64,arm64, universal - Windows
amd64,arm64 - single binary distribution
- Docker image
- future install script,
go install, and package manager support
Current local build helpers:
- Makefile
- Dockerfile
.github/workflows/ci.yml.github/workflows/release.yml- .goreleaser.yml
Current automation now includes:
- CI on pushes and pull requests for
gofmt,go test,go vet,staticcheck, and binary build verification - a dedicated CI
racejob that runsgo test -race ./...on a CGO-capable Linux runner - a dedicated CI
gosecpass for repo-wide security scanning - binary smoke verification covering
server,probe, health endpoints, and H3 loopback bench - tag-based release automation for
v*tags via GoReleaser - cross-platform archives for Linux, macOS, and Windows
Container runtime notes:
- the image now runs as non-root user
10001 - default command is
triton server - runtime state is expected under
/var/lib/triton - exposed ports cover supported HTTPS/TCP (
8443/tcp), supported real HTTP/3 (4434/udp), and dashboard (9090/tcp) - see OPERATIONS.md for persistence, cert, and remote-exposure guidance
Developer verification helpers:
make cleanmake testmake test-racemake test-fuzzmake perf-checkmake check-guardmake lintmake securitypwsh -File ./scripts/ci-local.ps1for local CI-style verification on Windows/PowerShellpwsh -File ./scripts/ci-local.ps1 -Raceto include race tests when a CGO toolchain is availablebash ./scripts/ci-smoke.shon bash-capable environmentspwsh -File ./scripts/ci-smoke.ps1on Windows/PowerShellbash ./scripts/ci-check-guard.shfor the combinedtriton checkCI gatepwsh -File ./scripts/ci-check-guard.ps1on Windows/PowerShell
Repository maintenance helper:
- GitHub maintenance is handled directly through standard repo workflows and CI scripts
High-value next steps from the specification and the current code trajectory:
- expand QUIC packet coverage beyond the current scaffold
- add packet protection and TLS key schedule
- implement richer stream and connection behavior
- add real H3 control streams and SETTINGS
- add QPACK
- connect the loopback H3 service to more runtime paths
- add a local H3 runner into bench mode
- add deeper probe modes on top of the in-repo transport
- improve dashboard observability
Project planning and product definition live under .project/:
- CONTRIBUTING.md
- API.md
- CONFIG.md
- OPERATIONS.md
- TROUBLESHOOTING.md
- SUPPORTED.md
- PRODUCTIONREADY.md
- ROADMAP.md
- SPECIFICATION.md
- IMPLEMENTATION.md
- TASKS.md
- ENGINE_STRATEGY.md
For current-state truth, start with SUPPORTED.md.
This repository is already more than a static scaffold, but it is still pre-v1 and mid-implementation relative to the full specification. The docs intentionally separate:
- the supported product path that exists today
- the future-looking target state described in the specification