Reliability of clock_gettime_nsec_np vs. swift-ntp for tamper-proof KPI timestamps?

We are building a KPI(Telemetry) analytics reporting feature in our iOS app that requires recording and publishing reliable timestamps back to our backend server. Standard system time (Date()) is not suitable for our use case because it is susceptible to manual user changes (system clock manipulation) as well as clock drift over time. We are considering clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW ) as a potential solution for iOS 10+. However, we want to confirm: Is clock_gettime_nsec_np a reliable, drift-free source for this purpose? Does the underlying OS handle NTP synchronization for these clocks, or can user-level time changes still impact them? Additionally, we recently came across Apple's official swift-ntp client library to fetch true NTP time directly. For production KPI reporting, is relying on an NTP library like swift-ntp the recommended approach, or is clock_gettime_nsec_np sufficient on modern iOS? We’d appreciate any insights or past experiences from the community. Thanks!

Answered by DTS Engineer in 898188022

The answer is, as always, it depends. Specifically, I’m not going to recommend a specific approach to you, but I can explain the characteristics of the available APIs.

Apple APIs use two sources of time [1]:

  • A CPU counter of some form [2]
  • The real-time clock

CLOCK_MONOTONIC_RAW is based on the former. Given that, the answer to this question is obvious:

Does the underlying OS handle NTP synchronization for these clocks …

No. That wouldn’t make any sense, because NTP is about wall time.

can user-level time changes still impact them?

No.

However, there are two things to keep in mind:

  • The CPU counter doesn’t count when the CPU is asleep. So, when the device sleeps the system ‘backs up’ the CPU counter to the RTC and then, on wake, restores it. This is the key difference between CLOCK_MONOTONIC_RAW and CLOCK_UPTIME_RAW.
  • APIs that are based on the CPU counter don’t specify what the initial value is when the system boots. Historically it started at zero, but that’s not part of the API and thus you can’t rely on it (the implementation of this stuff has got increasingly complicated in recent years).

So using CLOCK_MONOTONIC_RAW as a timestamp is fine, but it only make sense in the context of the current boot session. I talk more about that in this post, and indeed that post and the post before it on that thread should be interesting to you.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Our devices have other sources of time, like GPS time, but they’re not available via our APIs.

[2] The mechanics of this have changed in the past and could well change again in the future.

The answer is, as always, it depends. Specifically, I’m not going to recommend a specific approach to you, but I can explain the characteristics of the available APIs.

Apple APIs use two sources of time [1]:

  • A CPU counter of some form [2]
  • The real-time clock

CLOCK_MONOTONIC_RAW is based on the former. Given that, the answer to this question is obvious:

Does the underlying OS handle NTP synchronization for these clocks …

No. That wouldn’t make any sense, because NTP is about wall time.

can user-level time changes still impact them?

No.

However, there are two things to keep in mind:

  • The CPU counter doesn’t count when the CPU is asleep. So, when the device sleeps the system ‘backs up’ the CPU counter to the RTC and then, on wake, restores it. This is the key difference between CLOCK_MONOTONIC_RAW and CLOCK_UPTIME_RAW.
  • APIs that are based on the CPU counter don’t specify what the initial value is when the system boots. Historically it started at zero, but that’s not part of the API and thus you can’t rely on it (the implementation of this stuff has got increasingly complicated in recent years).

So using CLOCK_MONOTONIC_RAW as a timestamp is fine, but it only make sense in the context of the current boot session. I talk more about that in this post, and indeed that post and the post before it on that thread should be interesting to you.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Our devices have other sources of time, like GPS time, but they’re not available via our APIs.

[2] The mechanics of this have changed in the past and could well change again in the future.

Reliability of clock_gettime_nsec_np vs. swift-ntp for tamper-proof KPI timestamps?
 
 
Q