diff --git a/haversine_02/src/memtester/main.c b/haversine_02/src/memtester/main.c
index 6065133..857c919 100644
--- a/haversine_02/src/memtester/main.c
+++ b/haversine_02/src/memtester/main.c
@@ -1,12 +1,61 @@
 #include "aliases.h"
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
+
+#define PAGESIZE 4096
+
+#if _WIN32
+
+#include <intrin.h>
+#include <psapi.h>
+#include <windows.h>
+
+typedef struct {
+  bool Initialized;
+  HANDLE ProcessHandle;
+} os_metrics;
+
+static os_metrics GlobalMetrics;
+
+static u64 GetOSTimerFreq(void) {
+  LARGE_INTEGER Freq;
+  QueryPerformanceFrequency(&Freq);
+  return Freq.QuadPart;
+}
+
+static u64 ReadOSTimer(void) {
+  LARGE_INTEGER Value;
+  QueryPerformanceCounter(&Value);
+  return Value.QuadPart;
+}
+
+static u64 ReadOSPageFaultCount(void) {
+  PROCESS_MEMORY_COUNTERS_EX MemoryCounters = {};
+  MemoryCounters.cb = sizeof(MemoryCounters);
+  GetProcessMemoryInfo(GlobalMetrics.ProcessHandle,
+                       (PROCESS_MEMORY_COUNTERS *)&MemoryCounters,
+                       sizeof(MemoryCounters));
+
+  u64 Result = MemoryCounters.PageFaultCount;
+  return Result;
+}
+
+static void InitializeOSMetrics(void) {
+  if (!GlobalMetrics.Initialized) {
+    GlobalMetrics.Initialized = true;
+    GlobalMetrics.ProcessHandle =
+        OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
+                    GetCurrentProcessId());
+  }
+}
+
+#else // _WIN32
+
 #include <sys/mman.h>
 #include <sys/resource.h>
 #include <sys/time.h>
 
-#define PAGESIZE 4096
-
 typedef struct rusage rusage_t;
 
 u64 page_fault_count() {
@@ -17,6 +66,8 @@ u64 page_fault_count() {
   return usage.ru_minflt + usage.ru_majflt;
 }
 
+#endif // _WIN32
+
 int main(int argc, char *argv[]) {
   if (argc < 2 || argc > 2) {
     printf("Usage: %s [NUMBER OF PAGES TO ALLOCATE]\n", argv[0]);
@@ -24,6 +75,10 @@ int main(int argc, char *argv[]) {
     return EXIT_FAILURE;
   }
 
+#if _WIN32
+  InitializeOSMetrics();
+#endif
+
   u64 page_count = atol(argv[1]);
   u64 alloc_size = page_count * PAGESIZE;
   u64 touch_size = 0;
@@ -33,8 +88,13 @@ int main(int argc, char *argv[]) {
   for (u64 touch_count = 0; touch_count <= page_count; ++touch_count) {
     touch_size = touch_count * PAGESIZE;
 
+#if _WIN32
+    u8 *data = (u8 *)VirtualAlloc(0, alloc_size, MEM_RESERVE | MEM_COMMIT,
+                                  PAGE_READWRITE);
+#else
     u8 *data = (u8 *)mmap(NULL, alloc_size, PROT_READ | PROT_WRITE,
                           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+#endif
 
     if (!data) {
       printf("Failed to allocate memory\n");
@@ -42,20 +102,33 @@ int main(int argc, char *argv[]) {
       return EXIT_FAILURE;
     }
 
+#if _WIN32
+    u64 fault_start = ReadOSPageFaultCount();
+#else
     u64 fault_start = page_fault_count();
+#endif
 
     for (u64 i = 0; i < touch_size; ++i) {
       data[i] = (u8)i;
     }
 
+#if _WIN32
+    u64 fault_end = ReadOSPageFaultCount();
+#else
     u64 fault_end = page_fault_count();
+#endif
 
     u64 faults = fault_end - fault_start;
 
-    printf("%lu,%lu,%lu,%ld\n", page_count, touch_count, faults,
-           ((i64)faults - touch_count));
+    printf("%llu,%llu,%llu,%lld\n", (unsigned long long)page_count,
+           (unsigned long long)touch_count, (unsigned long long)faults,
+           ((long long)faults - touch_count));
 
+#if _WIN32
+    VirtualFree(Data, 0, MEM_RELEASE);
+#else
     munmap((void *)data, alloc_size);
+#endif
   }
 
   return EXIT_SUCCESS;