tutorial · 2026-03-01
Building a Real-Time FPS and Memory Performance Chart HUD in UE5
Drop a live FPS, frame-time and memory graph on screen in minutes using Fast Chart Widgets' template and auto-collection system.
Why an on-screen performance graph beats stat fps
Every UE5 developer knows 'stat fps' and 'stat unit', but those console overlays give you a single number that flickers too fast to read and disappears the moment something interesting happens. When you are chasing a hitch during a specific encounter, or watching memory creep up over a long play session, you need a real time FPS and memory graph on screen — a rolling history you can actually watch, not an instantaneous readout you have to screen-record and scrub through frame by frame.
This tutorial builds exactly that using Fast Chart Widgets, a runtime data-visualisation plugin for UE5 that adds a Blueprintable UMG widget drawn entirely in Slate. The part that makes a performance HUD trivial is its template and auto-collection system: rather than hand-wiring a tick loop that samples the engine and feeds data points, you apply a pre-built Performance template and tell the widget to start collecting. The chart then samples and plots the metric on its own.
The workflow below assumes the plugin is installed into your project's Plugins folder and enabled, and that you are on a supported engine version (Unreal Engine 5.5, 5.6 or 5.7, Windows 64-bit). Everything here is achievable from Blueprints, with the C++ equivalents noted where they help.
Choosing the right performance template
Fast Chart Widgets ships 34 pre-configured chart templates organised into six marketplace categories — Performance, Gameplay, Multi-Data, Visual Styles, Minimal and Other. For a performance HUD you want the Performance category, which includes templates such as FPSMonitor, FrameTime and MemoryUsage. Each template is a DataAsset that bundles the chart type, styling, axis configuration and, crucially, which engine metric to auto-collect.
The fastest way to see what is on offer is the editor path. Open a Widget Blueprint and click the 'Chart Template Marketplace' button the plugin adds to the Widget Blueprint editor toolbar. Pick a category, choose a template such as FPSMonitor, and it drops a fully styled UFastChartWidget straight onto your canvas with one click — no need to hand-configure dozens of properties. This is ideal when you want to eyeball the styling before committing.
If you would rather start from a clean widget, add a UFastChartWidget to your UMG canvas yourself and reference the template DataAsset directly. The template carries the heavy lifting either way; the difference is just whether the editor inserts a pre-configured widget for you or you bring your own.
ApplyTemplate then StartDataCollection
Once a UFastChartWidget exists on a HUD you can display, the live data is two Blueprint-callable nodes away. ApplyTemplate, StartDataCollection and StopDataCollection are all BlueprintCallable, so the whole HUD can be driven from an Event Graph without touching C++.
1. Create your HUD widget and add it to the viewport as usual — for a debug overlay, a 'Create Widget' followed by 'Add to Viewport' on Begin Play (or behind a debug key) is enough. Make sure the UFastChartWidget is reachable, either as a named child of your HUD or as the root.
2. On the UFastChartWidget, call 'Apply Template' and pass it the Performance DataAsset you chose — FPSMonitor, FrameTime or MemoryUsage. This configures the chart's type, axes and styling, and sets which metric it will sample.
3. Call 'Start Data Collection' on the same widget. From this point the chart samples its configured metric and appends points on its own; you do not write a tick loop or push values yourself for the built-in sources.
4. When you want to freeze the graph — for example to inspect a spike, or when the debug overlay is hidden — call 'Stop Data Collection'. Calling 'Start Data Collection' again resumes sampling.
In C++ the shape is identical: LoadObject a UFastChartTemplate DataAsset, call ApplyTemplate, then StartDataCollection, and AddToViewport. One detail worth knowing is that the builder and series objects the widget creates are retained on the widget itself (in its ActiveChartBuilders), so Blueprint callers do not have to promote them to a variable to keep them alive past garbage collection.
Which metrics auto-collect
The auto-collection system understands a fixed set of engine metrics. A template's data source can be FPS, FrameTime, Memory, GameThreadTime, RenderThreadTime or GPUTime. Those six cover the questions a performance HUD usually needs to answer: is the frame rate dropping, is the frame getting longer, is memory climbing, and when a frame is slow, is the game thread, the render thread or the GPU the bottleneck.
Two further sources exist for cases the built-ins do not cover. Custom lets you feed your own values — call AddDataPoint(float) each time you have a number to plot — which is how you would chart something gameplay-specific like draw distance, active actor count or your own subsystem's timings. None is the manual mode where the chart does no sampling at all and you drive every point.
A practical setup is to run two or three charts side by side: an FPSMonitor for the at-a-glance frame rate, a MemoryUsage chart to catch leaks over a session, and optionally a frame-time breakdown using GameThreadTime, RenderThreadTime and GPUTime so a hitch immediately tells you which thread to blame. Because each chart is just a widget with its own template, you can lay them out however your overlay needs.
One honest caveat: the plugin's documentation does not publish rendering-cost or benchmark figures for the charts themselves, so treat the HUD as a development and profiling aid and measure its own overhead in your project if you intend to ship it in a player-facing build.
Keeping the chart readable with auto-range floors
The most common complaint about a live performance graph is that it looks frantic. When a value is roughly stable, naive auto-ranging zooms the Y axis so tightly that tiny, meaningless variations fill the whole chart, and the line jitters violently even though nothing is really happening. Fast Chart Widgets addresses this directly with a minimum auto-range span: MinAutoRangeSpanY sets a floor on how far the Y axis is allowed to collapse, so small fluctuations stay small on screen instead of being magnified into noise.
By default the chart fits to data, which is what you want most of the time. You control this with SetFitToDataY and SetFitToDataX for automatic ranging, or SetManualYRange and SetManualXRange (with their X equivalents) when you want a fixed window — for instance pinning an FPS chart's Y axis from 0 to your target frame rate so the line's height always means the same thing.
For a memory chart, a manual Y range anchored at zero often reads best because it preserves the true sense of scale: a gentle upward creep stays a gentle upward creep rather than being re-zoomed into an alarming cliff every few seconds. For FPS, fit-to-data with a sensible MinAutoRangeSpanY usually gives the most useful balance between detail and stability.
From here you can style the overlay to taste — Fast Chart Widgets exposes deep per-axis settings, multiple grid layers, legend placement and themes — but the core performance HUD is done: a styled chart, a Performance template applied, data collection started, and a Y axis that stays calm. Open a Widget Blueprint, click the Chart Template Marketplace button, and you can have it on screen this afternoon.
Auto-collected performance metrics
| Data source | What it tracks | Typical HUD use |
|---|---|---|
| FPS | Frames per second | At-a-glance frame rate, the FPSMonitor template |
| FrameTime | Time to render one frame | Spotting hitches the average FPS hides |
| Memory | Memory usage | Catching leaks and creep over a long session |
| GameThreadTime | Game-thread cost per frame | Is gameplay/CPU logic the bottleneck |
| RenderThreadTime | Render-thread cost per frame | Is the render thread the bottleneck |
| GPUTime | GPU cost per frame | Is the GPU the bottleneck |
The built-in data sources a Performance template can sample automatically once you call Start Data Collection.
FAQ
How do I show a real-time FPS and memory graph on screen in Unreal Engine?
Add a UFastChartWidget from Fast Chart Widgets to a HUD widget, call Apply Template with a Performance template (FPSMonitor or MemoryUsage), then call Start Data Collection. The widget samples and plots the metric on its own once it is in the viewport, giving you a rolling on-screen graph rather than a single flickering number.
Which performance metrics can the chart collect automatically?
Six engine metrics auto-collect: FPS, FrameTime, Memory, GameThreadTime, RenderThreadTime and GPUTime. There is also a Custom source where you push your own values with AddDataPoint, and a None source for fully manual charts.
How do I stop the FPS graph from jittering when the value is stable?
Use MinAutoRangeSpanY, which sets a floor on how far the Y axis can collapse, so small variations stay small instead of being magnified. Alternatively pin a fixed window with SetManualYRange — for example 0 to your target frame rate — instead of fitting to data.
Do I need to write C++ to build the performance HUD?
No. ApplyTemplate, StartDataCollection and StopDataCollection are all BlueprintCallable, so the entire HUD can be driven from an Event Graph. The same calls exist in C++ if you prefer — LoadObject the template DataAsset, ApplyTemplate, StartDataCollection, then AddToViewport.
What engine versions and platforms does Fast Chart Widgets support?
The live packages target Unreal Engine 5.5, 5.6 and 5.7, and the plugin's PlatformAllowList is Windows 64-bit. Treat it as a Windows, UE 5.5-plus tool.
Fast Chart Widgets
Line, bar and pie widgets that bind straight to your data — no custom drawing code. Build dashboards, stats screens and debug overlays in minutes.