# How to Choose Geographically Appropriate NTS Servers: A Complete Guide

> Choose geographically appropriate NTS servers by matching client location to nts-sources.yml. Prioritize non-virtualized servers with low stratum for optimal performance.

- Repository: [Jauder Ho/nts-servers](https://github.com/jauderho/nts-servers)
- Tags: how-to-guide
- Published: 2026-03-04

---

**Select geographically appropriate NTS servers by matching your client's location with the `location` field in [`nts-sources.yml`](https://github.com/jauderho/nts-servers/blob/main/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`](https://github.com/jauderho/nts-servers/blob/main/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 server
- **`notes`** – Optional operational details or restrictions
- **`vm`** – Boolean flag indicating virtualized infrastructure (`true` for 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`](https://github.com/jauderho/nts-servers/blob/main/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`](https://github.com/jauderho/nts-servers/blob/main/nts-sources.yml) or by programmatically filtering the data.

### Manual Selection from YAML

Open [`nts-sources.yml`](https://github.com/jauderho/nts-servers/blob/main/nts-sources.yml) and locate entries where the `location` value matches your target region. For example, to find servers in Germany:

```yaml
- 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:

```python
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`](https://github.com/jauderho/nts-servers/blob/main/scripts/ntpServerConverter.py)** to generate client-ready configuration files.

### Using ntpServerConverter.py

The converter script processes [`nts-sources.yml`](https://github.com/jauderho/nts-servers/blob/main/nts-sources.yml) and supports three output formats:

- **`generate_markdown`** – Creates documentation tables for the README
- **`generate_chrony_conf`** – Produces [`chrony.conf`](https://github.com/jauderho/nts-servers/blob/main/chrony.conf) files for the Chrony NTP client
- **`generate_ntp_toml`** – Generates [`ntp.toml`](https://github.com/jauderho/nts-servers/blob/main/ntp.toml) configuration 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:

```bash

# 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`](https://github.com/jauderho/nts-servers/blob/main/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:

```bash
python scripts/ntpServerConverter.py nts-sources.yml

```

This updates [`README.md`](https://github.com/jauderho/nts-servers/blob/main/README.md) with the latest server table, and refreshes the global [`chrony.conf`](https://github.com/jauderho/nts-servers/blob/main/chrony.conf) and [`ntp.toml`](https://github.com/jauderho/nts-servers/blob/main/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`](https://github.com/jauderho/nts-servers/blob/main/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`](https://github.com/jauderho/nts-servers/blob/main/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`](https://github.com/jauderho/nts-servers/blob/main/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.yml`](https://github.com/jauderho/nts-servers/blob/main/nts-sources.yml)** file contains curated server metadata including a `location` field for geographic filtering and a `vm` flag to identify virtualized infrastructure.
- Use **[`scripts/ntpServerConverter.py`](https://github.com/jauderho/nts-servers/blob/main/scripts/ntpServerConverter.py)** to 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`](https://github.com/jauderho/nts-servers/blob/main/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`](https://github.com/jauderho/nts-servers/blob/main/nts-sources.yml) indicates servers running on virtualized hardware, which often suffer from CPU scheduling jitter that degrades time synchronization accuracy. The [`ntpServerConverter.py`](https://github.com/jauderho/nts-servers/blob/main/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`](https://github.com/jauderho/nts-servers/blob/main/ntpServerConverter.py) script to regenerate your client configurations automatically after pulling the latest [`nts-sources.yml`](https://github.com/jauderho/nts-servers/blob/main/nts-sources.yml).