Running an NTP Pool Server: Operator Guide & Retrospective
The NTP Pool (pool.ntp.org) is the time-synchronisation infrastructure that, without them knowing it, underpins most of the consumer Internet: home routers, smartphones, IoT devices, and a large portion of Linux distributions by default. This network of over 4,000 servers is 100% volunteer-based, coordinated since 2003 by Ask Bjørn Hansen and a handful of contributors.
Our Why Contribute to the NTP Pool page covers the reasons to join the project. This one is the practical follow-up: how to run a pool server in 2026, pitfalls encountered, and what to size for load. RDEM Systems has operated pool-registered servers for several years — a significant share under its own AS206014, others on third-party transits.
1. Technical prerequisites before registering
Before any registration, the server must tick four boxes:
- Static public IP address (IPv4; IPv6 strongly recommended). The
2.pool.ntp.organd3.pool.ntp.orgzones are statistically AAAA-richer: contributing over IPv6 there has disproportionate impact. See also our NTP IPv6 test guide. - UDP port 123 open bidirectionally at the firewall and ISP side, without aggressive rate-limits. Some consumer ISPs filter inbound NTP traffic — an external test is essential. Our sister site covers opening UDP/123 correctly (no rebound) on iptables, firewalld, ufw and Windows Firewall.
- Stable upstream synchronisation from at least 4 quality sources (reliable Stratum 1 or Stratum 2). Local offset must stay under 10 ms in steady state, ideally under 1 ms. Our Raspberry Pi + GPS retrospective documents the minimum viable build for a personal Stratum 1.
- 24/7 server with monitoring. A server that frequently goes down will see its score drop and will be automatically excluded from the pool during outages. Set up alerts on offset > 100 ms and on unreachable.
2. Registering on manage.ntppool.org
Registration is free and takes five minutes:
- Create an account on the NTP Pool admin panel (manage.ntppool.org).
- Add a server by its public IP (no hostname — the pool queries the IP directly). IPv4 and IPv6 are managed separately: two registrations for one dual-stack server.
- Choose geographic zones the server will serve. By default, the pool assigns the country zone
of the IP. A European operator can extend to
europeandglobal. - Set the net speed — bandwidth you offer. Do not overestimate: 100 Mbit/s actually delivered beats 1 Gbit/s announced but unserved.
- Allow 24–48 hours for monitors to establish an initial score. Below positive score, the server does not yet receive real traffic.
3. Understanding the scoring system
Several geographically distributed monitors (Europe, Americas, Asia, Oceania) query each registered server every 10–20 minutes. Each query produces a score increment based on the response:
| Result | Score impact | Typical cause |
|---|---|---|
| OK, offset < 75 ms | +1 (progressive toward +20) | Normal operation |
| OK, offset 75–400 ms | Slight penalty | Server under load or degraded WAN |
| Offset > 400 ms | −4 | Broken local sync, mishandled leap second |
| Timeout / no response | −5 | Firewall, server down, net speed exceeded |
| Stratum 16 announced | −5 | Unsynchronised daemon at the operator |
Global score ranges from −100 (banned) to +20 (excellent).
A server with score above +10 is included in pool DNS responses proportionally
to its net speed. Score is public at ntppool.org/scores/<IP> and helpful for
diagnosing regressions.
The pool tolerates temporary dips (maintenance, reboot) without immediate exclusion. But a score drop below +10 removes the server from DNS responses until recovery.
4. Sizing bandwidth and the "net speed"
The declared net speed drives the volume of requests the pool directs to the server proportionally. Five levels:
| Net speed | Typical req/s | Average outbound bandwidth | Operator profile |
|---|---|---|---|
| 1 Mbit/s | < 50 | < 4 kbit/s | Individual, residential connection |
| 10 Mbit/s | 50–200 | 4–16 kbit/s | Small hosted VPS |
| 100 Mbit/s | 500–2,000 | 40–160 kbit/s | Pro infrastructure, comfortable VPS |
| 500 Mbit/s | 2,500–10,000 | 200 kbit/s–1 Mbit/s | Datacentre, dedicated bandwidth |
| 1,000 Mbit/s | 5,000–20,000 | 500 kbit/s–2 Mbit/s | Operator with dedicated link + serious CPU |
An NTP packet is 90 bytes at UDP level (48-byte payload + 8 UDP + 20 IPv4 + optional headers). In practice, CPU load remains negligible even at 20,000 req/s on one modern core. The real sizing is bandwidth and link quality: a network with stable latency helps the pool more than a beefy server behind a jittery connection.
5. chrony configuration in public-server mode
The choice between chrony and ntpd for a public server is structural — see which daemon to pick for a public server on check-ntp.net for the detailed decision. Minimum recommended configuration on chrony 4.x:
# /etc/chrony/chrony.conf — public NTP pool server
# === Upstream sources (at least 4, diversified) ===
server time.cloudflare.com iburst nts
server nts.netnod.se iburst nts
server ntp1.ptb.de iburst
pool 2.pool.ntp.org iburst maxsources 4
# === Accept public traffic ===
# Accept NTP requests from the whole Internet
allow 0.0.0.0/0
allow ::/0
# === Rate limiting to protect the service ===
# KoD (Kiss-o'-Death) above ~4 req/s from one IP
ratelimit interval 1 burst 16 leak 2
# === Security ===
# Never serve our internal variables
noclientlog
# Disable control commands externally (chronyc stays local)
bindcmdaddress 127.0.0.1
bindcmdaddress ::1
# === Stability ===
makestep 1.0 3
rtcsync
leapsecmode system
# === NTS server-side (optional but recommended) ===
ntsserverkey /etc/chrony/nts.key
ntsservercert /etc/chrony/nts.crt
The ratelimit directive is critical: a client looping on one request per second
(symptom of a broken IoT device) can represent kbit/s by itself and hurt the score for everyone
else. KoD signals it to slow down; compliant implementations obey, bad ones keep going but on
a pace chrony ignores.
6. ntpd / ntpsec alternative configuration
# /etc/ntp.conf — ntpd/ntpsec public server
server 0.pool.ntp.org iburst
server 1.pool.ntp.org iburst
server time.cloudflare.com iburst nts
server ntp1.ptb.de iburst
# Restrict world actions
restrict default kod limited nomodify notrap nopeer noquery
restrict -6 default kod limited nomodify notrap nopeer noquery
# Localhost has all rights
restrict 127.0.0.1
restrict ::1
# Leap second history
leapfile /usr/share/zoneinfo/leap-seconds.list
# NO monlist (DDoS amplification vector)
# ntpsec disables mode 6/7 by default; on classic ntpd:
# disable monitor
The limited flag enables native rate-limiting; kod sends Kiss-o'-Death
to abusers; nomodify notrap nopeer noquery blocks any remote reconfiguration attempt.
Do not disable any of these defaults.
7. Abuse, DDoS and misconfigured clients
Joining the pool, the server becomes a target for three parasite behaviours:
7.1 Vendor lock on a hardcoded IP
Consumer device manufacturers (routers, IP cameras, smart TVs) have historically hardcoded a specific NTP server IP in their firmware — sometimes theirs, sometimes a third-party operator picked at random. Millions of devices then query that IP forever. Documented cases: Netgear WNDR router to University of Wisconsin (2003), D-Link NAS to poul-henning.kamp.dk (2005). There is no clean solution: filter source IP in iptables, or accept the load and send KoD.
7.2 DDoS amplification via monlist (historical)
In 2014, ntpd < 4.2.7 exposed a monlist command (mode 7) returning the list of the
last 600 clients. Used in reflected attack, a 234-byte request could produce a ~49 KB response
— a 200× amplification factor. The February 2014 attacks (CloudFlare, Hearthstone) consumed
hundreds of Gbit/s. Mitigations: disable mode 6 and 7 server-side (default on chrony 4.x and
ntpsec), or migrate to these modern implementations.
7.3 Clients that ignore KoD
Kiss-o'-Death is an NTP packet with stratum 0 and a refid code (RATE, DENY…)
that tells the client to slow down or change source. RFC-compliant clients obey. Bad ones ignore
and keep going. For those:
# Temporarily ban an abusive IP (iptables)
iptables -I INPUT -s 203.0.113.42 -p udp --dport 123 -j DROP
# Or dynamically via ipset + fail2ban
# jail chrony_kod in /etc/fail2ban/jail.d/chrony.conf
8. Operator-side monitoring
Three axes to watch continuously on a pool server:
- Score on ntppool.org. Scrape JSON via
https://www.ntppool.org/scores/<IP>/log?monitor=*. Alert on score < +10. - Local offset and stratum. Export
chronyc trackingto Prometheus with the chrony_exporter or equivalent. Alert on offset > 50 ms or stratum > 3. - Traffic and abuse. Count inbound UDP 123 packets via
nftablesorconntrack. A curve that suddenly spikes signals a vendor lock or active attack.
9. What RDEM learned in production
- IPv6 is undervalued in the pool. The proportion of v6 contributors stays low; a well-configured dual-stack server gets disproportionate v6 exposure — useful to the pool, useful for SEO.
- Net speed lies. An operator who under-declares (100 Mbit/s announced on a real 1 Gbit/s link) delivers better experience: headroom during spikes, stable latency. The pool does not need a traffic record, it needs reliable servers.
- Upstream sync is the real bottleneck. A pool server drifting 50 ms for 10 minutes is more harmful to the ecosystem than a server that is down. Invest first in your upstream sources (4 diversified, NTS where possible) before raising bandwidth.
- KoD protects the pool, not the server. chrony/ntpd rate-limit does not prevent an abuser from consuming your bandwidth — it invites them to stop. Capacity protection happens at the firewall level.
- The leap second is a contribution test. Operators who handle leap events correctly (see our dedicated page) keep their score. Those who do not anticipate dive in the following hours.
10. De-registering a server cleanly
Abrupt removal produces monitor timeouts, which impact the score of other servers listed alongside. Clean procedure:
- Uncheck geographic zones on manage.ntppool.org. The server leaves DNS responses within a few hours.
- Wait 48 hours before actually cutting the NTP service. Client DNS caches expire during this window.
- Remove the final registration via the interface — this erases historical scores.
- Announce the removal beyond two weeks if you were a visible contributor.
Resources and references
- pool.ntp.org — official project site
- manage.ntppool.org — operator admin panel
- ntppool.org/a/rdem-systems — our public contribution
- chrony official documentation
- RFC 5905 — NTPv4