Cook & Packaging Performance
Cook time is iteration tax. Epic Games Japan reported a 14× speedup on iterative cooks (815s → 58s) using multi-process cook with UE 5.4. UE 5.5 added Zen Server as production-ready shared DDC, UE 5.6 added BC7-RDO encoding 25–30% faster, and UE 5.7 fixed ~99% of incremental-cook false-positive recooks. This tutorial covers the cook pipeline, DDC strategy, the multi-process / iterative / incremental cook ladder, IoStore vs pak vs Zen, and the regressions to gate in CI.
The cook pipeline at a glance
Editor → CookCommandlet → staging → pak / IoStore / Zen container. Time goes to:
- Asset compile (textures, meshes, navigation).
- Shader compile (largest line on most projects; can take hours).
- Package serialize.
- Container build (pak/IoStore/Zen).
Most cook-time wins come from (1) reducing the surface (skip editor-only content, deduplicate via Shader Permutation Reduction), (2) parallelizing (multi-process cook), and (3) caching aggressively (DDC + iterative/incremental).
DDC strategy — local, shared, Zen
Three layers of derived data cache:
- Local DDC — per-engineer NVMe SSD. Default ~200–500 GB. Fast warm hits; cold miss falls through.
- Shared DDC — UNC path (filesystem) or S3 bucket (cloud). Multi-TB. Team-wide cache; warm hits across machines.
- Zen Server — UE 5.5+ default for new projects. Replaces filesystem shared DDC for production. Ships
zen.exe, runs as a service, supports hot/cold tiering.
The senior pattern: UE-LocalDataCachePath + UE-SharedDataCachePath env vars override DefaultEngine.ini. Verify with DerivedDataCache.DumpUsage — reading INI alone doesn't tell you what's actually being used.
Zen Server deep dive
Zen does three things:
- Zen as DDC — replaces filesystem shared DDC. Better invalidation, hot/cold tiers.
- Zen as cooked output store —
bUseZenStore=trueinDefaultGame.ini(or "Use ZenStore as cooking output" in Project Settings). Replaces pak as the storage backend for cooked content. - Zen Loader — default-on in 5.5. Cuts runtime dependency-graph processing "from seconds down to milliseconds" by moving EDL prep offline (per Epic Zen Loader docs).
Configure auto-launch:
[Zen] AutoLaunch=true
Zen's local-project store lives under %LOCALAPPDATA%\UnrealEngine\Common\Zen\ by default; teams have hit C: drive exhaustion until they redirect.
IoStore vs pak vs Zen container
Three cooked output formats:
- pak — UE4 legacy. Single .pak archive per chunk.
- IoStore (.ucas/.utoc) — UE 5.0+. Optimized for SSD streaming. Default for shipped UE5 titles.
- Zen container — 5.5+ next-gen. Runtime-streamable, supports IoStoreOnDemand for install-on-demand patterns.
Zen Server on PS5 streaming: ~1.8× faster app launch, ~3.1× faster map loads vs pak (per Unreal Fest 2024).
Multi-process cook
Multi-process cook (Director/Worker model) shipped in 5.3 stable. Configuration:
[CookSettings]
CookProcessCount=8 ; Worker count; tune by RAM, not just coresOr via UAT BuildCookRun: -AdditionalCookerOptions="-cookprocesscount=8".
Scaling: doubling cores does not double throughput — each worker needs its own RAM (~8–16 GB), shader compilation contention dominates above ~6 workers on most projects. Sweet spot is typically 4–6 workers on a 32 GB build farm machine.
-CookProcessCount=N workers crash if the .uproject isn't at the canonical UnrealEngine/<Project>/<Project>.uproject-style path. Persists in projects with relocated uprojects.
Iterative vs incremental cook
-iterate— reusesSaved/Cooked/from prior cook. Fast for unchanged content. Epic UE 5.4 reported 815s → 58s (~14×).-cookincremental— UE 5.5+; Zen-aware incremental cook. ReportsPackages Cooked: N, Packages Iteratively Skipped: M.
UE 5.6 ships ~20% recook rate due to non-deterministic dependencies. UE 5.7 fixes ~99% of engine-type incremental dependency false positives. For project script types, opt in explicitly:
[CookSettings] +IncrementalClassScriptPackageAllowList=Allow,/Game
Validate with BuildGraph task IncrementalValidate -diffonly — detects false incremental skips.
Cooker memory tuning
[CookSettings] MemoryMaxUsedPhysical=16384 ; MiB cap on cooker MemoryMaxUsedVirtual=0 ; 0 = unlimited MemoryMinFreePhysical=1024 ; MiB headroom requirement
ShaderCompileWorkers can blow through 32 GB during cook; throttle with r.ShaderCompilingMaxMemoryPercentage. On 32 GB build farms with 6 multi-process workers + ShaderCompileWorker fan-out, OOM is the typical failure mode — cap memory aggressively.
Build farm cooks
The shipped pattern for shipping titles: Horde + Zen shared DDC + Zen cook snapshots + -buildmachine. The flags:
RunUAT BuildCookRun -project=YourGame.uproject ^
-platform=Linux+Win64 ^
-cook -stage -archive ^
-archivedirectory=Builds/ ^
-unattended -buildmachine ^
-compressed -pak -iostore-buildmachine enables detailed cook timing CSV, error logging, no warning cap, no crash dialogs. -unattended suppresses modal dialogs (forgetting it = hung cook waiting on dialog).
Cook-time regression checklist
Run on every CI pull:
- Total cook wall time — alert if >X% above baseline.
- Incremental skip ratio — alert if it drops below project baseline (the canonical "non-deterministic dep crept in" signal).
- Per-class cook time deltas — texture, shader, world. Catches asset-class regressions.
- OOM tracking — ShaderCompileWorker memory peaks above headroom triggers alert.
- Final pak/IoStore/Zen size — alert on growth without corresponding feature flag.
PerfGuard can shell out to UnrealEditor-Cmd -run=cook -platform=... -unattended -trace=default -tracefile=<path> and parse the cooker summary line plus Unreal Cooking Insights trace. CI gate: alert when incremental skip ratio drops, when per-class cook time deltas exceed budget, when total wall time grows. Catches the silent regression Epic forums document — "code change quietly invalidates 20% more packages, adds 4–10 minutes per CI run."
- Loading Time Optimization — Zen Loader is shared with cooked-data loading.
- Memory & VRAM Optimization — cooker memory and shipped memory share many CVars.
- Memory & VRAM Optimization — cooker memory caps and shipped-build memory share many CVars.