{"id":"88c378e131bbc668","repo":"redis/redis","slug":"monotonic-x86-linux-unable-to-determine-clock-ra","errorCode":null,"errorMessage":"monotonic: x86 linux, unable to determine clock rate\n","messagePattern":"monotonic: x86 linux, unable to determine clock rate\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/monotonic.c","lineNumber":87,"sourceCode":"                double ghz = atof(&buf[pmatch[1].rm_so]);\n                mono_ticksPerMicrosecond = (long)(ghz * 1000);\n                break;\n            }\n        }\n        while (fgets(buf, bufflen, cpuinfo) != NULL) {\n            if (regexec(&constTscRegex, buf, nmatch, pmatch, 0) == 0) {\n                constantTsc = 1;\n                break;\n            }\n        }\n\n        fclose(cpuinfo);\n    }\n    regfree(&cpuGhzRegex);\n    regfree(&constTscRegex);\n\n    if (mono_ticksPerMicrosecond == 0) {\n        fprintf(stderr, \"monotonic: x86 linux, unable to determine clock rate\\n\");\n        return;\n    }\n    if (!constantTsc) {\n        fprintf(stderr, \"monotonic: x86 linux, 'constant_tsc' flag not present\\n\");\n        return;\n    }\n\n    snprintf(monotonic_info_string, sizeof(monotonic_info_string),\n            \"X86 TSC @ %ld ticks/us\", mono_ticksPerMicrosecond);\n    getMonotonicUs = getMonotonicUs_x86;\n}\n#endif\n\n#if defined(__aarch64__)\nstatic long mono_ticksPerMicrosecond = 0;\n\n/* Read the clock value.\n * CNTVCT_EL0 is a system counter register, that provides the monotonic","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/redis/redis/blob/3acc0c49cf5ad2af9425d333e62728342dd6159b/src/monotonic.c#L69-L105","documentation":"Emitted during monotonicInit_x86linux() (only when built with -DUSE_PROCESSOR_CLOCK on x86_64 Linux) when the regex '^model name\\s+:.*@ ([0-9.]+)GHz' fails to match any line in /proc/cpuinfo, leaving mono_ticksPerMicrosecond at 0. Because the TSC tick rate is unknown, the function returns without assigning getMonotonicUs, so Redis falls back to the POSIX clock_gettime(CLOCK_MONOTONIC) path. It is a warning to stderr, not fatal.","triggerScenarios":"Built redis-server with CFLAGS='-DUSE_PROCESSOR_CLOCK' on an x86_64 Linux host whose /proc/cpuinfo 'model name' line lacks an '@ X.YYGHz' token (e.g. AMD/Epyc, custom/embedded CPUs, virtualized CPUs that report a non-standard model string, or a kernel that omits the GHz suffix).","commonSituations":"AMD processors and many cloud/virtualized environments report CPU model names without the '@ N.NGHz' format Intel uses, so the regex never matches. Also seen on kernels where the model-name format changed. The server still runs (POSIX fallback) but loses the faster TSC-based monotonic clock.","solutions":["Ignore it if acceptable — Redis transparently falls back to clock_gettime(CLOCK_MONOTONIC) and runs correctly, just slightly slower on clock reads.","Rebuild without -DUSE_PROCESSOR_CLOCK (the default) to silence the message and use POSIX monotonic time.","Inspect /proc/cpuinfo to confirm the model-name format; if your platform genuinely exposes constant_tsc and a known GHz, the upstream regex may need extension.","On a host where the message is noise, redirect stderr or log it at debug level rather than treating it as an error."],"exampleFix":"// before: built with processor clock, AMD CPU has no @GHz in /proc/cpuinfo\n$ make CFLAGS=\"-DUSE_PROCESSOR_CLOCK\"\n// after: use default POSIX monotonic clock\n$ make","handlingStrategy":"fallback","validationCode":"#!/usr/bin/env bash\n# On x86 Linux, redis derives the TSC frequency from cpuinfo/cpuinfo_max_freq.\n# If it can't, it logs this warning and falls back. Pre-check so you know the box is affected.\nif [ \"$(uname -m)\" != \"x86_64\" ]; then exit 0; fi\nif [ ! -r /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq ]; then\n  echo \"no cpufreq cpuinfo_max_freq -> redis will warn on clock rate\" >&2\nfi\n# 'constant_tsc' must be in cpu flags or the fast path is abandoned.\nif ! grep -qw constant_tsc /proc/cpuinfo; then\n  echo \"constant_tsc absent -> monotonic clock rate warning expected\" >&2\nfi","typeGuard":"// No typed value to narrow: this is a host-capability probe, not data validation.\n// Model the probe result instead.\nexport interface MonotonicSupport { clockRateKnown: boolean; constantTsc: boolean; }\nexport function isMonotonicSupport(o: unknown): o is MonotonicSupport {\n  return typeof o === 'object' && o !== null\n    && typeof (o as MonotonicSupport).clockRateKnown === 'boolean'\n    && typeof (o as MonotonicSupport).constantTsc === 'boolean';\n}","tryCatchPattern":"// The warning is non-fatal: capture it from stderr and log, but do not abort.\nimport { spawn } from 'node:child_process';\nconst proc = spawn('redis-server', [confPath]);\nproc.stderr.on('data', chunk => {\n  const s = chunk.toString();\n  if (/unable to determine clock rate/.test(s)) {\n    log.warn('redis monotonic clock fallback on this host; expect lower-res event timing');\n  }\n});","preventionTips":["Run Redis on hosts whose CPU advertises 'constant_tsc' (grep /proc/cpuinfo).","Ensure cpufreq cpuinfo_max_freq is readable; avoid minimal containers that mask /sys.","Pin redis to a kernel/CPU combo you have tested so the monotonic path is known-good.","Treat the warning as informational, not fatal: Redis keeps working via a fallback clock.","Don't deploy Redis under virtualization that hides TSC info without first verifying the clock path."],"tags":["monotonic","x86","tsc","clock","build-flags","linux"],"analyzedSha":"3acc0c49cf5ad2af9425d333e62728342dd6159b","analyzedAt":"2026-08-01T22:07:56.715Z","schemaVersion":2}