214
@cors_error_cleo ·

Actions cache hits every run but npm ci still reinstalls all 900 packages Pipelines

Our actions/setup-node step reports a cache hit and restores in about 8 seconds, but the npm ci right after it still takes 2m40s and clearly unpacks everything again. The lockfile hasn't changed between the two runs I compared. Node 20, npm 10, monorepo with three workspaces. What am I actually caching if not the install?

8 answers Share
Report

Answering anonymously — a moderator will review it first.

  • @rollback_rae · 3mo ago · 3 replies

    setup-node's cache only stores the npm download cache (~/.npm), not node_modules. So on a hit you skip the network, but npm still unpacks and links every package, which is the slow part in a monorepo. Two fixes, pick one: cache node_modules yourself keyed on the lockfile hash and skip npm ci entirely when the key hits, or change the install to npm ci --prefer-offline --no-audit --fund=false. The second one usually buys 30-40% and takes one line.

    187
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @cors_error_cleo · 3mo ago

      That explains the 8 second restore against a 2m40 install. --prefer-offline --no-audit took us to 1m50, and caching node_modules on the lock hash got it to 22s on a hit.

      41
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
    • @static_typing_fan · 3mo ago

      If you cache node_modules directly, key it on hashFiles('**/package-lock.json') AND the node version, otherwise you get native modules built against the wrong ABI the day the runner image bumps.

      26
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @hot_heap_hana · 3mo ago · 2 replies

    Check whether you have any git or http dependencies in that lockfile. Those bypass the npm cache entirely and re-fetch on every run, and one of them can eat a minute on its own. Grep the lockfile for "resolved": "git and you'll know in a second.

    74
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @cors_error_cleo · 3mo ago

      Two, both internal. Moving them onto our private registry is on the list now.

      12
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @regexafterdark · 3mo ago

    Monorepo detail people miss: npm ci deletes node_modules before it starts, always, by design. So any per-workspace timing you see is a full cold link no matter what's in the download cache. Warm installs mean npm install plus a lockfile drift check in CI, which is a tradeoff some teams won't take.

    38
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @shortcut_sam · 3mo ago · 2 replies

    Just move to pnpm, the content-addressed store makes this a non-issue.

    9
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @rollback_rae · 3mo ago

      Probably true long term, but that's migrating a whole monorepo to fix a two minute install. Worth doing on purpose, not as a debugging step.

      8
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report