Quick answer: Unreal Insights is the modern profiling framework introduced in UE 4.26 that replaces the legacy session frontend profiler. It captures traces to a .
This Unreal insights performance profiling guide covers everything you need to know. Unreal Engine is capable of stunning visuals, but that power comes with complexity that can tank performance in unexpected ways. A single misconfigured material, an over-eager Blueprint tick, or an unculled mesh in the distance can cost you 5 milliseconds per frame. Unreal Insights is the engine's modern profiling framework, and it is the single most important tool for understanding where your frame budget goes. This guide covers everything from capturing your first trace to interpreting GPU pass timings and fixing the bottlenecks you find.
Stat Commands: Quick Diagnostics
Before diving into Unreal Insights traces, use stat commands for a quick read on your game's health. Open the console with the backtick key and type these commands. They overlay real-time information on the viewport:
stat fps // Frame rate and frame time in milliseconds
stat unit // Game thread, render thread, GPU, and total frame time
stat unitgraph // Visual graph of the above over time
stat scenerendering // Draw calls, mesh draw commands, render pass times
stat gpu // Per-pass GPU timing (requires GPU profiling enabled)
stat game // Game thread breakdown by category
stat memory // Memory usage by category
The stat unit command is the most important starting point. It shows four numbers: Frame, Game, Render, and GPU time. The frame time is bounded by the slowest of the other three. If Game is 18ms, Render is 8ms, and GPU is 12ms, you are game-thread bound. Fix your gameplay code first.
Understanding Unreal's Thread Model
Unreal runs on three primary threads that pipeline work across frames. Understanding this model is critical for interpreting profiling data correctly:
The Game Thread runs all gameplay logic: Blueprint ticks, C++ actor ticks, animation updates, physics simulation, AI behavior trees, and input processing. The Render Thread translates the scene into draw commands: visibility culling, material setup, draw call submission, and particle system updates. The GPU executes the draw commands: vertex processing, pixel shading, post-processing, and buffer swaps.
These threads overlap. While the GPU renders frame N, the render thread prepares frame N+1, and the game thread simulates frame N+2. A spike on any thread eventually stalls the others when they reach a synchronization point. The stat unit numbers reflect this pipelining, so a GPU spike may not appear as a frame drop until a frame or two later.
Capturing a Trace with Unreal Insights
Unreal Insights captures traces to .utrace files that you analyze after the session. This is more powerful than real-time stat commands because you can scrub through seconds of data, zoom into individual frames, and compare frame timings across the entire session.
// Launch from command line with trace channels enabled
$ ./MyGame.exe -trace=cpu,gpu,frame,bookmark,memory
// Or enable tracing at runtime via console commands
Trace.Start cpu,gpu,frame,bookmark
// ... play through the problem area ...
Trace.Stop
// Trace files are saved to:
// {ProjectDir}/Saved/TracingProfiles/
For editor profiling, use the Trace menu in the toolbar. Select the channels you want (CPU Timing, GPU Timing, Frame Timing, Memory) and click Start Trace. Play in Editor, reproduce the issue, then stop the trace. The .utrace file appears in the Saved directory.
Open the trace in the standalone UnrealInsights application (found in Engine/Binaries) or from the Session Frontend in the editor. The standalone application is faster for large traces and does not compete with the editor for resources.
Timing Insights: Reading the Timeline
The Timing Insights view is the core of Unreal Insights. It displays a timeline where each row represents a thread and each block represents a timed scope (a function or engine subsystem). The horizontal axis is time. Wider blocks took longer.
Zoom in on a spike frame. The game thread row shows the tick hierarchy: UWorld::Tick contains TickTaskManager, which contains individual actor ticks. Look for unusually wide blocks. Click on a block to see its duration, call count, and child breakdown in the details panel.
// Common game thread timing scopes to watch
UWorld::Tick
TickActors // All actor ticks combined
BP_EnemyAI_C::Tick // Specific Blueprint tick
TickTaskManager // Async task completion
UpdateAnimation // Skeletal mesh animation
PhysicsSimulation // Chaos physics step
NavigationSystem::Tick // Navmesh queries and path updates
// Common render thread timing scopes
FSceneRenderer::Render
InitViews // Visibility and culling
BasePass // Opaque geometry rendering
TranslucencyPass // Transparent objects
PostProcessing // Bloom, DOF, motion blur, etc.
GPU Profiling and Shader Complexity
GPU traces in Unreal Insights show per-pass timing: how long the base pass, shadow rendering, translucency, and post-processing each take. This data requires D3D12 or Vulkan and adds some overhead, but it is invaluable for identifying GPU bottlenecks.
The Shader Complexity view mode in the viewport (under the Lit dropdown) visualizes how many shader instructions each pixel requires. Green is cheap, red is expensive, white is extremely expensive. Overlapping translucent materials, complex material graphs with many texture samples, and layered landscape materials are common sources of high shader complexity.
// Console commands for GPU investigation
r.ScreenPercentage 50 // Halve render resolution to test if GPU fill-rate bound
r.SetRes 1280x720 // Lower resolution to isolate GPU vs CPU
showflag.PostProcessing 0 // Disable post-processing to measure its cost
showflag.Translucency 0 // Disable translucency rendering
showflag.DynamicShadows 0 // Disable dynamic shadows
ProfileGPU // One-frame GPU capture (also Ctrl+Shift+,)
The ProfileGPU command captures a single frame of GPU timing and displays it in a popup. It is faster than a full Insights trace when you just need a quick look at per-pass costs. Shadow rendering is frequently the most expensive pass, followed by the base pass and post-processing.
Slate and Widget Performance
Unreal's UI systems (Slate and UMG) can be surprisingly expensive. Every widget that ticks, every invalidation that triggers a layout pass, and every complex material on a UI element costs frame time. In games with complex HUDs, UI can consume 2-5ms per frame.
// Stat commands for UI profiling
stat slate // Slate render and tick timing
stat ui // UMG widget update costs
// Common UI performance fixes
// 1. Disable ticking on widgets that don't need per-frame updates
// 2. Use invalidation boxes around volatile sections
// 3. Collapse invisible widgets instead of setting opacity to 0
// 4. Avoid complex materials on UI elements (use simple textures)
// 5. Reduce widget hierarchy depth
In the Timing Insights timeline, look for SlatePrepass, SlateTick, and SlateRender scopes. If these are wide, your UI is consuming significant frame budget. The Widget Reflector tool (Window > Developer Tools > Widget Reflector) shows the complete widget hierarchy and highlights widgets by update frequency.
Blueprint Tick Optimization
Blueprint actors that tick every frame are one of the most common performance issues in Unreal projects. Each Blueprint tick has overhead from the virtual machine, and complex Blueprint graphs with many nodes multiply this cost.
// In C++: Disable tick when not needed
AMyActor::AMyActor() {
PrimaryActorTick.bCanEverTick = false;
// Or set a longer tick interval
PrimaryActorTick.TickInterval = 0.1f; // 10 Hz instead of every frame
}
// In Blueprint: Class Defaults > Tick section
// Set "Start with Tick Enabled" to false
// Set "Tick Interval" to 0.2 for actors that don't need per-frame updates
// Use timers instead of tick for periodic logic
GetWorldTimerManager().SetTimer(
TimerHandle,
this,
&AMyActor::UpdateAI,
0.25f, // Every 250ms
true // Looping
);
In Insights, look for BlueprintTime in the game thread. If it is significant, identify which Blueprint actors are ticking by adding bookmark traces or using the stat game command which breaks down tick time by actor class.
Profiling Packaged Builds
Editor profiling adds overhead from the editor UI, asset loading systems, and debug checks. Always validate your findings in a packaged build. Package a Development build (not Shipping — Shipping strips all profiling code) and launch with trace arguments.
// Package a Development build for profiling
// In Project Settings > Packaging > Build Configuration: Development
// Launch with Insights connection
$ ./MyGame.exe -trace=cpu,gpu,frame -tracehost=127.0.0.1
// On the profiling machine, run UnrealInsights in server mode
$ ./UnrealInsights.exe -store
// Insights will receive the trace data over the network
// This is especially useful for profiling on consoles or mobile devices
Network tracing lets you profile a game running on a different machine, which is essential for console development and for avoiding the observer effect where the profiling tool itself affects performance.
Related Resources
For GPU-specific profiling across all engines, see GPU profiling for game developers. To learn how to test across hardware configurations, read how to benchmark your game across hardware tiers. For integrating performance data with bug reports, explore bug reporting tools for Unreal Engine.
Run stat unit in your project right now and write down the three numbers: Game, Render, GPU. That tells you which thread to optimize first. Everything else follows from that answer.