#5787·undici

Support maxRequestsPerClient for HTTP/2 sessions

Author: johnlyonmsCreated Sep 8, 2026Updated Sep 10, 2026
Labelsenhancement

This would solve...

maxRequestsPerClient currently limits the number of requests sent over an HTTP/1.1 connection, but it does not appear to apply after HTTP/2 is negotiated.

The option is documented as:

The maximum number of requests to send over a single connection before the socket is reset.

In Undici 8.10.0, the request counter is enforced in client-h1.js. The HTTP/2 implementation does not import or use kMaxRequests.

This means applications using allowH2 cannot place a request-count lifetime on an HTTP/2 session. We encountered a case where an HTTP/2 session remained logically reusable after its transport stopped making progress. Subsequent requests continued selecting that session. Periodically retiring a session after a bounded number of requests would provide useful defense in depth and limit how long unhealthy or stale sessions can be reused.

The implementation should look like...

When HTTP/2 is negotiated and maxRequestsPerClient is a positive number:

  • Count requests/streams opened on the current HTTP/2 session.
  • Once the limit is reached, stop assigning new requests to that session.
  • Allow existing streams to complete, then gracefully retire the session.
  • Establish a new session for queued or subsequent requests.
  • Preserve the existing null/0 behavior that disables the limit.

The exact behavior around concurrent streams could follow maintainer guidance—for example, whether the limit is strict or may be exceeded by streams already opened concurrently.

I have also considered...

  • Rotating the dispatcher in application code after request timeouts. This works as a reactive mitigation, but requires applications to own dispatcher lifecycle and duplicate session-health logic.
  • HTTP/2 PING frames. These help with liveness detection but do not provide a bounded session lifetime.
  • A separate HTTP/2-specific option. That would be workable, but extending maxRequestsPerClient seems consistent with its documented connection-level semantics.

Additional context

Environment where this was observed:

  • Node.js 24
  • Undici 8.10.0
  • HTTP/2 enabled with allowH2

I would be happy to help test the behavior or contribute a change with guidance on the preferred HTTP/2 retirement semantics.