Back to Home

HTTP/2 and HTTP/3 in Angie: configuration and performance

The article details the technical configuration of HTTP/2 and HTTP/3 in the Angie web server. It covers key directives, stream limitations, QUIC features, TLS 1.3 and OpenSSL requirements, network conditions for HTTP/3, support announcement mechanisms, and performance monitoring methods.

HTTP/2 and HTTP/3 in Angie: how to configure without errors
Advertisement 728x90

HTTP/2 and HTTP/3 in Angie: Technical Configuration, Pitfalls, and Performance

Angie is a modern, high-performance web server with native support for HTTP/2 and HTTP/3. Unlike Nginx, its implementation of these protocols includes BPF acceleration, kernel-level QUIC optimizations, and integration with upstream servers over UDP. This article focuses not on theory but on practical aspects of enabling, fine-tuning, and troubleshooting common issues in production environments—ranging from HOL blocking to DoS vulnerabilities in multiplexed connections.

Why HTTP/2 and HTTP/3 Require a Special Approach in Angie

The key difference between traditional servers and Angie isn’t just the presence of features—it’s how they’re architected around the processing model. In HTTP/1.1, each TCP socket is handled by a separate worker process, which naturally distributes the load. HTTP/2 and HTTP/3 break this pattern: a single client establishes one long-lived connection (a QUIC connection or a TLS session with ALPN), which is entirely processed by a single worker process. This boosts efficiency at low latencies but creates hotspots when traffic is highly concentrated. This is especially critical for HTTP/2: if http2_max_concurrent_streams is set to 1024 and a client opens 900 streams, all that client’s traffic will pass through a single process—even with 8 CPU cores. In HTTP/3, the situation is even more complex: while a QUIC connection can migrate between interfaces, Angie’s current implementation doesn’t redistribute the load across workers during migration—it keeps the connection tied to the original process.

Moreover, Angie doesn’t just enable these protocols; it applies system-level optimizations unavailable in Nginx. For example, quic_bpf on activates eBPF programs to filter and preprocess QUIC packets in the kernel space, reducing context switches. And quic_gso on enables Generic Segmentation Offload at the network stack level—crucial for lowering CPU load when transmitting large objects (such as video fragments or WebAssembly bundles).

Google AdInline article slot

Key HTTP/2 Parameters: From Security to Performance

Configuring HTTP/2 in Angie goes beyond simply setting http2 on. Three groups of parameters have a real impact on stability and security:

1. Stream and Resource Limits

  • http2_max_concurrent_streams isn’t just a limit—it’s a factor in load distribution. The default value of 128 works well for moderately dynamic web applications. For API gateways with many long-polling connections, it’s recommended to reduce it to 64 to avoid overloading a single worker.
  • http2_max_requests sets the maximum number of requests per connection. The default is 1000. Setting it to 0 disables the limit, but that’s risky: a client could hold a connection indefinitely, exhausting the worker_connections limit.
  • http2_idle_timeout defines how long an idle connection stays active. The standard value of 3 minutes can be increased to 5 minutes for mobile clients with unstable LTE, but no more—otherwise, the risk of DoS attacks via “zombie connections” rises.

2. Buffering and Chunk Sizes

Google AdInline article slot
  • http2_chunk_size controls the size of response chunks. A value of 8 KB strikes a balance between latency and throughput. For media content (MSE/DASH), it makes sense to increase it to 64 KB, though this reduces flexibility in prioritization.
  • http2_recv_buffer_size adjusts the buffer for incoming data. Increasing it beyond the default 128 KB rarely improves performance but does raise memory usage per connection.
  • http2_body_preread_size specifies how much data is read before the handler starts. This is critical for middleware that inspects request bodies (e.g., WAF filtering). It’s recommended to set it to 64 KB for JSON APIs and 1 MB for file uploads.

3. Disabling Legacy Features

Server Push has been removed from Angie’s codebase—not because of a configuration error, but as a deliberate decision. Any attempt to use http2_push or http2_push_preload will result in a config parsing error. This eliminates the classic caching problem: push resources can’t be conditionally delivered and often duplicate data already cached by the client.

Configuring HTTP/3: QUIC, TLS 1.3, and Network Readiness

Enabling HTTP/3 in Angie requires three levels of preparation: library, network, and DNS infrastructure.

Google AdInline article slot

Libraries and TLS

A mandatory requirement is OpenSSL ≥ 1.1.1 for basic HTTP/3 and ≥ 3.5.1 for 0-RTT. However, the OpenSSL version doesn’t guarantee compatibility: some distributions (e.g., RHEL 9.3) use an openssl-fips fork that doesn’t support QUIC extensions. You can verify this with the command:

angie -V 2>&1 | grep -i quic

If the output is empty, QUIC was disabled during compilation.

Network Requirements

UDP/443 must be open not only in the firewall but also on all intermediate devices: L4 load balancers, DDoS protection systems, and SD-WAN gateways. QUIC uses variable-length packets, and many stateful filters block packets larger than 1500 bytes without explicit permission. You should also disable PMTU Discovery at the kernel level (net.ipv4.ip_no_pmtu_disc = 1)—otherwise, fragmentation on the client side will lead to packet loss.

Announcement Mechanisms

Angie supports two ways of informing clients about HTTP/3:

  • Alt-Svc Header—the standard and most compatible option. Here’s an example configuration:
add_header Alt-Svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400';

Here, ma=86400 is the lifetime of the announcement in seconds. It’s not recommended to set ma=0 to “disable” it—the client will ignore such a header.

  • HTTPS Records in DNS—requires client support (Chrome ≥ 117, Safari ≥ 17) and proper DNSSEC configuration. The record format is:
_https.example.com. IN HTTPS 1 . alpn="h3,h3-29" port=443

Both methods can be combined: clients that support DNS announcements use them, while others rely on Alt-Svc.

What Matters

  • HTTP/2 and HTTP/3 in Angie create a single connection per client, fully tied to one worker process—this requires revisiting the limits for worker_connections and events { use epoll; }.
  • Server Push has been permanently removed from Angie—any mention in the config will cause a parsing error.
  • For HTTP/3, TLS 1.3 support is mandatory, but not all OpenSSL builds include it—check with angie -V.
  • QUIC connections require UDP/443 to be open at every network level, including L4 load balancers and DDoS systems.
  • quic_bpf on and quic_gso on are key optimizations that reduce CPU load by 15–22% when transferring >100 Mbps.

Performance and Monitoring in Production

Assessing the effectiveness of HTTP/2/3 is impossible without metrics at the connection level. Angie provides the following internal log variables:

  • $http2—1 if the connection uses HTTP/2, otherwise empty;
  • $http3—1 for HTTP/3;
  • $quic_version—the QUIC version (e.g., ff00001d);
  • $bytes_sent and $request_length—allow you to calculate protocol-level overhead.

To analyze HOL blocking, use a graph showing the relationship between request_time and http2_stream_id: a sharp rise in time at high stream IDs indicates queuing delays. In HTTP/3, this effect doesn’t occur—each stream is processed independently.

When conducting load tests with wrk or hey, always specify the -H "Connection: keep-alive" and -H "Accept-Encoding: gzip, br" flags; otherwise, the tests will emulate HTTP/1.1 behavior. For HTTP/3, use hey -h3 or curl --http3.

A common mistake is relying solely on ab (ApacheBench): it doesn’t support HTTP/2 or HTTP/3, so the results will be skewed.

— Editorial Team

Advertisement 728x90

Read Next