host, srflx, relay. Three words that decide whether your WebRTC call connects. Step through how a browser gathers every possible path and how ICE picks the winner.
When your browser wants to connect to another browser, it does not know in advance which network path will work. So it does something pragmatic: it lists every path it can possibly imagine, sends that list to the other side, and then both ends test all the combinations until one succeeds. Each entry in that list is an ICE candidate, and ICE stands for Interactive Connectivity Establishment.
A raw candidate looks like this: candidate:1 1 UDP 2122260223 192.168.1.20 54321 typ host. The important part is at the end. The typ field tells you which kind of candidate it is, and that single word explains most WebRTC connection problems.
A host candidate is an address on one of your device's own interfaces. If you are on Wi-Fi it might be 192.168.1.20. These have the highest priority because if both peers are on the same network, a direct local path is the fastest possible route and costs nothing. In a modern browser you will usually see something like a1b2c3d4.local instead of the real IP, because browsers now hide private addresses behind mDNS names to stop websites fingerprinting your home network.
Server reflexive candidates come from asking a STUN server what your public address looks like from outside. This is the candidate that makes internet calls possible, because it is an address the other peer can actually route to. If you gather no srflx candidates at all, STUN is blocked or unreachable and direct connections from that network will fail.
Relay candidates are addresses allocated on a TURN server. They only appear if you configured TURN with working credentials. They have the lowest priority in ICE because every media packet has to travel through that server, which costs you bandwidth and adds a hop of latency. ICE treats relay as the fallback of last resort, which is exactly right.
Once both sides have exchanged candidates, ICE forms every possible pairing of local and remote candidates and runs connectivity checks on them, in priority order. Each check is a STUN request sent along that path. If a reply comes back, the pair works. ICE keeps the highest priority pair that succeeded and nominates it, and media starts flowing. Everything else is discarded. This is why a call can take a moment to connect: it is quietly trying many paths at once.
This diagram is part of Sazrika Foundation. Gather your real candidates with the ICE Candidate Inspector, read the companion diagram on STUN vs TURN, or decode an offer with the SDP Analyzer.