Next.js 16.3's most concrete promise is that next build duration drops noticeably on repeat builds. The disk-based file system cache Turbopack's dev server has used since 16.1 has now moved to next build too, with the 16.3 release published on August 3, 2026, enabled by default. This post covers the two separate config keys the cache uses, how to make it persistent in CI, why build-lock discipline is still mandatory on an 8GB VPS, and the extra gain from the experimental Rust-based React Compiler.
💡 Pro Tip:turbopackFileSystemCacheForBuildcomes enabled by default; simply upgrading to Next.js 16.3 without doing anything else already brings the first gain — the real work is keeping the.next/cachedirectory persistent across builds in CI.
Table of Contents
- What Changed in 16.3: Two Things
- Version History
- Where the Cache Lives, What It Invalidates
- Moving the Cache in CI
- Building on an 8GB Server: RAM Pre-Check and Build-Lock Requirement
- Measurement: Cold vs Cached Build Comparison
- When the Cache Lies, and How to Clear It
- Combined Gains with the Experimental Rust React Compiler
- FAQ
- How do I enable the Turbopack FileSystem cache?
- Why is next build still slow, and why does the cache miss?
- How do I reduce the dev server's RAM consumption?
- How do I make the Turbopack cache persistent in CI?
- Are disk cache and memory eviction the same thing?
- When should I turn off turbopackFileSystemCacheForBuild?
- Does disk cache change production behavior (the output)?
- Conclusion
- Sources
What Changed in 16.3: Two Things
The 16.3 announcement covered two separate but related features at once: "The disk caching feature that's been speeding up dev since 16.1 now works with next build and is enabled by default." The dev-side disk cache mechanism now also works on the build side, with no extra setting needed.
The second feature is a separate mechanism: turbopackMemoryEviction, released experimentally in 16.3.0 with default mode 'auto'. Per the official docs, this setting only applies to next dev sessions and requires disk cache to be enabled, since data evicted from memory gets read back from disk. There's no separate memory eviction mechanism on the build side.
Don't confuse the two — both share the word "cache" but solve different problems. Disk cache avoids recomputing compilation output, helping both dev and build. Memory eviction only prevents RAM from bloating in long-running dev sessions and isn't part of the build process. You can disable each independently, but their default — both enabled — is the right starting point for most projects.
Version History
Bringing the cache to build didn't happen overnight. The official config reference gives this chronology:
Version | Change |
|---|---|
v15.5.0 | Persistent cache released experimentally in canary releases |
v16.0.0 | Beta with separate flags for build and dev |
v16.1.0 | File system cache enabled by default for dev |
v16.3.0 | File system cache enabled by default for build |
As of writing (2026-09-23), the latest tag of next on npm is 16.3.6; canary is 16.4.0-canary.40. So 16.4 isn't stable yet — verify the current version yourself with npm view next version.
Where the Cache Lives, What It Invalidates
Two separate keys write to two separate directories. turbopackFileSystemCacheForDev (default true) writes under .next/dev/cache/turbopack; turbopackFileSystemCacheForBuild (default true) writes under .next/cache/turbopack. There's no single unified turbopackFileSystemCache key — the config reference lists two separate booleans.
Exactly how much of the cache invalidates when which input changes isn't officially documented; the behavior you can rely on in practice: with disk cache enabled, Turbopack reads the disk entries before compiling new changes; unchanged artifacts come from disk instead of being regenerated.
1# To see which caches are enabled in your next.config.js2node -e "console.log(require('./next.config.js'))"Moving the Cache in CI
Whether the cache speeds up the build depends on one condition: the .next/cache directory being preserved across runs. The official docs state it plainly: "Builds only get faster when that directory is restored before each build." Without restoring it, every build starts from scratch even with disk cache enabled.
On self-hosted builds — servers reusing the same working directory across builds — the cache persists automatically. Containerized builds differ: since each build starts from a clean layer, you need to explicitly mount or cache .next/cache.
Next.js's official "CI Build Caching" guide recommends an actions/cache step for GitHub Actions, and describes the same approach for Vercel, CircleCI, Travis, GitLab, Netlify, AWS CodeBuild, Bitbucket, Heroku, Azure Pipelines, and Jenkins — all targeting .next/cache. Whichever provider you use, the question is the same: does the build environment carry .next/cache forward to the next run? On platform builds like Vercel this is usually automatic; if you manage your own CI runner (GitHub Actions, GitLab CI, Jenkins), you define this step yourself.
1# GitHub Actions — carry .next/cache across builds2- name: Cache Next.js build output3 uses: actions/cache@v44 with:5 path: .next/cache6 key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}If your build environment never preserves .next/cache — e.g. it always starts from a clean container layer — the official recommendation is to set turbopackFileSystemCacheForBuild: false to avoid writing the cache for nothing.
1// next.config.js — if the build environment never persists the cache2module.exports = {3 experimental: {4 turbopackFileSystemCacheForBuild: false,5 },6};Building on an 8GB Server: RAM Pre-Check and Build-Lock Requirement
There's no official build-time peak memory measurement for Turbopack; the up-to-90% memory reduction in the 16.3 announcement belongs to next dev sessions, not build. So on an 8GB VPS, safety isn't an official Next.js guarantee — it's your own operational discipline.
In practice: check available RAM before starting a build, and make sure a second next build process isn't running at the same time (pgrep -f 'next build'). On an 8GB server, two concurrent builds can cut off each other's .next/standalone output midway, sending the service into a MODULE_NOT_FOUND restart loop. Disk cache itself neither raises nor lowers this risk — it's just a data structure on disk; extra peak RAM comes from the build's normal compilation process.
- RAM pre-check: verify the minimum free memory threshold before starting the build.
- Build-lock: block concurrent
next buildprocesses withpgrep. - Swap margin: leave a swap layer above RAM so the build doesn't hit OOM at its peak.
These three items aren't about disk cache itself — they're the general discipline of running any Node.js build on a resource-constrained server. Even with disk cache enabled, the build still builds the dependency graph in memory and compiles in memory; the cache only skips recomputing the unchanged part, it doesn't mean zero memory use. So dropping build-lock or the RAM pre-check on the assumption "caching means less RAM now" is a wrong inference — the two solve different problems.
Same logic for swap: it covers the build's temporary peak, while the cache reduces total work across repeated builds. On an 8GB-or-less server, using both together is safer than relying on either alone.
Measurement: Cold vs Cached Build Comparison
The Next.js 16.3 announcement shared three real project measurements in a table. The official numbers are as follows:
Project | Cold build | Cached build | Gain |
|---|---|---|---|
vercel.com/geist | 30s | 5.5s | ~5.5× |
nextjs.org | 21s | 9.2s | ~2.3× |
vercel.com/home | 66s | 46s | ~1.4× |
The announcement also says "…are seeing some projects with 5.5x faster builds on CI." Worth noting: 5.5× is the best case, measured in a single project (vercel.com/geist); the actual range across the official examples runs from 1.4× to 5.5×. Where your own project lands in that range depends on codebase size and how much actually changes between builds — no official formula exists for this.
The most reliable way to see your own project's real gain is to measure two builds yourself. A simple timestamp in your CI step is enough:
1# To measure and log build duration in a CI step2time next buildRun this under two different conditions: once with .next/cache empty (cold), and once after it's restored (cached). The difference will reflect your own codebase's build behavior much more than the 1.4×-5.5× range given in the table — which files get recompiled with the next change directly determines the cache's hit rate.
When the Cache Lies, and How to Clear It
Next.js's official docs don't have a separate "broken cache" or "stale cache" troubleshooting page. The two verified behaviors: the cache gives no speedup if it isn't restored (the CI section above), and it can be fully disabled with turbopackFileSystemCacheForBuild: false.
The safest move when you're suspicious is to delete .next/cache and run the build from scratch — this forces a full cold build without disabling the cache, giving you a reference point.
1# To clear a suspicious cache and get a full cold build2rm -rf .next/cache3next buildBeyond this there's no "cache validation" API or official debug command; the reference method is deleting .next/cache and taking a cold build.
In practice, most moments where the cache seems to be "lying" come down to the CI scenario above: it was never restored, or restored with the wrong key. Ask two questions first: does the CI step actually restore .next/cache, and does the restored cache belong to the current lockfile or an old dependency set? Check these before touching the config flags.
Combined Gains with the Experimental Rust React Compiler
Another piece affecting build speed in 16.3 is the experimental Rust-based React Compiler integrated into Turbopack. Per the announcement, early tests observed 20-50% compilation gains in large React apps (Vercel's v0 cited as an example): "Promising early tests against large React apps like v0 showed compilation wins of 20-50%."
Stable, Babel-based React Compiler support has been available since 16.0. To try the Rust-based native version, enable the React Compiler itself and additionally use the experimental turbopackRustReactCompiler flag.
1// next.config.js — experimental Rust React Compiler2module.exports = {3 reactCompiler: true,4 experimental: {5 turbopackRustReactCompiler: true,6 },7};These two gains are independent: disk cache skips the unchanged part in repeated builds, while the Rust React Compiler speeds up compiling the part that changed. Enabling both together doesn't conflict.
Concretely: when only a handful of components change in a PR, disk cache skips recompiling the unchanged hundreds of files, while the Rust React Compiler kicks in on those few changed components. Since both mechanisms are experimental, trying them together in staging before a large prod build is a reasonable order — especially since turbopackRustReactCompiler is still experimental.
GOLDEN TIP
The most valuable insight in this article
This tip holds the article's most important takeaway.
Easter Egg
You found a hidden gem!
There's a hidden detail in this section. Want to uncover it?
Reader Reward
If you're going to enable Turbopack disk cache on your own project after reading this piece, applying the checklist below in order will make it clear whether it's actually speeding up your builds. The list is a tidy summary of the steps covered in the sections above.
FAQ
How do I enable the Turbopack FileSystem cache?
In Next.js 16.1+, the dev cache (turbopackFileSystemCacheForDev) already comes enabled by default; in 16.3+, so does the build cache (turbopackFileSystemCacheForBuild) — no separate activation step needed. Turn either off by setting it to false under experimental in next.config.js; otherwise nothing is required.
Why is next build still slow, and why does the cache miss?
The most common reason: the build environment doesn't preserve .next/cache between runs. This is especially true when containerized CI starts from a clean layer every time — the cache can never be read. Fix it by explicitly caching or mounting this directory on your CI provider; if that's not possible, disable the cache with turbopackFileSystemCacheForBuild: false.
How do I reduce the dev server's RAM consumption?
In 16.3, Turbopack's new turbopackMemoryEviction mechanism (default mode 'auto'), which works alongside disk cache, significantly reduces dev memory usage on large projects — up to 90% in the official examples. No extra action needed; upgrading to 16.3 is enough.
How do I make the Turbopack cache persistent in CI?
The next build cache is written under .next/cache; this directory provides no speed gain at all unless it's preserved between workflow runs. This is usually automatic on self-hosted builds; manual cache/mount configuration is required on containerized CI.
Are disk cache and memory eviction the same thing?
No. Disk cache (turbopackFileSystemCacheForDev/ForBuild) writes and reads compilation output to/from disk; it works in both dev and build. turbopackMemoryEviction is a separate mechanism that evicts data from memory only in next dev sessions, and requires disk cache to be enabled to work.
When should I turn off turbopackFileSystemCacheForBuild?
Only when the build environment can't preserve .next/cache across builds at all. If the cache stays enabled there, you pay the write cost at the end of every build but never benefit from the read side — the official recommendation is to set the flag to false in this scenario to skip the unnecessary write.
Does disk cache change production behavior (the output)?
The official docs describe the cache only as a compilation speedup mechanism; there's no statement that it changes the produced output's content. The safest way to get a reference point when in doubt is a full cold build via the "clearing the cache" step above, then compare the output.
Conclusion
The Turbopack disk cache in Next.js 16.3 is one of the rare features that can speed up next build with a single upgrade — but only teams that keep .next/cache persistent in CI see the real gain. The official examples range from 1.4× to 5.5×; your own number depends on your dependencies' size and how often they change.
For related version transitions and surrounding ecosystem decisions, see the Next.js 16.3 Instant Navigations and Cache Components guide, the transition from Edge Runtime removal to Node, the decision to migrate to the TypeScript 7 Go compiler, and Prisma 6.7-6.8's shift after the Rust engine. On the bundler side, the webpack to Vite migration guide is also a useful comparison.
Sources
- Next.js 16.3 announcement — the arrival of cache in build, memory eviction figures, and the CI measurement table.
- Next.js 16.3 Turbopack deep-dive post — Rust React Compiler and extended memory/CI data.
- turbopackFileSystemCache config reference — the two separate keys, directory paths, and the version history table.
- turbopackMemoryEviction config reference — the experimental memory eviction mechanism and its dev-only constraint.
- Next.js CI Build Caching guide — persistent cache examples for GitHub Actions, GitLab, CircleCI, and other providers.
- npm registry dist-tags: next — version verification as of writing (2026-09-23).
Tags
iOS Development News
Weekly Swift tips, SwiftUI tricks and iOS best practices. No spam, only valuable content.
Your subscription starts when you open the link in the confirmation email and press “Confirm my subscription”. The newsletter keeps open/click statistics; you can unsubscribe anytime with one click. Privacy
