burl supports multiple HTTP protocol versions. This guide covers when and how to use each.
By default, burl uses automatic protocol negotiation:
# Auto-negotiate (default)
burl https://api.example.com
Force HTTP/1.1 with --http1:
burl https://api.example.com --http1
| Feature | HTTP/1.1 |
|---|---|
| Connections | One request per connection at a time |
| Head-of-line blocking | Yes (at connection level) |
| Header compression | No |
| Server push | No |
| Multiplexing | No |
Force HTTP/2 with --http2:
burl https://api.example.com --http2
| Feature | HTTP/2 |
|---|---|
| Connections | Multiple streams per connection |
| Head-of-line blocking | Yes (at TCP level) |
| Header compression | Yes (HPACK) |
| Server push | Yes |
| Multiplexing | Yes |
HTTP/3 support is experimental and may not work with all servers.
Force HTTP/3 with --http3:
burl https://api.example.com --http3
| Feature | HTTP/3 |
|---|---|
| Transport | QUIC (UDP-based) |
| Head-of-line blocking | No |
| Header compression | Yes (QPACK) |
| Connection migration | Yes |
| 0-RTT | Yes |
Run benchmarks with different protocols to compare:
#!/bin/bash
URL="https://api.example.com/users"
echo "HTTP/1.1:"
burl "$URL" --http1 -c 50 -d 30s -f json | jq '{
protocol: "HTTP/1.1",
rps: .summary.requests_per_second,
p99: .latency_ms.p99
}'
echo -e "\nHTTP/2:"
burl "$URL" --http2 -c 50 -d 30s -f json | jq '{
protocol: "HTTP/2",
rps: .summary.requests_per_second,
p99: .latency_ms.p99
}'
echo -e "\nHTTP/3:"
burl "$URL" --http3 -c 50 -d 30s -f json | jq '{
protocol: "HTTP/3",
rps: .summary.requests_per_second,
p99: .latency_ms.p99
}' 2>/dev/null || echo "HTTP/3 not supported"
If HTTP/2 doesn't work:
curl -I --http2 https://api.example.com 2>&1 | grep -i "http/2"
openssl s_client -alpn h2 -connect api.example.com:443 </dev/null 2>&1 | grep "ALPN"
If HTTP/3 doesn't work:
curl -I https://api.example.com 2>&1 | grep -i "alt-svc"
nc -vzu api.example.com 443