home

more info on my very accurate clock web app (and centralizing links)

Update: 2024/09/17

NIST is proving too unreliable, so I've (at least mostly) switched to checking against Big Evil Goo (time.google.com). I'm relabeling to "ext" for external. That is, I'm just looking for a source outside of (external to) AWS as a sanity check.

more on the "chm" / chrony measurements page

chrony is an implementation of the Network Time Protocol. I use chrony to both keep accurate time on Kwynn.com and measure chrony's health / accuracy. The clock has one chrony reading, but I have since learned that the reading I use isn't complete enough. I've spent too much time geeking out trying to understand chrony's readings. I eventually created the "chm" page to give sufficient readings to assess chrony's accuracy, and thus Kwynn.com's accuracy. I get into the "chm" details further below.

Chm demonstrates that Kwynn.com is usually well under 0.1ms of accuracy relative to the Maryland NIST official time servers / atomic clocks. In early January, 2022, Kwynn.com lives at AWS EC2 "us-east-1a" in northern Virginia. I have several reasons to suspect it's near Ashburn, VA, so it's roughly 18 miles from the NIST servers in Gaithersburg, MD. My chrony config is set to use the Amazon Time Sync Service. I just did an SNTP "ping":

$ sntp -nosleep
1664428242415780704
1664428242269000159
1664428242269001318
1664428242494034347
2610:20:6f15:15::27 

The $ is the Linux command prompt. I am showing the command I'm running. "sntp" is one of my SNTP clients. The times are the nanosecond UNIX Epoch times that the request to the server was sent, the time received by the server, the time sent from the server, and the time received by "me." The round trip is less than 0.4 ms, which is also what my "peer dispersion" (more below) shows in /var/log/chrony/measurements.log

As for NIST "ping":

$ wrap.php 2610:20:6f15:15::27 
[1641858964082631363,1641858964085861986,1641858964085862937,1641858964088946573]

or 6.3 ms.

In terms of reading your time--the time of the computer running the browser--my clock should be better than NIST's client-side web clock. For one, I'm nearly certain NIST only takes one sample, based on my reading the network traffic, and mine takes 15 by default and then lets you reset or add more readings. I also give standard deviation numbers, and I account for the time that JavaScript takes to process (part of the internal error).

Back to chm: an NTP client polls or requests the time from a server. The numbers are as above--client sent time, server receive, server send, and client receive time. The correction between client and server is roughly if not precisely the average client times minus the average server times. Otherwise put, the client has no alternative but to assume that outgoing time versus incoming time are equal, although chrony does try to account for asymmetry such as a cell phone that sends at very low power versus receiving at relatively high power from a relatively powerful transmitter on a cellular service tower. The server sends both its own receive and send time to try to account for its own processing time. The calculation assumes that the relevant time reading is precisely between receive and send. Thus, if the average of send and receive on the client side minus the average on the server side is zero, the client is assumed to be in perfect sync with the server.

A statistical model is used to determine which of these polls are valid and which should be thrown out. This model is in large part determined by the lowest round trip time because it is assumed to have the lowest possible difference between outgoing and incoming time. On my local machine, when I switch from wired internet to my cell phone's USB tether, the cellular-carried polls are usually considered invalid for hours or indefinitely.

The active polls are the valid ones. They are the points in the linear regression line that estimates the constant correction needed between the client and server.

Regarding "constant correction," that's most of what an NTP client does, as I'll explain: if you have a 3 GHz CPU clock, your system assumes that each clock tick is 0.333ns or 1 / (3 * 10^9)--if your clock runs at 3 billion cycles a second, each tick is 1 / 3 billion seconds. (Note that in many programming languages / is division and * is multiplication, so I use that here.) Chrony estimates your clock's deviation from a perfect 3 GHz and corrects the "wall clock" time versus the CPU clock time. That is the "frcor" or frequency correction I list, which is in ppm or parts per millions. That is, an frcor of 65 means that for every million seconds of clock time that passes, chrony is adjusting CPU time versus wall time by 65 seconds, or "a value of 1 ppm would mean that when the system’s clock thinks it has advanced 1 second, it has actually advanced by 1.000001 seconds relative to true time" from the chronyc man page or $ man chronyc

Not coincidentally, I wrote a PHP extension that lets you read your CPU's tick count since boot, or you can use the C language, which is what PHP does.

Back to the chm readings, the active polls are the current points in the linear regression controlling the correction of the CPU clock versus the "wall" time. Sometimes kwynn.com shows 6 - 9, and right now it's showing 18. On one hand, the more polls / points the merrier, but the poll span is also important, which is my next line in chm. The official NTP protocol says, "The non-linear loop described below [develops an accurate measurement] in 15 minutes" (page 48).

I have kwynn.com set to "iburst" in /etc/chrony/chrony.conf, which is an "initial burst" of polling--when it starts, the client polls very often for 30 - 60 seconds before slowing down to steady state. As for the steady state, kwynn.com is set to whatever the default is. My observation is that with a good connection or a great connection such as kwynn.com has, the time is accurate within a handful of polls (5 or 6) as the root dispersion (below) and residual frequency (below) go down. But it takes 15 minutes to more confidently distinguish network asymmetry from clock error. The clock has to run for a certain amount of time before the precise variation in time is determinable.

The "poll span" is the age of the oldest to newest active poll. Obviously the less time since the last poll the better, which is my next line in chm. Now that I think about it, I'm pretty sure the default maximum poll interval is 1,024 seconds or 17 minutes, so hopefully kwynn.com never gets higher than that.

"0.034840 ms offset - last poll" is the latest reading / correction / error from the AWS (in my case) server. Completely outside of chrony, my code makes a poll to the NIST servers, so I show that reading. As you see at the above NIST link, they caution to never poll more often than 4s, and my code exponentially backs off from 4 seconds, so that's why you won't see a new NIST poll upon every refresh.

Note that I don't remember which sign I'm using for fast and slow. I tend to use negative for kwynn.com being slow, but I'm almost certain the NTP protocol does it the opposite way to mean that the client is fast and thus the correction is negative. I think I used it opposite NTP, but I'm not going digging. (You can look at my code versus the NTP / SNTP spec.)

The "current est" is chrony's own estimate of the clock's accuracy. It's not always 0 because chrony can only adjust the clock so quickly or time-sensitive applications (real time systems among others) would get very "confused" and start to malfunction. For example, several systems crashed during the last leap second that added a second at the end of December 31, 2016.

Chrony's own estimate is useful to indicate that chrony is running, but in itself, as I hope I'm explaining in great detail, it's not meaningful. . Chrony will show very precise numbers with a highly asymmetric and inconsistent cell phone connection, so that chrony estimate is suspect. That's "inconsistent" in terms of 10s of ms. It works fine for my browsing purposes.

"root disp" is root dispersion. It's a statistical calculation of the quality of the time signal going all the way back to the root or the "official" atomic time. I say "all the way back" because NTP servers (and clients) come in "stratum." Stratum 0 is the atomic clock itself. Stratum 1 is the computer attached to it, such as the NIST servers. The AWS server I read is a stratum 3, where I would assume that stratum 2 is either run by AWS or is perhaps a telecom's time server. As I've said, though, as stratum 3 servers go, it's quite high quality.

To elaborate, the root dispersion is a quality estimate at that moment. The rd increases until the next poll, and then it might increase again in the case of a high-correciton poll. I don't show the "skew," but the skew is the largest possible error based on the latest poll--the skew is the unknowable of inconsistent network delay relative to how much clock time has passed. The longer chrony has run, the easier it is to tell this difference. I left the skew out because the root dispersion shows the effect of the skew at any given point. (I would guess that root dispersion is skew times the elapsed time since the last poll.)

"peer dispersion" is the dispersion from kwynn.com to the AWS server, which is a fraction / component of root dispersion. (I don't list it in "chm.")

Root delay is (roughly) the best active round trip "ping" / delay time from kwynn.com to NIST or whatever the root is. (I can't be sure NIST is the root. An alternative is a well-calibrated GPS receiver, which is another source of atomic time.)

Maximum error is the theoretical maximum error taking into account delay, dispersion, the latest correction, etc. The calculation I use is higher than the official calculation--that is, I estimate more possible error. With a good connection and after several good polls, that number becomes more and more theoretical. After several polls over 15 minutes, the actual error should be much lower. The maximum error assumes among other things absurd, total asymmetry between outgoing and incoming.

Residual frequency goes back to the issue that chrony can only change the time so quickly. It's one of the measures of the delay in changing the frequency correction / time. The rf may go up after a poll. If another poll does not intervene, the rf goes down quickly. I sometimes see a rf of 0.002 parts per million on kwynn.com, which indicates great accuracy. When I first turn on chrony locally, I sometimes see 300 or 1,000 ppm.

One of the uses of the "NTP server" table is to show whether or not the frequency correction changes. No correction may mean one of two things. It may mean that chrony is throwing it's hands up and staying with the last correction saved to disk, perhaps from a previous boot session. That is, chrony won't change the correction if the data isn't good enough. Or a lack of change means that the polling is very stable. Right now, kwynn.com is only changing by 0.001 ppm. Based on both the NTP server and NIST polls, that means that chrony is very happy and my time is very accurate.

Note that a CPU clock's frequency changes based on temperature which in turn changes based on usage. (Kwynn.com is a virtual machine, so that would be my usage and everyone else's on the machine, perhaps dozens or 100s of VMs.) I have seen reference in chrony to taking temperature into account, but on my local machine, my brief attempts don't seen to do anything. I haven't looked into it on kwynn.com.

In the tables, "min" is elapsed minutes since the poll. The most recent polls should be the same as their entries higher on the page; times are in ms.

older entries

2022, January 18 - probably invisible clock change

This will only affect anyone who has been looking at the details of the network traffic with browser developer tools. Rather than all the "chronyc tracking" readouts, I'm going to whittle it down to what's shown on the clock--"< 1 ms (+3.186µs) - t serv acc (chrony)." The entire chrony output will remain elsewhere in raw form and JSON.

I'm also going to get rid of all the "Is AWS?" stuff. That will also have no affect on the user-level, front-end output of the clock. Earlier today I created a "1.0" label on the source code linked above. That was before this probable change. In the unlikely event someone nearly as eggheaded as I am wants that data in that form, let me know. My contact info and web form are linked from my resume, which is in turn linked from my home page above and is directly linked below.

Welcome VeVe users! (2022, early January)

In the original version of this page, I asked why the clock had become so (relatively) popular all of a sudden. I got the following in response. I'm paraphrasing a bit and anonymizing.

I shared the link with the VeVe collectible crowd. They use it to time VeVe's NTF drops. I hope this is a good thing! -- DP

He's referring to VeVe. Sure, it's a good thing. I was just surprised that my fairly tiny web traffic became much bigger in proportion to "tiny."

My request to you for more info: why did this become so (relatively) popular in late December, 2021? (solved as above: VeVe)

In mid-December, I saw a number of DARPA LifeLog (Facebook) links to my clock. Then on December 30, the clock was mentioned on a YouTube live chat and / or a YouTube video. I can see that from my web server access logs, but my brief attempts to dig farther didn't go anywhere. Around mid-day my time on December 30, something like 115 people used the clock. A relatively lot of people have used it since.

In what context was I mentioned on those platforms? What was the video about? My resume has contact info including a brand new web message form.

page history

  1. 01/18 18:32 - noting change - rm is AWS and most chrony info
  2. 2022/01/14 18:56 EST / UTC -5 -- resolving the traffic mystery with VeVe users
  3. Last-Modified: Wed, 12 Jan 2022 00:29:46 GMT - first time I officially noted
  4. probably created somewhat before the above - matter of hours
HTML5 valid