# Server Stratification in NTP: Understanding Time Accuracy and Stratum Levels

> Discover server stratification in NTP. Understand how stratum levels impact time accuracy, precision, and network synchronization for optimal performance.

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

---

**Server stratification in NTP defines how many "hops" a time server is from an authoritative reference clock, with lower stratum numbers indicating shorter network paths, lower jitter, and higher precision time synchronization.**

In the Network Time Protocol (NTP), server stratification determines the reliability and accuracy of time synchronization across distributed networks. The `jauderho/nts-servers` repository manages a curated list of Network Time Security (NTS) servers, tracking each server's stratum level in [`nts-sources.yml`](https://github.com/jauderho/nts-servers/blob/main/nts-sources.yml) to help users select the most accurate time sources available. Understanding server stratification is essential for configuring robust time infrastructure and maintaining microsecond-level clock accuracy in production environments.

## What Is Server Stratification?

Server stratification organizes NTP servers into hierarchical layers called **strata** based on their distance from a primary reference clock. Each level represents one additional degree of separation from the authoritative time source:

| Stratum | Description |
|---------|-------------|
| **0** | Reference clocks (GPS, atomic clocks, radio clocks). Not reachable directly via NTP. |
| **1** | Servers directly synchronized to a stratum-0 device via local interfaces. |
| **2-15** | Servers synchronized to the next higher stratum. Higher numbers indicate greater distance from the reference. |
| **≥16** | Unsynchronized or unreachable servers. |

A **stratum-1** server connects directly to a hardware reference clock, while a **stratum-2** server synchronizes against a stratum-1 server, and so on. When clients query time, they receive the server's current stratum value, which indicates the quality of the time source.

## Why Server Stratification Matters for Time Accuracy

Lower stratum values correlate directly with higher time accuracy for several critical reasons:

- **Shorter network paths**: Stratum-1 and stratum-2 servers minimize the number of intermediate network hops, reducing accumulated latency and asymmetric delays.
- **Lower jitter**: Each synchronization layer introduces timing variability. Lower strata exhibit less jitter because they have fewer upstream sources of variance.
- **Algorithm weighting**: Time selection algorithms in `chrony` and `ntpd` weight lower-stratum servers more heavily when calculating system clock offsets, automatically preferring stratum-1 and stratum-2 sources over higher-stratum alternatives.
- **Security posture**: High-stratum servers may be more susceptible to timing attacks or upstream compromise, weakening the trust chain for dependent clients.

Mixing servers of widely different strata in a client configuration can degrade overall accuracy, as the client must weigh noisy high-stratum measurements against more reliable low-stratum ones.

## How the nts-servers Repository Manages Stratification

The `jauderho/nts-servers` repository automates the tracking and utilization of server stratification data to ensure users always have access to accurate time sources.

### Tracking Stratum in the Central Data Store

Server metadata resides in [`nts-sources.yml`](https://github.com/jauderho/nts-servers/blob/main/nts-sources.yml), which stores each NTS server's hostname, geographic location, and current stratum value. According to the repository structure, this data populates the README tables (lines 30-38), displaying the **Stratum** column for human-readable server selection (e.g., `time.cloudflare.com` listed as stratum 3).

### Automated Stratum Detection

The [`scripts/ntsUpdateServers.py`](https://github.com/jauderho/nts-servers/blob/main/scripts/ntsUpdateServers.py) file implements automated stratum monitoring through the `get_stratum()` function (lines 46-71). This script queries each listed host to detect stratum changes and maintain data accuracy:

```python

# scripts/ntsUpdateServers.py

def get_stratum(hostname, logger):
    """
    Get stratum for a hostname using ntpdate.
    Returns the stratum as integer or None if not found.
    """
    try:
        cmd = ['ntpdate', '-q', hostname]
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)

        if result.returncode == 0:
            for line in result.stdout.split('\n'):
                line = line.strip()
                # Look for "sN" where N is the stratum number

                stratum_match = re.search(r'\bs(\d+)\b', line)
                if stratum_match:
                    return int(stratum_match.group(1))

```

*The function parses `ntpdate -q` output to extract the `sN` token indicating current stratum, allowing the repository to detect when servers change strata due to upstream connectivity issues.*

To update all stored stratum values:

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

```

### Configuration File Generation

The [`scripts/ntpServerConverter.py`](https://github.com/jauderho/nts-servers/blob/main/scripts/ntpServerConverter.py) utility (lines 36-44) transforms the YAML data into configuration files for popular NTP implementations. It generates [`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) entries that preserve stratum awareness, inserting comments for virtualized servers that may provide less accurate time (lines 70-81):

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

```

This generates configuration lines like `server <hostname> nts iburst`, enabling `chrony` to apply its internal weighting algorithms based on the strata embedded in server responses.

## Summary

- **Server stratification** measures distance from stratum-0 reference clocks, with stratum 1 representing the most accurate network-accessible time sources.
- Lower stratum servers provide reduced jitter, lower latency, and higher precision due to shorter synchronization chains.
- The `jauderho/nts-servers` repository automates stratum monitoring via [`scripts/ntsUpdateServers.py`](https://github.com/jauderho/nts-servers/blob/main/scripts/ntsUpdateServers.py), ensuring the [`nts-sources.yml`](https://github.com/jauderho/nts-servers/blob/main/nts-sources.yml) database reflects current server capabilities.
- Accurate stratification data enables time selection algorithms in `chrony` and `ntpd-rs` to optimize server selection and maintain microsecond-level clock synchronization.

## Frequently Asked Questions

### What is the difference between stratum 0 and stratum 1 NTP servers?

Stratum 0 devices are hardware reference clocks such as atomic clocks, GPS receivers, or radio clocks that are not accessible via network protocols. Stratum 1 servers are computers directly synchronized to a stratum-0 device through a local interface (such as RS-232 or PPS signals), making them the most accurate time servers available over a network.

### Why does a higher stratum number indicate less accurate time?

Each stratum level adds network latency and accumulates timing errors from upstream servers. As the stratum number increases, the time signal traverses additional intermediate servers, accumulating jitter and increasing the potential for asymmetric network delays that degrade precision.

### How does chrony use stratum information when selecting servers?

Chrony's clustering and combining algorithms weight lower-stratum servers more heavily during time source selection. When multiple servers are available, chrony preferentially synchronizes against stratum-1 and stratum-2 sources while treating higher-stratum servers as backup or outlier candidates, minimizing clock offset and maximizing stability.

### Can a server's stratum level change dynamically?

Yes, a server's reported stratum can increase if it loses synchronization with its upstream source (effectively becoming stratum 16/unsynchronized) or decrease when reconnecting to a better reference clock. The [`ntsUpdateServers.py`](https://github.com/jauderho/nts-servers/blob/main/ntsUpdateServers.py) script detects these transitions by periodically querying servers with `ntpdate -q` and updates [`nts-sources.yml`](https://github.com/jauderho/nts-servers/blob/main/nts-sources.yml) when discrepancies are found, ensuring the repository maintains an accurate view of server quality.