HAProxy doesn’t just enable HTTP/2; it rewrites your HTTP/1.1 requests into HTTP/2 for the backend, and then back to HTTP/1.1 for the client if the client doesn’t support HTTP/2.
Let’s see HAProxy in action, managing a simple frontend and backend.
frontend http_frontend
bind *:80
bind *:443 ssl crt /etc/ssl/certs/mycert.pem alpn h2,http/1.1
default_backend http_backend
backend http_backend
server app1 192.168.1.10:80 check
server app2 192.168.1.11:80 check
Here’s what’s happening:
frontend http_frontend: This section defines how HAProxy listens for incoming connections.bind *:80: This line tells HAProxy to listen on port 80 for plain HTTP traffic.bind *:443 ssl crt /etc/ssl/certs/mycert.pem alpn h2,http/1.1: This is where the magic for HTTPS and HTTP/2 happens.*:443: Listen on port 443 for HTTPS traffic.ssl crt /etc/ssl/certs/mycert.pem: Enable SSL/TLS and specify the certificate file. You’ll need to replace/etc/ssl/certs/mycert.pemwith the actual path to your certificate and private key file (often a combined.pemfile).alpn h2,http/1.1: This is the Application-Layer Protocol Negotiation (ALPN) extension for TLS. It tells clients that HAProxy supports both HTTP/2 (h2) and HTTP/1.1 (http/1.1). The order matters:h2is preferred. When a client connects via HTTPS, it will negotiate which protocol to use based on this list. If the client supportsh2, HAProxy will speak HTTP/2 with it.
default_backend http_backend: Any traffic hitting this frontend will be directed to thehttp_backendunless specific rules say otherwise.backend http_backend: This section defines the group of servers that will handle the requests.server app1 192.168.1.10:80 check: Defines a backend server namedapp1at IP192.168.1.10on port80. Thecheckdirective means HAProxy will periodically ping this server to ensure it’s healthy.server app2 192.168.1.11:80 check: Defines another backend server.
When a client connects to https://yourdomain.com (port 443), it performs a TLS handshake. During this handshake, the client and HAProxy negotiate the application protocol using ALPN. If the client offers h2 and HAProxy supports it (as specified by alpn h2,http/1.1), they will establish an HTTP/2 connection. HAProxy then rewrites the HTTP/2 frames into HTTP/1.1 requests and forwards them to your backend servers. The responses from the backend (which will be HTTP/1.1) are then rewritten back into HTTP/2 frames by HAProxy before being sent to the client.
If the client does not support HTTP/2 or HAProxy’s ALPN list didn’t include h2, they would fall back to http/1.1.
The real power of HAProxy here is its ability to act as a protocol translator. Your backend servers can remain on HTTP/1.1, simplifying their configuration and development, while you can offer the performance benefits of HTTP/2 to modern clients. This is achieved by HAProxy’s internal handling of the protocol negotiation and conversion.
What most people miss is that HAProxy’s HTTP/2 support is primarily for downstream communication (client to HAProxy) and upstream conversion (HAProxy to backend). It doesn’t mandate that your backend servers must speak HTTP/2. This allows for a gradual adoption of HTTP/2 without requiring immediate upgrades of all your application servers.
The next hurdle is understanding how to leverage HTTP/2’s multiplexing and header compression for even finer-grained control.