How to Choose Geographically Appropriate NTS Servers: A Complete Guide
Select geographically appropriate NTS servers by matching your client's location with the location field in nts-sources.yml and prioritizing non-virtualized servers with low stratum values.
The jauderho/nts-servers repository maintains a curated, public list of Network Time Security (NTS) servers worldwide. Choosing geographically appropriate NTS servers reduces network latency, minimizes jitter, and ensures reliable time synchronization by keeping traffic within regional network boundaries.
Understanding the NTS Server Data Structure
All server metadata resides in nts-sources.yml at the repository root. This file uses a structured YAML format where each server entry contains fields that determine its geographic and operational suitability.
The nts-sources.yml File Structure
Each entry in the server list includes the following fields:
hostname– DNS name of the server, sometimes formatted as a Markdown link (e.g.,[time.example.com](https://time.example.com))stratum– NTP stratum level (1 is most accurate, higher numbers indicate distance from reference clocks)location– Human-readable geographic region (e.g., Germany, US, Brazil)owner– Organization or individual operating the servernotes– Optional operational details or restrictionsvm– Boolean flag indicating virtualized infrastructure (truefor VMs, often less accurate than physical hardware)
The file is alphabetically ordered by country, making manual browsing straightforward.
Why Geographic Proximity Matters for NTS
NTS traffic traverses the public Internet, making path length and network topology critical factors. Selecting geographically appropriate NTS servers provides three primary benefits:
- Reduced latency and jitter – Shorter network paths decrease round-trip time, which directly improves clock synchronization accuracy.
- Higher availability – Regional servers are less likely to be blocked by corporate firewalls or subject to cross-border routing instabilities.
- Data residency compliance – Some jurisdictions require that time synchronization traffic remain within national or regional boundaries.
The location field in nts-sources.yml uses country-level granularity, providing a practical balance between geographic precision and list maintainability.
How to Filter Servers by Location
You can identify geographically appropriate NTS servers either by manually inspecting nts-sources.yml or by programmatically filtering the data.
Manual Selection from YAML
Open nts-sources.yml and locate entries where the location value matches your target region. For example, to find servers in Germany:
- hostname: "[ptbtime1.ptb.de](https://ptbtime1.ptb.de)"
stratum: 1
location: Germany
owner: PTB
vm: false
Check the stratum and vm fields to ensure the server meets your accuracy requirements.
Programmatic Filtering with Python
For automated deployments, use Python to extract servers for a specific region while excluding virtualized infrastructure:
import yaml
def servers_by_location(yaml_path, region):
with open(yaml_path) as f:
data = yaml.safe_load(f)
return [
s for s in data["servers"]
if s["location"].lower() == region.lower() and not s["vm"]
]
if __name__ == "__main__":
german_servers = servers_by_location("nts-sources.yml", "Germany")
for srv in german_servers:
print(f"{srv['hostname']} (stratum {srv['stratum']})")
This script filters for geographically appropriate NTS servers and excludes VMs, outputting only high-quality physical infrastructure.
Generating Client Configurations for Specific Regions
Once you have identified geographically appropriate servers, use scripts/ntpServerConverter.py to generate client-ready configuration files.
Using ntpServerConverter.py
The converter script processes nts-sources.yml and supports three output formats:
generate_markdown– Creates documentation tables for the READMEgenerate_chrony_conf– Produceschrony.conffiles for the Chrony NTP clientgenerate_ntp_toml– Generatesntp.tomlconfiguration for ntpd-rs
By default, the script filters out virtualized servers (vm: true) and extracts plain hostnames from Markdown-formatted links.
Creating Region-Specific Configurations
To generate a configuration file containing only servers from a specific region, filter the YAML before conversion:
# 1. Extract German entries into a temporary file
python - <<'PY' nts-sources.yml germany.yml
import yaml, sys
src = yaml.safe_load(open(sys.argv[1]))
germany = {"servers": [s for s in src["servers"]
if s["location"] == "Germany" and not s["vm"]]}
yaml.safe_dump(germany, open(sys.argv[2], "w"))
PY
# 2. Generate a chrony.conf that contains only German servers
python scripts/ntpServerConverter.py germany.yml chrony germany-chrony.conf
# 3. Verify the result
cat germany-chrony.conf
This workflow produces a lean chrony.conf containing only geographically appropriate NTS servers for your target region.
Updating the README Automatically
To regenerate the full documentation and configuration files for all regions:
python scripts/ntpServerConverter.py nts-sources.yml
This updates README.md with the latest server table, and refreshes the global chrony.conf and ntp.toml files.
Best Practices for Production Deployments
When deploying geographically appropriate NTS servers in production environments, follow these guidelines to ensure reliability and accuracy.
Prioritize Low Stratum Servers
Stratum 1 servers connect directly to reference clocks (atomic clocks, GPS, or radio time signals). According to the data in nts-sources.yml, prefer servers with stratum: 1 for maximum accuracy, and use stratum 2 servers only when necessary for redundancy.
Avoid Virtualized Infrastructure
The vm field in nts-sources.yml indicates whether a server runs on virtualized hardware. Virtualized NTP servers often exhibit higher jitter due to CPU scheduling inconsistencies. The ntpServerConverter.py script excludes VMs by default, and you should maintain this filter for production time synchronization.
Configure Multiple Servers for Redundancy
Even geographically appropriate NTS servers can experience outages. Configure at least three servers from your region to maintain consensus and prevent single points of failure. The Chrony and ntpd-rs configuration generators in the repository automatically format multi-server entries correctly.
Summary
- Geographically appropriate NTS servers reduce latency and improve reliability by keeping time synchronization traffic within regional network boundaries.
- The
nts-sources.ymlfile contains curated server metadata including alocationfield for geographic filtering and avmflag to identify virtualized infrastructure. - Use
scripts/ntpServerConverter.pyto generate client configurations for Chrony or ntpd-rs, filtering by region and excluding VMs for optimal accuracy. - Prioritize stratum 1 servers and physical (non-VM) infrastructure for production deployments requiring high-precision time synchronization.
Frequently Asked Questions
What is the difference between NTS and standard NTP?
NTS (Network Time Security) is an extension of NTP (Network Time Protocol) that adds encryption and authentication using TLS and AEAD algorithms. While standard NTP transmits time data in plaintext and is vulnerable to man-in-the-middle attacks, NTS establishes encrypted sessions that protect against tampering and eavesdropping. The jauderho/nts-servers repository specifically lists servers that support NTS authentication.
How do I verify that an NTS server is geographically close to me?
You can verify geographic proximity by checking the location field in nts-sources.yml and then performing network latency tests. Use tools like ping or mtr to measure round-trip time to the server's hostname. Servers in your country or region should exhibit significantly lower latency (typically under 50ms) compared to intercontinental servers. The repository's location field uses country-level granularity to simplify this selection process.
Can I use virtualized NTS servers in production?
While technically possible, virtualized NTS servers are generally not recommended for production environments requiring high precision. The vm: true flag in nts-sources.yml indicates servers running on virtualized hardware, which often suffer from CPU scheduling jitter that degrades time synchronization accuracy. The ntpServerConverter.py script excludes virtualized servers by default, and you should maintain this filter unless you have specific requirements that tolerate higher timing variance.
How often should I update my NTS server list?
You should update your NTS server list whenever the jauderho/nts-servers repository receives updates, typically checking monthly or automating the process via CI/CD pipelines. Server availability, stratum levels, and network paths change over time; maintaining a current list ensures you are not attempting to connect to decommissioned servers or missing newly available, geographically closer options. Use the ntpServerConverter.py script to regenerate your client configurations automatically after pulling the latest nts-sources.yml.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →