Unreal Engine 5.8 tutorial

Part 9 — Optimization & profiling

Measure and fix performance in Unreal Engine 5.8: CPU vs GPU budgets, stat unit, Unreal Insights, and the common wins that turn a tech demo into a shippable game.

You’re a developer, so you know: measure, don’t guess. Performance work is the difference between a tech demo and a shippable game.

9.1 The two budgets

A frame must fit in your target time: 16.6 ms for 60 fps, 33.3 ms for 30. Two parallel budgets:

  • Game thread (CPU) — your gameplay logic, ticks, AI, physics setup.
  • GPU — rendering: triangles, overdraw, shadows, post-processing, lighting.

Find which one you’re bound by first; optimizing the other won’t help.

9.2 Tools

  • stat fps, stat unit (console, backtick ~ key) — unit shows Frame / Game / Draw / GPU ms. This tells you CPU-bound vs GPU-bound at a glance.
  • stat GPU — GPU cost broken down by pass.
  • Unreal Insights — the heavy-duty timeline profiler (trace a session, analyze CPU/GPU/memory frame by frame). Your “perf flame graph.”
  • GPU Visualizer (Ctrl+Shift+,) — per-pass GPU timing.
  • Shader Complexity / Quad Overdraw view modes (Viewport → View Mode) — visualize expensive shaders and overdraw as heatmaps.
  • stat Game, LLM (memory), obj list — memory and object tracking.

9.3 Common wins (developer instincts apply)

  • Kill unnecessary Tick. Per-frame work over many actors is the classic CPU sink. Use timers, events, and overlap callbacks instead. (PrimaryActorTick.bCanEverTick = false by default.)
  • Reduce draw calls. Instancing, Static Mesh merging, HLODs. Nanite helps a lot here.
  • Mind the lights. Dynamic shadowed lights were historically expensive; MegaLights changes the math, but shadow casting still costs. Cull shadows on small lights.
  • Object pooling. Spawning/destroying is costly; pool bullets/effects like any high-churn allocation.
  • LODs & culling. Distance culling, occlusion culling, and (for non-Nanite meshes) LODs. Nanite automates geometric LOD.
  • Async everything heavy. Load assets async (don’t hitch on LoadObject at runtime); use async traces where possible.
  • Profile on the target device, not just your beefy dev machine. A 60 fps editor scene can be 20 fps on a console/handheld.
Exercise 9 — WISP milestone

Run stat unit in the lit Hollow zone. Are you Game- or GPU-bound? (With many beacon lights + Niagara, you may be GPU-bound — a useful, realistic lesson.) Use Unreal Insights to find your most expensive function or pass, find one Shade or Mote doing per-frame Tick work that could be event-driven, convert it, and re-measure. Measure, change one thing, re-measure — that’s the whole discipline.