Next.js 8 Webpack Memory Improvements
Key Points
- concurrency-limited asset writes
- enable output.futureEmitAssets
- allocations reduced to ~184KB chunks
Summary
Next.js 8 includes upstream webpack optimizations that drastically reduce build-time heap usage when compiling many pages. The team identified large, simultaneous allocations caused by calling asset.source() concurrently for every file and by CachedSource holding generated output in memory. They fixed it by limiting concurrent asset writes and opting into a new webpack emit behavior that avoids unnecessary in-memory caching.
Key Points
- Problem: webpack was generating all asset sources concurrently (via asyncLib.forEach), causing very large one-time allocations (observed ~548 MB) that scaled with number of pages.
- Fix 1: Limit concurrency when iterating compilation.assets (e.g., asyncLib.forEachLimit with a practical limit like 15) to spread allocations over time (reduced chunks to ~34 MB).
- Fix 2: Use webpack's output.futureEmitAssets behavior to avoid keeping CachedSource results in memory after emit (further reduced allocation chunks to ~184 KB).
- Result: Significant drop in peak and incremental allocations; Next.js 8 ships these changes by default, but webpack users can opt in to the same improvements.
- Practical advice for engineers:
- Upgrade to Next.js 8 (or a webpack release that includes output.futureEmitAssets) to get the fixes out of the box.
- If running custom build pipelines, limit concurrent asset writes when iterating compilation.assets (start with ~15) and enable output.futureEmitAssets when available.
- Profile builds with Chrome DevTools/Node inspector to verify allocation patterns and tune concurrency.