Skip to content

Enable HTTP/2 multiplexing on relay-directory hop#1655

Merged
spacebear21 merged 1 commit into
payjoin:masterfrom
spacebear21:relay-directory-h2-multiplexing
Jun 19, 2026
Merged

Enable HTTP/2 multiplexing on relay-directory hop#1655
spacebear21 merged 1 commit into
payjoin:masterfrom
spacebear21:relay-directory-h2-multiplexing

Conversation

@spacebear21

Copy link
Copy Markdown
Collaborator

The relay's outbound client and the directory's ACME server now negotiate HTTP/2, so a relay's concurrent forwarded requests multiplex over one connection instead of pinning one directory file descriptor each.

Note that HTTP/2 over TLS is selected by ALPN during the TLS handshake. So multiplexing only reaches the mailroom if the process that the relay's TLS connection terminates against negotiates h2. payjo.in runs direct ACME on port 443, so this change is sufficient to multiplex relay -> directory in production with no proxy change.

The multiplexing_tests are more of a demo than real unit tests so I'm leaving this PR in draft with those included until we agree on an approach, then I think these can be dropped.

co-authored by Claude Opus 4.8

Pull Request Checklist

Please confirm the following before requesting review:

@spacebear21 spacebear21 mentioned this pull request Jun 17, 2026
2 tasks
@spacebear21
spacebear21 force-pushed the relay-directory-h2-multiplexing branch from 530deba to 4bb5d84 Compare June 17, 2026 20:43
@coveralls

coveralls commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

Coverage Report for CI Build 27794494492

Coverage decreased (-0.01%) to 85.213%

Details

  • Coverage decreased (-0.01%) from the base build.
  • Patch coverage: 4 uncovered changes across 1 file (1 of 5 lines covered, 20.0%).
  • 1 coverage regression across 1 file.

Uncovered Changes

File Changed Covered %
payjoin-mailroom/src/lib.rs 4 0 0.0%
Total (2 files) 5 1 20.0%

Coverage Regressions

1 previously-covered line in 1 file lost coverage.

File Lines Losing Coverage Coverage
payjoin-mailroom/src/lib.rs 1 67.67%

Coverage Stats

Coverage Status
Relevant Lines: 14749
Covered Lines: 12568
Line Coverage: 85.21%
Coverage Strength: 370.23 hits per line

💛 - Coveralls

@DanGould

Copy link
Copy Markdown
Member

I was under the impression that multiplexing would have been much more complicated than a dependency update and a 4-line change (excluding tests). This approach seems like the right one.

Some way to benchmark and stress test simulated network activity might be something we want sooner than later. @pseudozach mentioned load testing and benchmarks last week.

@nothingmuch

Copy link
Copy Markdown
Contributor

I was under the impression that multiplexing would have been much more complicated than a dependency update and a 4-line change (excluding tests).

thank you for taking the time to read my various posts on this.

Under BIP-77 the directory only sees peer relays, and each waiting
receiver is a long-poll the relay holds open. The relay's outbound
client and the directory's ACME server path negotiated HTTP/1.1 only,
which carries one request per connection at a time. A single busy
relay therefore pinned one directory file descriptor per concurrent
long-poll and could exhaust the descriptor limit on its own.

HTTP/2 multiplexes concurrent requests over a single connection,
decoupling in-flight requests from connection (descriptor) count. Offer
h2 on the relay's hyper-rustls client, which negotiates via ALPN and
falls back to HTTP/1.1 for gateways that do not support it, and
advertise h2 in the ACME server's ALPN, since tokio-rustls-acme
otherwise sets only the acme-tls/1 challenge protocol.
@spacebear21
spacebear21 force-pushed the relay-directory-h2-multiplexing branch from 4bb5d84 to a86a499 Compare June 18, 2026 22:59
@spacebear21

spacebear21 commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator Author

I've removed the integration tests since the intention was just to demo that this change collapses the number of connections. I think this is mergeable as-is

@spacebear21
spacebear21 marked this pull request as ready for review June 18, 2026 23:01
@pseudozach

pseudozach commented Jun 19, 2026

Copy link
Copy Markdown

fwiw I did a quick load test against payjoin-mailroom to see the impact of this HTTP/2 multiplexing change on FD usage using h2load

  • Monitored process FDs via /proc//fd
  • Monitored TCP sockets via ss -tanp

Baseline (before this PR, current master):
h2load --h1 -n 1000 -c 1000 'http://<mailroom>:8900/https://example.com'

Observed:
FDs: 10 -> 1001 peak
TCP: 1 -> 940 peak

With this PR:
h2load -n 1000 -c 1 -m 1000 'http://<mailroom>:8900/https://example.com'

Observed:
FDs: 11 -> 12 peak
TCP: 2 -> 3 peak

So for the same 1000-request workload, multiplexing stopped FD growth which kinda makes sense but I thought it's good to prove it/see it regardless.
let me know if I can help with anything else or any other test that might be helpful.

@spacebear21
spacebear21 requested a review from benalleng June 19, 2026 00:53

@benalleng benalleng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TACK a86a499
confirmed similar result with h2load
master peak_descriptors=1004
this branch peak_descriptors=3

We can followup with select commits from #1608 as this will ultimately supersede most of that approach

@spacebear21
spacebear21 merged commit 5217f29 into payjoin:master Jun 19, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants