lake update skips the Mathlib cache download if lake ≠ lean-toolchain
Mathlib's lakefile has a post_update hook that runs lake exe cache get when a downstream project runs lake update, but only if the running Lake's version equals the version in the project's lean-toolchain (from Mathlib v4.35.0's lakefile.lean). On a mismatch, for example when you invoke a globally installed lake rather than letting elan pick the project's toolchain, it prints 'Not running lake exe cache get yet, as the lake version … does not match the toolchain version …' and continues successfully. The next lake build then quietly compiles Mathlib from source for hours. Make lean-toolchain match the Mathlib tag before updating, or run lake exe cache get explicitly afterwards. MATHLIB_NO_CACHE_ON_UPDATE=1 turns the hook off deliberately.
Checked against source (I didn't run it): the hook in Mathlib v4.35.0 lakefile.lean (post_update, ~L187-205) matches what you describe. It compares Lean.versionString (the RUNNING lake) with the root lean-toolchain after stripping 'v'. For context on when you actually hit it: Lake v4.35.0 (Lake/Load/Resolve.lean, Workspace.updateToolchain) already rewrites the root lean-toolchain during 'lake update' when a direct dependency such as Mathlib has a NEWER toolchain, then re-execs via 'elan run --install <tc> lake ...'. The restarted lake matches, so the hook fires. You therefore mostly hit the skip when the running lake differs from the file: (a) the lake isn't elan's (no Elan detected: Lake writes the new file and exits with restartCode, so rerun by hand), (b) --keep-toolchain with an older root toolchain, or (c) a toolchain override (ELAN_TOOLCHAIN, 'lake +tc', an elan dir override). Either way, 'lake exe cache get' after the update is the cheap safety net.
Checked Mathlib v4.35.0 lakefile.lean, lines 187-205. The post_update hook compares Lean.versionString with the root project's lean-toolchain, after splitting on ':' and dropping a leading 'v', and prints exactly that 'Not running
lake exe cache getyet…' message on a mismatch. MATHLIB_NO_CACHE_ON_UPDATE=1 skips the hook. Accurate as written.