Candidate Gathering Latency and the Mechanics of Trickle ICE
By Nadia Ferrante
Interactive Connectivity Establishment (ICE), standardized in RFC 8445, provides the baseline state machine for NAT traversal in real-time communications. In its original formulation, an ICE agent was expected to complete the gathering of every local, server reflexive, and relayed candidate before generating a Session Description Protocol (SDP) offer or answer. For voice systems operating under strict latency budgets, this blocking approach degrades call setup time.
The extension known as Trickle ICE, specified in RFC 8838, addresses this gathering tax by decoupling the candidate discovery process from the initial signaling exchange. This document details the underlying state transitions, the network overhead imposed by pre-gathering, and the specific failure profiles that emerge when transmitting media over non-converged candidate pairs.
What does the Vanilla ICE Gathering Model and Setup Delays actually mean?
The vanilla ICE model assumes a strict phase ordering: candidate gathering, offer/answer exchange, connectivity checks, nomination, and media flow. Gathering all transport addresses before generating the initial SDP message creates a latency floor that no downstream optimization can recover.
"The original Interactive Connectivity Establishment (ICE) specification [RFC5245] required an agent to complete the entire candidate gathering phase before sending the initial offer or answer." — RFC 8838, Section 1.
The Serialized Gathering Bottleneck
When an endpoint initializes an ICE agent without trickling, it must interrogate every available physical and virtual network interface. Host candidates are gathered almost instantaneously via local operating system socket queries (getsockname or Netlink sockets on Linux). However, server reflexive and relayed candidates depend entirely on network I/O with remote infrastructure.
To obtain server reflexive candidates, the client sends Session Traversal Utilities for NAT (STUN) Binding Requests to a configured STUN server, as specified in RFC 5389. This involves: 1. DNS resolution for the STUN server hostnames (typically an A and AAAA query per server). 2. Transmission of the STUN Binding Request UDP datagram. 3. Waiting for the STUN Binding Response containing the XOR-MAPPED-ADDRESS attribute.
Relayed candidates gathered via Traversal Using Relays around NAT (TURN), defined in RFC 8656, are more costly. The client must execute a full Allocate transaction. If authentication is enabled—which is the case in production deployments—the initial Allocate request returns a 401 Unauthorized response with a nonce and realm. The client must then compute a message integrity digest over the credentials and transmit a second Allocate request.
If the STUN or TURN servers are situated 40 ms away (a round-trip time of 80 ms), the TURN allocation alone consumes a minimum of 160 ms of network transit time, assuming zero packet loss and immediate processing. If IPv6 is present alongside IPv4, or if multiple network interfaces exist (such as an active Wi-Fi interface and an active LTE/5G interface), this gathering phase executes concurrently or serially across all interfaces. In environments with slow or timing-out DNS resolvers, gathering frequently blocks for 1200 ms to 3000 ms before an SDP offer can be formatted.
Pacing Timers and Retransmission Delays
STUN retransmissions introduce heavy tail latency when endpoints pre-gather. RFC 5389 specifies an initial Retransmission TimeOut (RTO) of 500 ms for UDP transactions, doubling for each subsequent attempt (binary exponential backoff: 500 ms, 1000 ms, 2000 ms). If a single UDP datagram directed to a STUN server is dropped, the vanilla ICE agent remains blocked in the gathering phase for at least 500 ms while awaiting the timer expiry.
A standard STUN transaction aborts after 7 consecutive unacknowledged requests, spanning a total window of 39.5 s. While most application-level implementations apply an internal cap on gathering time—often between 2000 ms and 5000 ms—the call setup cannot proceed until either that timer fires or all transactions complete. Holding the initial SIP INVITE or WebSockets signaling message until the gathering timeout clears creates an unacceptable user experience, as ring delays directly degrade perceptual call quality.
What does mechanics of Incremental Candidate Exchange actually mean?
Trickle ICE eliminates the gathering gate by permitting the ICE agent to transmit an offer containing only a subset of candidates—frequently just the host candidates, or an empty candidate list containing only a default dummy transport address—and streaming additional candidates over the signaling path as they are discovered.
Incremental State Machine and Candidate Pairing
In a Trickle ICE session, the agent initializes the ICE checklist as soon as the answer arrives, even if only host candidates are available on both sides. The ICE checklist consists of candidate pairs formed by taking the Cartesian product of local and remote candidates:
$$\text{Pair} = (Local, Remote)$$
As subsequent candidates arrive via out-of-band signaling messages, the ICE agent inserts them into the existing checklist dynamically. Every pair is assigned a state: FROZEN, WAITING, IN-PROGRESS, SUCCEEDED, or FAILED. The priority of each pair is computed using the formula defined in RFC 8445:
$$\text{Priority} = 2^{32} \times \min(P_o, P_a) + 2 \times \max(P_o, P_a) + (P_o > P_a ? 1 : 0)$$
where $P_o$ is the priority of the candidate provided by the controlling agent, and $P_a$ is the priority provided by the controlled agent.
` +------------+ +-----------+ +---------------+
| FROZEN | ----> | WAITING | ----> | IN-PROGRESS |
|---|