From 493f3aae3fe5fecc3dd1ee3e1976694922155cf9 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Wed, 19 Aug 2026 15:20:25 +0200 Subject: [PATCH 1/2] fix: re-warm the cache before the update row, so it measures updating MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The published update row said pnpm 12 takes 2.5s to Bun's 719ms. Almost none of that was updating. The rows before it delete the cache twice, and what each manager holds when update finally runs is an accident of row ordering: on the `node_modules` row pnpm restores the tree from the lockfile copy it keeps inside it — 32ms, zero registry requests — while Bun re-downloads the whole graph (4s, 1,145 packuments, 1,345 tarballs). So Bun arrived at update with a cache its own inefficiency had just re-warmed, and pnpm arrived cold and paid for 509 packuments and 566 tarballs inside the one run being timed. The row was measuring the wipe's echo, and it rewarded the manager that had wasted the most on the row before. Measured under the benchmark's own link with the imbalance removed — every manager re-fetches the base graph once, untimed, before the bump is timed: pnpm 12 updates in 801ms and Bun in 657ms. Bun's number barely moves, which is the confirmation: its published figure was never resolver speed, it was the warm cache. The re-warm runs in a throwaway copy of the project whose `cache/` is a symlink into the real one, with no lockfile and no `node_modules` — the fast managers would otherwise short-circuit and warm nothing, which is how the imbalance arose in the first place. A warm start is also what the row claims to model: a developer who bumps versions has the cache their installs left. The recorded results go, all of them: every manager's update number was measured under the old conditions, and `min()` must not pool the two. Co-Authored-By: Claude Opus 5 (1M context) --- benchmarkFixture.js | 29 +++ index.js | 3 +- results/bun/1.3.14/alotta-files-pnpr.yaml | 180 ------------------ results/npm/12.0.2/alotta-files-pnpr.yaml | 180 ------------------ results/pnpm11/11.22.0/alotta-files-pnpr.yaml | 30 --- .../pnpm12/12.0.0-rc.7/alotta-files-pnpr.yaml | 30 --- .../12.0.0-rc.7/alotta-files-pnpr.yaml | 30 --- .../yarn/6.0.0-rc.19/alotta-files-pnpr.yaml | 180 ------------------ .../6.0.0-rc.19/alotta-files-pnpr.yaml | 180 ------------------ 9 files changed, 31 insertions(+), 811 deletions(-) delete mode 100644 results/bun/1.3.14/alotta-files-pnpr.yaml delete mode 100644 results/npm/12.0.2/alotta-files-pnpr.yaml delete mode 100644 results/pnpm11/11.22.0/alotta-files-pnpr.yaml delete mode 100644 results/pnpm12/12.0.0-rc.7/alotta-files-pnpr.yaml delete mode 100644 results/pnpm_pnpr/12.0.0-rc.7/alotta-files-pnpr.yaml delete mode 100644 results/yarn/6.0.0-rc.19/alotta-files-pnpr.yaml delete mode 100644 results/yarn_pnp/6.0.0-rc.19/alotta-files-pnpr.yaml diff --git a/benchmarkFixture.js b/benchmarkFixture.js index ca49dec..b37318a 100644 --- a/benchmarkFixture.js +++ b/benchmarkFixture.js @@ -375,6 +375,35 @@ export default async function benchmark (pm, fixture, opts) { size = await getFolderSize.loose(path.join(cwd, 'cache')) } + console.log('# re-warm the cache for the update scenario (not measured)') + + // The rows above drained the cache twice, and what each manager holds by + // now depends on how it behaved on the rows in between — pnpm restores a + // warm `node_modules` from the lockfile copy it keeps inside it, touching + // the registry not at all, while Bun re-downloads the whole graph on the + // same row. Left like that, the update row hands Bun a cache its previous + // row just filled and pnpm a cold one, and what gets measured is the + // wipe's echo rather than the update. A developer who bumps versions has + // the cache their installs left, so every manager gets the base graph + // re-warmed here, untimed: a from-scratch resolve-and-fetch in a throwaway + // copy of the project whose `cache/` is a symlink into the real one. No + // lockfile and no `node_modules` go with it, or the fast managers would + // short-circuit and warm nothing, which is how the imbalance arose in the + // first place. + const rewarmDir = path.join(cwd, '.rewarm') + rimraf.sync(rewarmDir) + await fs.mkdir(rewarmDir, { recursive: true }) + for (const name of ['package.json', '.npmrc', 'pnpm-workspace.yaml', '.yarnrc.yml', '.yarnrc']) { + try { + cpSync(path.join(cwd, name), path.join(rewarmDir, name)) + } catch { + // A file a manager doesn't use was never written; nothing to copy. + } + } + await fs.symlink(path.join(cwd, 'cache'), path.join(rewarmDir, 'cache'), 'dir') + measureInstall(pm, rewarmDir, env) + rimraf.sync(rewarmDir) + console.log('# with updated dependencies') // update all dependency versions to '*' and install again diff --git a/index.js b/index.js index 90b059f..c60bdf4 100644 --- a/index.js +++ b/index.js @@ -118,7 +118,7 @@ const explanationByTest = { withWarmCacheAndLockfile: '`cache+trusted lockfile`: a developer reinstalling a known project.', withWarmModulesAndLockfile: '`trusted lockfile+node_modules`: the cache is deleted and install is run again.', repeatInstall: '`cache+trusted lockfile+node_modules`: re-running install when nothing has changed.', - updatedDependencies: '`update`: dependency versions are bumped in `package.json` and install is run again.', + updatedDependencies: '`update`: dependency versions are bumped in `package.json` and install is run again, from a warm cache.', } // Sort tests by descending time on the first PM (npm) — slowest first. @@ -384,6 +384,7 @@ async function writePage ({ formattedNow, registryVersion, sections, svgs, sorte - **Server-side resolution pays off when there is a graph to resolve.** Resolving one means walking it level by level, and each level costs a round trip, so the cost is roughly the depth of the graph times the latency. pnpr does that walk next to the registry — its own metadata access stays on loopback, the co-located shape the [pnpm monorepo's integrated benchmark](https://github.com/pnpm/pnpm) measures — and answers with the whole resolved lockfile at once, which is why the rows without a lockfile, and the row that changes dependencies, are the ones where it pulls ahead of plain pnpm. - **The lockfile is trusted, so every manager is asked for the same work.** pnpm verifies a lockfile against the registry before installing it — a supply-chain pass that costs a packument per package, and one no other manager here performs. The rows with a lockfile run every pnpm column with [\`trustLockfile\`](https://pnpm.io/settings#trustlockfile), so what they compare is the install rather than a safety check only one participant was asked for. It is on by default outside this benchmark, and pnpm's own resolution still applies its release-age policy on the rows that resolve. - **With an up-to-date lockfile there is nothing to resolve.** pnpm doesn't ask the server then, so those rows measure the same install in both pnpm 12 columns. + - **The update row starts from a warm cache.** The rows before it delete the cache twice, and how much of it a manager has rebuilt by the time update runs is an accident of row ordering — one manager's registry-free reuse of a warm \`node_modules\` left it cold on exactly the row where another's full re-download had just re-warmed itself. A developer who bumps versions has the cache their installs left, so before the update is timed, every manager re-fetches the base graph once, untimed. - Tarballs are still fetched by the client, in parallel and directly, on every row. ` diff --git a/results/bun/1.3.14/alotta-files-pnpr.yaml b/results/bun/1.3.14/alotta-files-pnpr.yaml deleted file mode 100644 index 15ff9bc..0000000 --- a/results/bun/1.3.14/alotta-files-pnpr.yaml +++ /dev/null @@ -1,180 +0,0 @@ -- firstInstall: 5152 - repeatInstall: 52 - withWarmCacheAndLockfile: 765 - withWarmCache: 843 - withLockfile: 3111 - withWarmCacheAndModules: 2080 - withWarmModulesAndLockfile: 50 - withWarmModules: 4372 - updatedDependencies: 835 - size: 329870744 -- firstInstall: 5076 - repeatInstall: 49 - withWarmCacheAndLockfile: 764 - withWarmCache: 794 - withLockfile: 3019 - withWarmCacheAndModules: 2077 - withWarmModulesAndLockfile: 47 - withWarmModules: 4359 - updatedDependencies: 826 - size: 329749077 -- firstInstall: 5103 - repeatInstall: 58 - withWarmCacheAndLockfile: 790 - withWarmCache: 804 - withLockfile: 3145 - withWarmCacheAndModules: 2112 - withWarmModulesAndLockfile: 50 - withWarmModules: 4359 - updatedDependencies: 800 - size: 329796061 -- firstInstall: 5000 - repeatInstall: 51 - withWarmCacheAndLockfile: 753 - withWarmCache: 826 - withLockfile: 3165 - withWarmCacheAndModules: 1941 - withWarmModulesAndLockfile: 51 - withWarmModules: 4281 - updatedDependencies: 736 - size: 329796061 -- firstInstall: 4982 - repeatInstall: 48 - withWarmCacheAndLockfile: 753 - withWarmCache: 764 - withLockfile: 3118 - withWarmCacheAndModules: 1925 - withWarmModulesAndLockfile: 46 - withWarmModules: 4286 - updatedDependencies: 806 - size: 329759408 -- firstInstall: 5029 - repeatInstall: 46 - withWarmCacheAndLockfile: 743 - withWarmCache: 766 - withLockfile: 3149 - withWarmCacheAndModules: 2234 - withWarmModulesAndLockfile: 45 - withWarmModules: 4283 - updatedDependencies: 719 - size: 329861555 -- firstInstall: 5030 - repeatInstall: 47 - withWarmCacheAndLockfile: 750 - withWarmCache: 824 - withLockfile: 3015 - withWarmCacheAndModules: 1963 - withWarmModulesAndLockfile: 46 - withWarmModules: 4211 - updatedDependencies: 834 - size: 329763057 -- firstInstall: 4984 - repeatInstall: 48 - withWarmCacheAndLockfile: 751 - withWarmCache: 826 - withLockfile: 3001 - withWarmCacheAndModules: 2008 - withWarmModulesAndLockfile: 53 - withWarmModules: 4297 - updatedDependencies: 741 - size: 329833644 -- firstInstall: 4973 - repeatInstall: 48 - withWarmCacheAndLockfile: 774 - withWarmCache: 778 - withLockfile: 3007 - withWarmCacheAndModules: 1960 - withWarmModulesAndLockfile: 46 - withWarmModules: 4288 - updatedDependencies: 721 - size: 329829548 -- firstInstall: 5112 - repeatInstall: 51 - withWarmCacheAndLockfile: 785 - withWarmCache: 806 - withLockfile: 3061 - withWarmCacheAndModules: 2041 - withWarmModulesAndLockfile: 48 - withWarmModules: 4331 - updatedDependencies: 743 - size: 330575613 -- firstInstall: 5040 - repeatInstall: 51 - withWarmCacheAndLockfile: 793 - withWarmCache: 867 - withLockfile: 3151 - withWarmCacheAndModules: 2282 - withWarmModulesAndLockfile: 50 - withWarmModules: 4306 - updatedDependencies: 759 - size: 329759584 -- firstInstall: 5101 - repeatInstall: 51 - withWarmCacheAndLockfile: 791 - withWarmCache: 823 - withLockfile: 3044 - withWarmCacheAndModules: 2113 - withWarmModulesAndLockfile: 49 - withWarmModules: 4265 - updatedDependencies: 733 - size: 330577930 -- firstInstall: 4993 - repeatInstall: 50 - withWarmCacheAndLockfile: 764 - withWarmCache: 855 - withLockfile: 3078 - withWarmCacheAndModules: 2042 - withWarmModulesAndLockfile: 49 - withWarmModules: 4325 - updatedDependencies: 824 - size: 329759740 -- firstInstall: 5027 - repeatInstall: 49 - withWarmCacheAndLockfile: 766 - withWarmCache: 787 - withLockfile: 3015 - withWarmCacheAndModules: 2149 - withWarmModulesAndLockfile: 47 - withWarmModules: 4531 - updatedDependencies: 825 - size: 329871076 -- firstInstall: 4999 - repeatInstall: 52 - withWarmCacheAndLockfile: 744 - withWarmCache: 778 - withLockfile: 3039 - withWarmCacheAndModules: 1940 - withWarmModulesAndLockfile: 48 - withWarmModules: 4367 - updatedDependencies: 729 - size: 329759740 -- firstInstall: 4996 - repeatInstall: 48 - withWarmCacheAndLockfile: 775 - withWarmCache: 860 - withLockfile: 3128 - withWarmCacheAndModules: 1980 - withWarmModulesAndLockfile: 51 - withWarmModules: 4358 - updatedDependencies: 833 - size: 329759816 -- firstInstall: 5017 - repeatInstall: 54 - withWarmCacheAndLockfile: 775 - withWarmCache: 779 - withLockfile: 3097 - withWarmCacheAndModules: 2401 - withWarmModulesAndLockfile: 52 - withWarmModules: 4292 - updatedDependencies: 744 - size: 329763912 -- firstInstall: 5123 - repeatInstall: 49 - withWarmCacheAndLockfile: 767 - withWarmCache: 852 - withLockfile: 3105 - withWarmCacheAndModules: 1987 - withWarmModulesAndLockfile: 48 - withWarmModules: 4300 - updatedDependencies: 848 - size: 330579941 diff --git a/results/npm/12.0.2/alotta-files-pnpr.yaml b/results/npm/12.0.2/alotta-files-pnpr.yaml deleted file mode 100644 index 4a65149..0000000 --- a/results/npm/12.0.2/alotta-files-pnpr.yaml +++ /dev/null @@ -1,180 +0,0 @@ -- firstInstall: 60448 - repeatInstall: 1506 - withWarmCacheAndLockfile: 10789 - withWarmCache: 57578 - withLockfile: 14325 - withWarmCacheAndModules: 2033 - withWarmModulesAndLockfile: 1536 - withWarmModules: 2024 - updatedDependencies: 9954 - size: 323744969 -- firstInstall: 60379 - repeatInstall: 1517 - withWarmCacheAndLockfile: 10649 - withWarmCache: 57190 - withLockfile: 14218 - withWarmCacheAndModules: 2020 - withWarmModulesAndLockfile: 1519 - withWarmModules: 2047 - updatedDependencies: 9967 - size: 323744969 -- firstInstall: 60539 - repeatInstall: 1496 - withWarmCacheAndLockfile: 10685 - withWarmCache: 58434 - withLockfile: 14402 - withWarmCacheAndModules: 2127 - withWarmModulesAndLockfile: 1540 - withWarmModules: 2066 - updatedDependencies: 10102 - size: 323744969 -- firstInstall: 58798 - repeatInstall: 1449 - withWarmCacheAndLockfile: 10346 - withWarmCache: 55919 - withLockfile: 13837 - withWarmCacheAndModules: 1960 - withWarmModulesAndLockfile: 1440 - withWarmModules: 2063 - updatedDependencies: 9703 - size: 323744969 -- firstInstall: 58742 - repeatInstall: 1447 - withWarmCacheAndLockfile: 10352 - withWarmCache: 55706 - withLockfile: 13777 - withWarmCacheAndModules: 1924 - withWarmModulesAndLockfile: 1454 - withWarmModules: 2006 - updatedDependencies: 9662 - size: 323744969 -- firstInstall: 58709 - repeatInstall: 1457 - withWarmCacheAndLockfile: 10589 - withWarmCache: 56159 - withLockfile: 13864 - withWarmCacheAndModules: 1952 - withWarmModulesAndLockfile: 1451 - withWarmModules: 1946 - updatedDependencies: 9647 - size: 323744969 -- firstInstall: 49802 - repeatInstall: 1507 - withWarmCacheAndLockfile: 10663 - withWarmCache: 15732 - withLockfile: 14141 - withWarmCacheAndModules: 1988 - withWarmModulesAndLockfile: 1468 - withWarmModules: 1975 - updatedDependencies: 9343 - size: 323745207 -- firstInstall: 49957 - repeatInstall: 1478 - withWarmCacheAndLockfile: 10749 - withWarmCache: 15680 - withLockfile: 14125 - withWarmCacheAndModules: 1979 - withWarmModulesAndLockfile: 1475 - withWarmModules: 1989 - updatedDependencies: 9313 - size: 323745207 -- firstInstall: 49714 - repeatInstall: 1466 - withWarmCacheAndLockfile: 10674 - withWarmCache: 15718 - withLockfile: 14136 - withWarmCacheAndModules: 1981 - withWarmModulesAndLockfile: 1471 - withWarmModules: 1976 - updatedDependencies: 9313 - size: 323745207 -- firstInstall: 48743 - repeatInstall: 1369 - withWarmCacheAndLockfile: 8831 - withWarmCache: 13706 - withLockfile: 12768 - withWarmCacheAndModules: 1848 - withWarmModulesAndLockfile: 1352 - withWarmModules: 1806 - updatedDependencies: 8973 - size: 323741734 -- firstInstall: 48707 - repeatInstall: 1380 - withWarmCacheAndLockfile: 8979 - withWarmCache: 14261 - withLockfile: 13009 - withWarmCacheAndModules: 1883 - withWarmModulesAndLockfile: 1374 - withWarmModules: 1914 - updatedDependencies: 9144 - size: 323741734 -- firstInstall: 48169 - repeatInstall: 1336 - withWarmCacheAndLockfile: 8808 - withWarmCache: 13546 - withLockfile: 12670 - withWarmCacheAndModules: 1796 - withWarmModulesAndLockfile: 1337 - withWarmModules: 1827 - updatedDependencies: 8872 - size: 323741734 -- firstInstall: 48439 - repeatInstall: 1332 - withWarmCacheAndLockfile: 8828 - withWarmCache: 13667 - withLockfile: 12838 - withWarmCacheAndModules: 1844 - withWarmModulesAndLockfile: 1395 - withWarmModules: 1807 - updatedDependencies: 8888 - size: 323741890 -- firstInstall: 47985 - repeatInstall: 1317 - withWarmCacheAndLockfile: 8546 - withWarmCache: 13356 - withLockfile: 12608 - withWarmCacheAndModules: 1787 - withWarmModulesAndLockfile: 1321 - withWarmModules: 1780 - updatedDependencies: 8834 - size: 323741890 -- firstInstall: 49139 - repeatInstall: 1449 - withWarmCacheAndLockfile: 10386 - withWarmCache: 15233 - withLockfile: 13870 - withWarmCacheAndModules: 1959 - withWarmModulesAndLockfile: 1449 - withWarmModules: 1958 - updatedDependencies: 9188 - size: 323741890 -- firstInstall: 48404 - repeatInstall: 1348 - withWarmCacheAndLockfile: 8834 - withWarmCache: 13519 - withLockfile: 12703 - withWarmCacheAndModules: 1824 - withWarmModulesAndLockfile: 1347 - withWarmModules: 1824 - updatedDependencies: 8911 - size: 323741966 -- firstInstall: 50839 - repeatInstall: 1522 - withWarmCacheAndLockfile: 11148 - withWarmCache: 16198 - withLockfile: 14626 - withWarmCacheAndModules: 2048 - withWarmModulesAndLockfile: 1544 - withWarmModules: 2067 - updatedDependencies: 9590 - size: 323741966 -- firstInstall: 48962 - repeatInstall: 1373 - withWarmCacheAndLockfile: 9282 - withWarmCache: 14431 - withLockfile: 12999 - withWarmCacheAndModules: 1836 - withWarmModulesAndLockfile: 1363 - withWarmModules: 1845 - updatedDependencies: 8948 - size: 323741966 diff --git a/results/pnpm11/11.22.0/alotta-files-pnpr.yaml b/results/pnpm11/11.22.0/alotta-files-pnpr.yaml deleted file mode 100644 index ca45f32..0000000 --- a/results/pnpm11/11.22.0/alotta-files-pnpr.yaml +++ /dev/null @@ -1,30 +0,0 @@ -- firstInstall: 8157 - repeatInstall: 592 - withWarmCacheAndLockfile: 2572 - withWarmCache: 4683 - withLockfile: 4747 - withWarmCacheAndModules: 740 - withWarmModulesAndLockfile: 767 - withWarmModules: 743 - updatedDependencies: 7579 - size: 307865329 -- firstInstall: 9036 - repeatInstall: 660 - withWarmCacheAndLockfile: 2816 - withWarmCache: 5136 - withLockfile: 5142 - withWarmCacheAndModules: 814 - withWarmModulesAndLockfile: 817 - withWarmModules: 811 - updatedDependencies: 8275 - size: 307865329 -- firstInstall: 8226 - repeatInstall: 593 - withWarmCacheAndLockfile: 2559 - withWarmCache: 4743 - withLockfile: 4887 - withWarmCacheAndModules: 770 - withWarmModulesAndLockfile: 775 - withWarmModules: 748 - updatedDependencies: 7713 - size: 307865329 diff --git a/results/pnpm12/12.0.0-rc.7/alotta-files-pnpr.yaml b/results/pnpm12/12.0.0-rc.7/alotta-files-pnpr.yaml deleted file mode 100644 index 3db4724..0000000 --- a/results/pnpm12/12.0.0-rc.7/alotta-files-pnpr.yaml +++ /dev/null @@ -1,30 +0,0 @@ -- firstInstall: 5117 - repeatInstall: 21 - withWarmCacheAndLockfile: 647 - withWarmCache: 1208 - withLockfile: 3424 - withWarmCacheAndModules: 63 - withWarmModulesAndLockfile: 78 - withWarmModules: 68 - updatedDependencies: 2592 - size: 325840458 -- firstInstall: 5219 - repeatInstall: 20 - withWarmCacheAndLockfile: 667 - withWarmCache: 1153 - withLockfile: 3474 - withWarmCacheAndModules: 61 - withWarmModulesAndLockfile: 81 - withWarmModules: 69 - updatedDependencies: 2632 - size: 325832266 -- firstInstall: 5258 - repeatInstall: 21 - withWarmCacheAndLockfile: 669 - withWarmCache: 1258 - withLockfile: 3451 - withWarmCacheAndModules: 64 - withWarmModulesAndLockfile: 80 - withWarmModules: 72 - updatedDependencies: 2609 - size: 325840458 diff --git a/results/pnpm_pnpr/12.0.0-rc.7/alotta-files-pnpr.yaml b/results/pnpm_pnpr/12.0.0-rc.7/alotta-files-pnpr.yaml deleted file mode 100644 index 1b8563b..0000000 --- a/results/pnpm_pnpr/12.0.0-rc.7/alotta-files-pnpr.yaml +++ /dev/null @@ -1,30 +0,0 @@ -- firstInstall: 3569 - repeatInstall: 20 - withWarmCacheAndLockfile: 714 - withWarmCache: 815 - withLockfile: 3413 - withWarmCacheAndModules: 64 - withWarmModulesAndLockfile: 82 - withWarmModules: 75 - updatedDependencies: 1120 - size: 325942739 -- firstInstall: 3612 - repeatInstall: 21 - withWarmCacheAndLockfile: 735 - withWarmCache: 782 - withLockfile: 3422 - withWarmCacheAndModules: 71 - withWarmModulesAndLockfile: 86 - withWarmModules: 74 - updatedDependencies: 1164 - size: 325938643 -- firstInstall: 3613 - repeatInstall: 19 - withWarmCacheAndLockfile: 665 - withWarmCache: 739 - withLockfile: 3472 - withWarmCacheAndModules: 65 - withWarmModulesAndLockfile: 83 - withWarmModules: 74 - updatedDependencies: 1127 - size: 325942739 diff --git a/results/yarn/6.0.0-rc.19/alotta-files-pnpr.yaml b/results/yarn/6.0.0-rc.19/alotta-files-pnpr.yaml deleted file mode 100644 index 0146cbe..0000000 --- a/results/yarn/6.0.0-rc.19/alotta-files-pnpr.yaml +++ /dev/null @@ -1,180 +0,0 @@ -- firstInstall: 8370 - repeatInstall: 1354 - withWarmCacheAndLockfile: 2087 - withWarmCache: 5725 - withLockfile: 6387 - withWarmCacheAndModules: 3914 - withWarmModulesAndLockfile: 6872 - withWarmModules: 8722 - updatedDependencies: 2982 - size: 313928602 -- firstInstall: 8401 - repeatInstall: 1362 - withWarmCacheAndLockfile: 2126 - withWarmCache: 5858 - withLockfile: 6360 - withWarmCacheAndModules: 3941 - withWarmModulesAndLockfile: 6908 - withWarmModules: 8756 - updatedDependencies: 3034 - size: 313928602 -- firstInstall: 8369 - repeatInstall: 1377 - withWarmCacheAndLockfile: 2132 - withWarmCache: 5812 - withLockfile: 6414 - withWarmCacheAndModules: 4031 - withWarmModulesAndLockfile: 6883 - withWarmModules: 8838 - updatedDependencies: 2916 - size: 313928602 -- firstInstall: 8322 - repeatInstall: 1332 - withWarmCacheAndLockfile: 2079 - withWarmCache: 5617 - withLockfile: 6285 - withWarmCacheAndModules: 3913 - withWarmModulesAndLockfile: 6804 - withWarmModules: 8603 - updatedDependencies: 2817 - size: 313936262 -- firstInstall: 8338 - repeatInstall: 1331 - withWarmCacheAndLockfile: 2088 - withWarmCache: 5620 - withLockfile: 6314 - withWarmCacheAndModules: 3875 - withWarmModulesAndLockfile: 6843 - withWarmModules: 8669 - updatedDependencies: 2858 - size: 313936262 -- firstInstall: 8341 - repeatInstall: 1359 - withWarmCacheAndLockfile: 2103 - withWarmCache: 5613 - withLockfile: 6374 - withWarmCacheAndModules: 3853 - withWarmModulesAndLockfile: 6849 - withWarmModules: 8780 - updatedDependencies: 3088 - size: 313936262 -- firstInstall: 8288 - repeatInstall: 1338 - withWarmCacheAndLockfile: 2097 - withWarmCache: 5750 - withLockfile: 6334 - withWarmCacheAndModules: 3881 - withWarmModulesAndLockfile: 6862 - withWarmModules: 8671 - updatedDependencies: 2974 - size: 313932386 -- firstInstall: 8269 - repeatInstall: 1337 - withWarmCacheAndLockfile: 2081 - withWarmCache: 5676 - withLockfile: 6377 - withWarmCacheAndModules: 3842 - withWarmModulesAndLockfile: 6847 - withWarmModules: 8655 - updatedDependencies: 2904 - size: 313932386 -- firstInstall: 8282 - repeatInstall: 1349 - withWarmCacheAndLockfile: 2170 - withWarmCache: 5765 - withLockfile: 6323 - withWarmCacheAndModules: 3873 - withWarmModulesAndLockfile: 6836 - withWarmModules: 8657 - updatedDependencies: 2957 - size: 313932386 -- firstInstall: 8402 - repeatInstall: 1462 - withWarmCacheAndLockfile: 2243 - withWarmCache: 5935 - withLockfile: 6551 - withWarmCacheAndModules: 4018 - withWarmModulesAndLockfile: 6984 - withWarmModules: 8923 - updatedDependencies: 3168 - size: 313932446 -- firstInstall: 8494 - repeatInstall: 1470 - withWarmCacheAndLockfile: 2247 - withWarmCache: 6091 - withLockfile: 6525 - withWarmCacheAndModules: 4090 - withWarmModulesAndLockfile: 6961 - withWarmModules: 8891 - updatedDependencies: 3244 - size: 313932446 -- firstInstall: 8496 - repeatInstall: 1463 - withWarmCacheAndLockfile: 2254 - withWarmCache: 5925 - withLockfile: 6453 - withWarmCacheAndModules: 4048 - withWarmModulesAndLockfile: 6864 - withWarmModules: 8625 - updatedDependencies: 3018 - size: 313932446 -- firstInstall: 8514 - repeatInstall: 1449 - withWarmCacheAndLockfile: 2217 - withWarmCache: 5878 - withLockfile: 6379 - withWarmCacheAndModules: 3960 - withWarmModulesAndLockfile: 6834 - withWarmModules: 8765 - updatedDependencies: 3123 - size: 313932446 -- firstInstall: 8308 - repeatInstall: 1460 - withWarmCacheAndLockfile: 2189 - withWarmCache: 5790 - withLockfile: 6413 - withWarmCacheAndModules: 3995 - withWarmModulesAndLockfile: 6797 - withWarmModules: 8745 - updatedDependencies: 2993 - size: 313932446 -- firstInstall: 8242 - repeatInstall: 1331 - withWarmCacheAndLockfile: 2076 - withWarmCache: 5682 - withLockfile: 6322 - withWarmCacheAndModules: 3882 - withWarmModulesAndLockfile: 6770 - withWarmModules: 8583 - updatedDependencies: 2858 - size: 313932446 -- firstInstall: 8278 - repeatInstall: 1443 - withWarmCacheAndLockfile: 2214 - withWarmCache: 6022 - withLockfile: 6390 - withWarmCacheAndModules: 3991 - withWarmModulesAndLockfile: 6823 - withWarmModules: 8701 - updatedDependencies: 3062 - size: 313932548 -- firstInstall: 8501 - repeatInstall: 1365 - withWarmCacheAndLockfile: 2147 - withWarmCache: 5873 - withLockfile: 6473 - withWarmCacheAndModules: 3972 - withWarmModulesAndLockfile: 6900 - withWarmModules: 8899 - updatedDependencies: 2963 - size: 313932548 -- firstInstall: 8399 - repeatInstall: 1444 - withWarmCacheAndLockfile: 2221 - withWarmCache: 5953 - withLockfile: 6440 - withWarmCacheAndModules: 4051 - withWarmModulesAndLockfile: 6809 - withWarmModules: 8720 - updatedDependencies: 2981 - size: 313932548 diff --git a/results/yarn_pnp/6.0.0-rc.19/alotta-files-pnpr.yaml b/results/yarn_pnp/6.0.0-rc.19/alotta-files-pnpr.yaml deleted file mode 100644 index b38caad..0000000 --- a/results/yarn_pnp/6.0.0-rc.19/alotta-files-pnpr.yaml +++ /dev/null @@ -1,180 +0,0 @@ -- firstInstall: 4911 - repeatInstall: 0 - withWarmCacheAndLockfile: 157 - withWarmCache: 3993 - withLockfile: 3059 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2827 - size: 304863586 -- firstInstall: 4937 - repeatInstall: 0 - withWarmCacheAndLockfile: 164 - withWarmCache: 3902 - withLockfile: 3041 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2781 - size: 304867682 -- firstInstall: 5042 - repeatInstall: 0 - withWarmCacheAndLockfile: 168 - withWarmCache: 4004 - withLockfile: 3055 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2862 - size: 304863586 -- firstInstall: 4964 - repeatInstall: 0 - withWarmCacheAndLockfile: 148 - withWarmCache: 3709 - withLockfile: 2995 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2702 - size: 304875342 -- firstInstall: 4986 - repeatInstall: 0 - withWarmCacheAndLockfile: 150 - withWarmCache: 3733 - withLockfile: 2991 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2698 - size: 304871246 -- firstInstall: 4941 - repeatInstall: 0 - withWarmCacheAndLockfile: 150 - withWarmCache: 3722 - withLockfile: 3027 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2696 - size: 304867150 -- firstInstall: 4996 - repeatInstall: 0 - withWarmCacheAndLockfile: 155 - withWarmCache: 3747 - withLockfile: 3078 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2775 - size: 304871846 -- firstInstall: 5000 - repeatInstall: 0 - withWarmCacheAndLockfile: 151 - withWarmCache: 3717 - withLockfile: 3008 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2760 - size: 304867750 -- firstInstall: 4954 - repeatInstall: 0 - withWarmCacheAndLockfile: 160 - withWarmCache: 3927 - withLockfile: 3041 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2783 - size: 304863654 -- firstInstall: 5071 - repeatInstall: 0 - withWarmCacheAndLockfile: 168 - withWarmCache: 4032 - withLockfile: 3062 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2788 - size: 304867810 -- firstInstall: 5023 - repeatInstall: 0 - withWarmCacheAndLockfile: 172 - withWarmCache: 3894 - withLockfile: 3032 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2792 - size: 304871906 -- firstInstall: 5007 - repeatInstall: 0 - withWarmCacheAndLockfile: 157 - withWarmCache: 3860 - withLockfile: 3073 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2892 - size: 304876002 -- firstInstall: 4998 - repeatInstall: 0 - withWarmCacheAndLockfile: 153 - withWarmCache: 3914 - withLockfile: 3080 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2737 - size: 304876002 -- firstInstall: 4982 - repeatInstall: 0 - withWarmCacheAndLockfile: 152 - withWarmCache: 3754 - withLockfile: 3070 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2872 - size: 304871906 -- firstInstall: 4873 - repeatInstall: 0 - withWarmCacheAndLockfile: 149 - withWarmCache: 3685 - withLockfile: 3040 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2705 - size: 304867810 -- firstInstall: 5015 - repeatInstall: 0 - withWarmCacheAndLockfile: 157 - withWarmCache: 3777 - withLockfile: 3040 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2701 - size: 304876104 -- firstInstall: 4967 - repeatInstall: 0 - withWarmCacheAndLockfile: 157 - withWarmCache: 3857 - withLockfile: 3066 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2825 - size: 304863816 -- firstInstall: 4972 - repeatInstall: 0 - withWarmCacheAndLockfile: 156 - withWarmCache: 3761 - withLockfile: 3044 - withWarmCacheAndModules: 0 - withWarmModulesAndLockfile: 0 - withWarmModules: 0 - updatedDependencies: 2797 - size: 304867912 From 6d8fb3919056b7cfc3f644d1664748384de0e782 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Wed, 19 Aug 2026 15:36:41 +0200 Subject: [PATCH 2/2] fix: surface warm-up config-copy failures, and clean up the throwaway dir on error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two review findings. The copy loop treated `package.json` and the optional config files alike and swallowed every error — a warm-up that silently lost its `.npmrc` would run against the public registry and hand the update row a cache warmed over the wrong network. The manifest now copies unconditionally and the optional files ignore only ENOENT. And the throwaway directory is removed in a `finally`, so a failed warm-up install doesn't leave `.rewarm` and its cache symlink behind. Co-Authored-By: Claude Opus 5 (1M context) --- benchmarkFixture.js | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/benchmarkFixture.js b/benchmarkFixture.js index b37318a..7100b5f 100644 --- a/benchmarkFixture.js +++ b/benchmarkFixture.js @@ -393,16 +393,24 @@ export default async function benchmark (pm, fixture, opts) { const rewarmDir = path.join(cwd, '.rewarm') rimraf.sync(rewarmDir) await fs.mkdir(rewarmDir, { recursive: true }) - for (const name of ['package.json', '.npmrc', 'pnpm-workspace.yaml', '.yarnrc.yml', '.yarnrc']) { - try { - cpSync(path.join(cwd, name), path.join(rewarmDir, name)) - } catch { - // A file a manager doesn't use was never written; nothing to copy. + try { + cpSync(path.join(cwd, 'package.json'), path.join(rewarmDir, 'package.json')) + for (const name of ['.npmrc', 'pnpm-workspace.yaml', '.yarnrc.yml', '.yarnrc']) { + try { + cpSync(path.join(cwd, name), path.join(rewarmDir, name)) + } catch (err) { + // A file a manager doesn't use was never written; nothing to copy. + // Anything else has to surface: a warm-up that silently lost its + // `.npmrc` would run against the public registry and hand the update + // row a cache warmed over the wrong network. + if (err?.code !== 'ENOENT') throw err + } } + await fs.symlink(path.join(cwd, 'cache'), path.join(rewarmDir, 'cache'), 'dir') + measureInstall(pm, rewarmDir, env) + } finally { + rimraf.sync(rewarmDir) } - await fs.symlink(path.join(cwd, 'cache'), path.join(rewarmDir, 'cache'), 'dir') - measureInstall(pm, rewarmDir, env) - rimraf.sync(rewarmDir) console.log('# with updated dependencies')