On August 30, 2026, Jeff Geerling connected old Macs to a network service simple enough to fit in nearly one sentence: open port 37, receive four bytes, close.1

Those bytes are one unsigned 32-bit integer, the number of seconds since midnight on January 1, 1900,3 with no JSON, timezone, server identifier, latency measurement or even a fractional second attached to the answer.

In 1983, RFC 868 simply called it Time.3

Its size is charming now, enough to suggest an age when protocols knew when to stop, but the more useful explanation is prosaic: the four-byte reply stays tiny because the protocol solves a deliberately narrow part of the problem.

NTP would appear two years later carrying much of what those four bytes could not express.4

Two services

RFC 867 and RFC 868 were both published in May 1983, offering two quite different answers to the same need. Daytime, RFC 867, listens on port 13. Over TCP the server sends one line containing date and time and closes the connection; over UDP an incoming datagram triggers a reply.2

The document would probably unsettle a modern API designer because there is no required syntax;2 it recommends a single printable ASCII line and gives two popular formats, yet a client cannot safely assume either one. Daytime is primarily a human debugging and measurement tool.2

RFC 867 says so itself: for machine-useful time, use RFC 868.2

Time gives up that readability in exchange for a deterministic machine reply: over TCP the client connects to port 37, receives a 32-bit value and disconnects, while over UDP an empty datagram is enough to trigger the four-byte response.3

Four bytes

RFC 868 chooses an epoch that NTP later inherits: 00:00:00 on January 1, 1900.3

January 1, 1970 therefore has the value 2,208,988,800.3 Converting a Time value to the Unix epoch can subtract exactly that many seconds, which is what Geerling does in his 2026 demonstration.1

The protocol has one-second resolution because its counter stores whole seconds,3 a trade-off that fits the motivation in the RFC: some systems have no date/time clock, while all clocks remain vulnerable to human or machine error. A brief poll of several independent network sites can at least confirm or correct a machine's local idea of time.3

Diagram of an empty request to port 37 and a four-byte reply representing seconds since 1900The UDP service defined by RFC 868 receives an empty datagram and returns exactly one 32-bit integer. IRZ illustration based on RFC 868

Four bytes are perfectly sufficient if three assumptions hold: whole-second granularity is enough, network transit is negligible for the application, and the client already knows how to interpret the 1900 epoch.

The protocol looks naive only when asked to solve more than its contract promises; its design is mainly narrow.

Missing journey

Suppose a server stamps its reply at 12:00:00 and the packet reaches the client 400 ms later.

RFC 868 gives the client “12:00:00” without any way to know whether the reply spent 2 ms, 40 ms or 400 ms travelling, because the packet carries no request-departure timestamp, server-receive timestamp or reply-departure timestamp.

Even a returned value with microsecond resolution would not reveal exact local time at reception, because a more precise number still says nothing about how long the packet spent travelling.

That is the important difference between resolution and synchronization.

Geerling runs into the same boundary naturally while replaying the protocol on a contemporary network: Time is excellent for showing network time on a vintage machine, but contains no mechanism for compensating variable delays across a multi-hop Internet.1

The small packet has not eliminated the problem; it has moved the problem into the client and into assumptions about the path.

Four timestamps

The first RFC actually titled Network Time Protocol is RFC 958 from September 1985, not 1988;4 RFC 1059 from July 1988 is the NTP version 1 specification that supersedes it.5 The distinction is minor historically but useful if the evolution from Time to NTP is going to be described precisely.

RFC 958 explicitly says NTP evolved from the Time Protocol and ICMP Timestamp messages.4

The conceptual jump appears in four instants:

  • t1: request leaves the client;
  • t2: request reaches the server;
  • t3: reply leaves the server;
  • t4: reply reaches the client.4

Those four numbers let the client estimate both round-trip network delay and its clock offset relative to the server. RFC 958 already gives equations recognizably equivalent to modern NTP.4

Diagram showing NTP timestamps t1 t2 t3 t4 between client and server and calculations for delay and offsetNTP no longer merely transmits a clock reading; it observes the times around the journey so clock and network can be separated as far as the model permits. IRZ illustration based on RFC 958 and RFC 5905

The calculation still depends on a real assumption: forward and return delays must be symmetric enough for the estimate to remain useful, and strong path asymmetry can still bias it.4

The protocol now at least carries the measurements needed to talk about the network rather than pretending it has no duration.

Thirty-two plus thirty-two

NTP in 1985 already uses 64-bit timestamps,4 with the upper half storing seconds relative to 1900 and the lower half storing a 32-bit fraction of a second. Its least-significant fraction bit corresponds to roughly 0.23 ns of numerical resolution.4

That numerical resolution says nothing about a 1985 machine actually synchronizing to 0.23 ns; timestamp granularity and the accuracy of a real clock-synchronization system live at different layers.

NTP also carries information about local clock precision, estimated error, drift and reference source.4 Later versions develop clock selection, filtering and discipline; NTPv4 formalizes statistics including offset, delay, dispersion and jitter.6

Where RFC 868 gains simplicity by omitting context, NTP transports enough context to decide how much confidence to place in a received time.

February 7

RFC 868's 32-bit seconds counter has a mathematical deadline: after 4,294,967,295 seconds, no larger unsigned value fits in the field. The next second corresponds to 06:28:16 UTC on February 7, 2036.7

RFC 868 already warned in 1983 that its epoch would “serve until the year 2036.”3

NTP inherits the same 32-bit seconds field inside its 64-bit timestamp. The fractional half increases resolution; it does not extend the range of the seconds counter.

Modern specifications therefore use NTP eras. RFC 4330 explains that a timestamp after rollover can be interpreted relative to a new base beginning exactly at 06:28:16 UTC on February 7, 2036.7 RFC 5905 formalizes era 0 and era 1 around the wrap.6

Context therefore becomes mandatory, because the seconds field alone can no longer distinguish 1900 from 2036.

There is a pleasing reversal here: the protocol that gained elegance from one self-contained integer eventually needs outside information to stay unambiguous beyond its first 136-year window.

Several clocks

RFC 868 nevertheless contains an idea more sophisticated than its packet: it recommends a brief poll of several independent sites to confirm or correct local time.3

No consensus mechanism exists inside the packet and strategy is left to the client; NTP gradually turns that intuition into a distributed system. RFC 958 already lets peers expose their clock type, precision, estimated error and drift, then use those properties to choose better references and fall back when a source fails.4

NTPv4 goes much further with strata, filtering, clock discipline and procedures for rejecting inconsistent measurements.6

The protocol grows because the question has changed: RFC 868 answers what time does this server say it is?, while NTP tries to answer what estimate of time can we defend after accounting for clocks, network delay and uncertainty?

Keep four bytes

None of this makes RFC 868 silly in 2026.

Geerling's demonstration shows exactly why old protocols remain delightful to manipulate: an xinetd service, one port, four bytes visible through xxd, and a vintage computer can obtain network time without a contemporary NTP client.1

Inside a closed lab, a test setup, a very constrained device or a teaching demonstration, a narrow protocol may be exactly the right abstraction.

Its usefulness survives as long as those omissions are named rather than mistaken for guarantees.

The lesson of RFC 868 is not that networks should have stayed simple. It is that protocol size often tracks how much uncertainty the design is willing to leave somewhere else.

Four bytes are enough to transport a seconds counter; once a client needs to know how long the counter took to arrive, whether its server drifts, whether another clock disagrees, what error is plausible and which side of February 2036 the value belongs to, those four bytes stop being the complete time.

They become what they always were: one measurement surrounded by assumptions that later network protocols learned to write down explicitly.