By inserting stat macros into C++ code, you can mark specific code blocks for timing measurement. The data collected here feeds into both Unreal Insights and the stat console commands.
Declared at the top of a .cpp file to categorize related stats
DECLARE_CYCLE_STAT(StatName, StatId, GroupName)
Declare a cycle counter stat
Typically declared at file scope
SCOPE_CYCLE_COUNTER(StatId)
Measure the time spent in the current scope
Automatically recorded when the scope exits
QUICK_SCOPE_CYCLE_COUNTER(StatId)
Declare and measure in one step
No separate DECLARE needed — one-liner
SCOPED_NAMED_TIMER(Text, Flags)
Quick named timer
No pre-declaration required; identifies by string
Typical usage:
1 2 3 4 5 6 7 8 9 10 11 12
// Declarations at the top of the file DECLARE_STATS_GROUP(TEXT("MyGame"), STATGROUP_MyGame, STATCAT_Advanced); DECLARE_CYCLE_STAT(TEXT("ProcessAI"), STAT_ProcessAI, STATGROUP_MyGame);
voidAMyActor::Tick(float DeltaTime) { Super::Tick(DeltaTime); // Measure the entire function body SCOPE_CYCLE_COUNTER(STAT_ProcessAI); // ... AI logic ... }
Scene rendering stats (Draw Calls, triangle count, visible object count)
stat engine
Core engine stats
stat streaming
Asset streaming stats
stat memory
Memory usage overview
stat particles
Particle system stats
stat physics
Physics simulation stats
stat net
Network stats
stat dumphitches
Log hitch information to the output log
Reading the Key Metrics
1 2 3 4 5 6 7 8 9 10 11
Example stat unit output: Frame: 33.2 ms ← Total frame time (target is 16.67ms = 60fps) Game: 12.1 ms ← Game Thread (logic / AI / animation) Draw: 5.3 ms ← Render Thread (render command preparation) RHI: 4.1 ms ← RHI Thread (GPU command submission) GPU: 18.7 ms ← Actual GPU render time
Identifying the bottleneck: - Game high → optimize logic code (reduce Ticks, optimize AI) - Draw high → reduce visible objects, improve LOD, culling - GPU high → optimize materials / lighting / post-processing
Custom Stat Groups
1 2
// Once a custom group is declared, view it in the console with: stat MyGroup DECLARE_STATS_GROUP(TEXT("My Game Stats"), STATGROUP_MyGame, STATCAT_Advanced);
Advanced Stat Commands
Command
Description
stat startfile
Start recording stats to a file
stat stopfile
Stop recording; produces a .ue4stats file that can be opened in Unreal Insights
stat dumphitches
Enable hitch logging; prints the call stack to the log when a threshold is exceeded
t.MaxFPS 60
Cap the maximum frame rate
r.VSync 0
Disable V-Sync for raw performance testing
4. GPU Analysis Tools
4.1 ProfileGPU (Console Command)
Entering ProfileGPU outputs a breakdown of GPU passes for the current frame in the Output Log:
1 2 3 4 5 6
Scene (18.2ms) ├── Base Pass (6.1ms) ├── Shadow Pass (3.2ms) ├── Lighting (4.8ms) ├── Translucency (2.1ms) └── Post Process (2.0ms)
4.2 GPU Visualizer (vis Command)
Command
Description
vis
Open the GPU Visualizer window
ProfileGPU
Single-frame GPU profile
r.ScreenPercentage 50
Lower render resolution to test GPU load
4.3 RenderDoc / PIX
RenderDoc: A general-purpose GPU frame analyzer with UE5 support. Lets you inspect pixel history and shader resources per Draw Call.
PIX (Windows): Microsoft’s GPU profiling tool, particularly well-suited for Xbox / DirectX projects.
Xcode GPU Profiler (macOS/iOS): GPU profiling for the Metal platform.
Note: This functionality (originally a UE4 feature) has been integrated into the GPU view inside UE5’s Unreal Insights.
5. Memory Analysis
Tool / Command
Description
obj list
List all UObjects and their memory usage
obj list class=StaticMesh
List objects of a specific class
memreport -full
Generate a full memory report
stat memory
Live memory statistics
mimalloc
UE5’s optional modern memory allocator (configured in .ini)
6. Blueprint Profiling
Blueprint Profiler: Editor menu Tools → Blueprint Profiler
Inspect execution time per Blueprint node to identify slow ones
Optimization tip: migrate hot-path Blueprint logic to C++
7. Debugging Tips
7.1 UE_LOG Timestamp Timing
A quick way to measure how long a code segment takes — just print timestamps to the log:
Subtract the two timestamps to get the actual elapsed time for that code segment (roughly 15 seconds in this example).
7.2 Disabling Local Compiler Optimizations
During debugging, compiler optimizations can interfere with breakpoints and variable inspection. You can temporarily disable them for a specific block of code:
1 2 3 4
#pragma optimize("", off) // Place the function or code you want to debug here // Optimizations are off — variables won't be eliminated, breakpoints will hit normally #pragma optimize("", on)
"" means use the current project’s optimization option set
off/on temporarily disables and re-enables optimization
Only affects code from the off pragma onward (until the matching on); typically wraps a single function implementation
1. Identify the Bottleneck stat fps + stat unit → determine whether it's a CPU or GPU bottleneck
2. CPU Bottleneck ├─ stat unitgraph → identify which thread is slow ├─ Unreal Insights Timing → pinpoint the specific function ├─ Check Tick, Blueprints, GC, physics └─ Use SCOPE_CYCLE_COUNTER for finer-grained measurement
3. GPU Bottleneck ├─ ProfileGPU → inspect pass distribution ├─ stat scenerendering → Draw Calls / triangle count ├─ GPU Visualizer → visual analysis └─ RenderDoc → deep dive into individual Draw Calls