diff --git a/src/common/steady_clock.cpp b/src/common/steady_clock.cpp
index 0d5908aa7..782859196 100644
--- a/src/common/steady_clock.cpp
+++ b/src/common/steady_clock.cpp
@@ -23,6 +23,19 @@ static s64 WindowsQueryPerformanceCounter() {
     QueryPerformanceCounter(&counter);
     return counter.QuadPart;
 }
+
+static s64 GetSystemTimeNS() {
+    // GetSystemTimePreciseAsFileTime returns the file time in 100ns units.
+    static constexpr s64 Multiplier = 100;
+    // Convert Windows epoch to Unix epoch.
+    static constexpr s64 WindowsEpochToUnixEpochNS = 0x19DB1DED53E8000LL;
+
+    FILETIME filetime;
+    GetSystemTimePreciseAsFileTime(&filetime);
+    return Multiplier * ((static_cast<s64>(filetime.dwHighDateTime) << 32) +
+                         static_cast<s64>(filetime.dwLowDateTime)) -
+           WindowsEpochToUnixEpochNS;
+}
 #endif
 
 SteadyClock::time_point SteadyClock::Now() noexcept {
@@ -53,4 +66,16 @@ SteadyClock::time_point SteadyClock::Now() noexcept {
 #endif
 }
 
+RealTimeClock::time_point RealTimeClock::Now() noexcept {
+#if defined(_WIN32)
+    return time_point{duration{GetSystemTimeNS()}};
+#elif defined(__APPLE__)
+    return time_point{duration{clock_gettime_nsec_np(CLOCK_REALTIME)}};
+#else
+    timespec ts;
+    clock_gettime(CLOCK_REALTIME, &ts);
+    return time_point{std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec}};
+#endif
+}
+
 }; // namespace Common
diff --git a/src/common/steady_clock.h b/src/common/steady_clock.h
index 9497cf865..dbd0e2513 100644
--- a/src/common/steady_clock.h
+++ b/src/common/steady_clock.h
@@ -20,4 +20,15 @@ struct SteadyClock {
     [[nodiscard]] static time_point Now() noexcept;
 };
 
+struct RealTimeClock {
+    using rep = s64;
+    using period = std::nano;
+    using duration = std::chrono::nanoseconds;
+    using time_point = std::chrono::time_point<RealTimeClock>;
+
+    static constexpr bool is_steady = false;
+
+    [[nodiscard]] static time_point Now() noexcept;
+};
+
 } // namespace Common