|
| 1 | +# Experiment: is the Turbopack FS build cache a net win? |
| 2 | + |
| 3 | +**Do not merge.** This branch exists to produce three measurements and then be closed. |
| 4 | + |
| 5 | +## Question |
| 6 | + |
| 7 | +`NEXT_TURBOPACK_BUILD_CACHE=1` was added in #5869 on the premise that a warm Turbopack |
| 8 | +filesystem cache makes `next build` faster. Observational data from 2026-07-29 suggests the |
| 9 | +opposite: |
| 10 | + |
| 11 | +| cache state | pre-build disk | compile | |
| 12 | +|---|---|---| |
| 13 | +| genuinely cold, FS cache on | 4.0K | **1.8 min** | |
| 14 | +| perfect-warm, FS cache on (written 50s earlier) | 5.1G | **4.0 min** | |
| 15 | +| mismatched-warm, FS cache on (old event-only key) | — | **11.3 min** | |
| 16 | +| FS cache absent entirely (13 runs before #5869) | n/a | **2.2–3.6 min, median 2.7** | |
| 17 | + |
| 18 | +Cold < perfect-warm < mismatched-warm. If that ordering is real, the cache is costing wall |
| 19 | +time and the correct action is to turn it off. |
| 20 | + |
| 21 | +All four rows are observational, from runs that differed in commit as well as cache state. |
| 22 | +This branch holds the tree constant and varies only the cache. |
| 23 | + |
| 24 | +## Method |
| 25 | + |
| 26 | +Three sequential runs on this one branch. Each commit touches **only** `.github/**` + |
| 27 | +this file, so the Next module graph is byte-identical across all three — cache-match |
| 28 | +quality is held constant and only cache *state* varies. |
| 29 | + |
| 30 | +| run | commit | `NEXT_TURBOPACK_BUILD_CACHE` | expected disk state | |
| 31 | +|---|---|---|---| |
| 32 | +| A | first push | `'1'` | **cold** (brand-new per-branch sticky key) | |
| 33 | +| B | trivial edit | `'1'` | **warm**, written by A, identical module graph | |
| 34 | +| C | flip the env | `'0'` | irrelevant — Turbopack ignores the on-disk cache | |
| 35 | + |
| 36 | +Read from each Build App log: `Report Next.js cache size (pre-build)`, |
| 37 | +`Compiled successfully in X`, `Report Next.js cache size (post-build)`. |
| 38 | + |
| 39 | +## Two traps this design defuses |
| 40 | + |
| 41 | +1. **Turbo task-cache replay.** A `.github`-only commit leaves Turbo's task inputs |
| 42 | + unchanged, so Turbo would replay a cached log and reprint a *stale* compile time from an |
| 43 | + unrelated run — fabricating the number being measured. `--force` makes every run a real |
| 44 | + build. Five such phantom runs had to be discarded from the observational data. |
| 45 | +2. **Cancelled-run confusion.** `ci.yml` sets `cancel-in-progress` for pull_request events, |
| 46 | + so pushing before a run finishes cancels it — and a cancelled run still writes its |
| 47 | + partial cache to the sticky disk. A prior conclusion ("a brand-new sticky key is not |
| 48 | + cold") was wrong for exactly this reason: the "first" run had a cancelled sibling 3 |
| 49 | + minutes earlier that had already committed 5.1 GB. **Each run here must reach |
| 50 | + `completed` before the next push.** |
| 51 | + |
| 52 | +## Result |
| 53 | + |
| 54 | +Filled in as runs land. |
| 55 | + |
| 56 | +| run | pre-build | compile | post-build | run id | |
| 57 | +|---|---|---|---|---| |
| 58 | +| A — cold, cache on | | | | | |
| 59 | +| B — warm, cache on | | | | | |
| 60 | +| C — cache off | | | | | |
0 commit comments