warpgate / netstats public infrastructure monitor
source www.warpgate.io/servers.json
next
live

Live list of public STUN, TURN, MQTT and NTP servers

Every server is re-checked every four hours and scored on how reliably it answers. Filter it below, download it, or fetch it from your own code — free, no key.

Server groups

— groups

Address families

ipv4 + ipv6
total servers
unique hosts
tier-1 reachable
degraded / unknown
unreachable

Servers

address family
transport
status
group host port af region latency status uptime 7d
fetching the server list…

Use this list

The list this page draws is public JSON. No key, no sign-up, and CORS is open, so it can be fetched from a browser as easily as from a server.

Endpoints

https://www.warpgate.io/servers.json

Use this one. It is plain HTTPS on the standard port, so it gets through networks that block everything but 80 and 443.

https://warpgate.io:8001/servers
http://ovh1.p2pd.net:8000/servers

The same file, served from the monitor's own ports, for software that already uses them. The plain HTTP one will not load from an HTTPS page. All three send gzip to clients that ask for it.

Be kind to it

The list is rebuilt every minute, but each server is only re-checked every four hours, so fetching more often than every few minutes gets you nothing new.

Both endpoints send an ETag. Send it back as If-None-Match and an unchanged list costs a few hundred bytes instead of the whole thing.

Quick start

curl, re-using the ETag — the second run prints 304 if nothing changed
curl -s -o servers.json --etag-save etag.txt --etag-compare etag.txt \
     -w '%{http_code}\n' https://www.warpgate.io/servers.json
Python, standard library only
import json, urllib.request

servers = json.load(urllib.request.urlopen("https://www.warpgate.io/servers.json"))

# best-scoring public STUN servers over IPv4/UDP
for group in servers["STUN(see_ip)"]["IPv4"]["UDP"][:5]:
    s = group[0]
    print(s["ip"], s["port"], round(s["score"], 3))
JavaScript, in a browser or Node 18+
const servers = await (await fetch("https://www.warpgate.io/servers.json")).json();
const ntp = servers.NTP.IPv4.UDP.map(group => group[0]);

What is in it

Servers are nested by kind, address family and transport:

{
  "STUN(see_ip)":   { "IPv4": { "UDP": [ [server], ... ], "TCP": [...] }, "IPv6": {...} },
  "STUN(test_nat)": { ... },
  "MQTT": { ... },  "TURN": { ... },  "NTP": { ... },
  "timestamp": 1789262981
}

Each list is sorted best score first. Every entry in it is itself a small list of servers that belong together — nearly always one. For STUN(test_nat) it is four: the two addresses and two ports of one RFC 3489 server, which only works as a set. STUN(see_ip) servers tell a client its public address; STUN(test_nat) servers can also tell it what kind of NAT it is behind.

fieldmeaning
ip, portwhere to reach it
fqnshost names that resolved to this address
score0 to 1. Rewards passing checks and unbroken uptime, and only climbs as history builds up, so a newly added server starts low
test_no, failed_testschecks run, and how many of them failed
uptime, max_uptimeseconds of the current, and the longest, unbroken run of passing checks
last_successUnix time it last answered. A server silent for 14 days stops being checked, so this is the field that says a listing has gone stale
af2 is IPv4, 10 is IPv6
proto2 is UDP, 1 is TCP
type3 STUN address lookup, 4 STUN NAT test, 5 MQTT, 6 TURN, 7 NTP
user, passwordcredentials for TURN servers that need them
id, status_id, group_id, alias_id, table_typethe monitor's own bookkeeping — don't rely on these

How it is made

The list comes from dogdorm, an open-source monitor that actively probes each server: STUN binding and change requests, TURN allocation, MQTT connections and NTP queries. It exists to keep warpgate's NAT traversal working on public infrastructure, and is published because a list that is actually checked is useful to anyone building peer-to-peer software.

Run your own dogdorm and this page will draw it too: use change at the top, or add ?src= to the address.