Skip to content

Option to pause the periodic net report when no connection is open #4589

Description

@gjiovi-dev

For devices on metered or battery-powered links, the periodic net report is most of what an idle endpoint spends: a QAD round trip every 20–26 s plus the kept QAD connection's 25 s keep-alive, and a portmapper probe each run. With no connection open there's nothing that uses the fresh address or the warm NAT mapping.

remote_state.rs already has a commented-out SESSION_ACTIVE_TIMEOUT ("the idle time at which we stop doing QAD queries"), which suggests this was planned. Would a NetReportConfig::pause_when_idle (default false) be acceptable? When set: once a first report exists, periodic ticks are skipped while no connection is open, the
kept QAD connections are closed, and a report runs when a connection is dialled or accepted (and on network change, as today). We have it working in a fork and would adapt it to whatever shape you prefer, e.g. a time-based idle.

Details
  • Idle is "no open connection", counted where RemoteStateActor already counts
    num_conns_opened/num_conns_closed, shared across actors.
  • The first report always runs: it's what finds the home relay.
  • A dial (ResolveRemote) or a new connection while paused schedules a run with a
    new UpdateReason::Active; the handshake doesn't wait for it, and the new
    candidates reach the connection through the existing local-addrs watcher.
  • Closing the kept QAD connections takes the net reporter lock; it then signals
    run_done, so a run deferred meanwhile still starts.
  • Tests: socket::tests::test_net_report_pauses_while_no_connection_is_open (via a
    test-only ForcePeriodicTick, like ForceNetworkChange) and
    test_net_report_keeps_running_when_not_asked_to_pause. Both checked to fail when
    the pause or the resume is removed.

Activity

  1. added theissue type on Oct 8, 2026
  2. flub commented on Oct 8, 2026

    @flub
    Collaborator

    Yeah, we do want to work with less network connectivity and waking up. The tradeoff to make is being able to establish a direct connection faster. Likely several modes will be the right solution, because delaying QAD until you need it would result in a lot more relay traffic.

  3. daveey commented on Oct 14, 2026

    @daveey

    Another data point for the QAD re-probe cost from #4523, from a constrained device. This is an ESP32-S3 running iroh 1.2.0, and the endpoint has one live connection to our hub.

    Unpatched, every net report re-handshakes with each relay. We counted ~73 new QUIC packet keys/min (X25519 + SHA-256 HKDF on every handshake), and that was the main source of 300-900 ms stalls on the core that also feeds our audio stream. Seeding the QAD observer with the first report, the same two lines as #4524, brought it down to ~9 keys/min on the same device. Early soak numbers: 0 audio overruns, and the worst stall went from ~350 ms to ~115-300 ms.

    We're carrying that as a vendored patch for now. Would a minimal fix like this be acceptable before #4400 lands, or would you rather we wait for the refactor?

  4. flub commented on Oct 14, 2026

    @flub
    Collaborator

    @daveey what minimal fix do you have in mind? A hotfix that does not affect the public API would be nice option. However the suggestion of adding a new public API is more problematic because we can't remove it again once we have a proper solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    • Status
      🚑 Needs Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions