Skip to content
unreal · profiling

Runtime perf instrumentationKBVEPerf

A lightweight, runtime-toggleable performance layer for UE5. Scoped timers and counters feed per-name aggregates that drain to three sinks — the log, an on-screen overlay, and a live HTTP /perf JSON readout — so any KBVE plugin can be profiled by flipping a CVar.

Near-zero when disabled

It compiles out of Shipping builds via KBVEPERF_ENABLED=0. When compiled in but disabled at runtime it costs a single atomic load plus a branch per scope, and can be toggled live with the kbve.perf CVar.

  • Timers — RAII scoped KBVEPERF_SCOPE.
  • Counters — gauge samples via KBVEPERF_COUNT.
KBVEPerfPlugin
UE 5.4Min engine
8099HTTP port
KBVELicense

What it gives you

Features

Scoped timers & counters

RAII scoped timers and counter gauges feed per-name aggregates, categorized by the name prefix before the first dot.

Three drain sinks

Aggregates drain to the log, an on-screen overlay, and a live HTTP /perf JSON readout of per-op timings.

Live HTTP readout

Enable with kbve.perf 1 and curl localhost:8099/perf for count, last, max, avg, and p95 per op plus counter gauges.

Compiles out of Shipping

KBVEPERF_ENABLED=0 removes it from Shipping builds; disabled at runtime it is one atomic load plus a branch per scope.

Instrument

Macros

#include "KBVEPerf.h"
void UMyThing::HotPath()
{
KBVEPERF_SCOPE("Grass.AddChunk"); // RAII scoped timer
KBVEPERF_COUNT("Grass.Instances", 72627); // counter / gauge sample
}

The name prefix before the first . is the category (Grass.AddChunkGrass). Add KBVEPerf to your module’s PrivateDependencyModuleNames and the plugin to your .uplugin Plugins list.

Runtime toggles

CVars & HTTP readout

CVarDefaultPurpose
kbve.perf0Master switch — 1 turns collection + /perf on.
kbve.perf.categories""Comma-separated allow-list, e.g. "Grass,Terrain". Empty = all.
kbve.perf.port8099Port for the HTTP /perf endpoint.
kbve.perf.overlay0On-screen overlay of the worst ops this frame.
kbve.perf.threshold3.0Log-sink threshold (ms).
Terminal window
kbve.perf 1
curl http://localhost:8099/perf
{
"frame": 12345,
"fps": 58.2,
"ops": [
{ "name": "Grass.AddChunk", "count": 412, "lastMs": 3.1, "maxMs": 10.9, "avgMs": 3.4, "p95Ms": 7.2 },
{ "name": "Terrain.GenerateMeshData", "count": 380, "lastMs": 0.6, "maxMs": 1.1, "avgMs": 0.7, "p95Ms": 0.9 }
],
"counts": [
{ "name": "Grass.ResidentChunks", "value": 25 },
{ "name": "Grass.Instances", "value": 72627 }
]
}

First consumer

Integration

KBVEWorld (terrain chunks + grass render subsystem) is the first consumer: the bespoke FKBVEHitchLog scoped timers were replaced with KBVEPERF_SCOPE, and the grass subsystem publishes KBVEPERF_COUNT gauges for resident chunks, registered chunks, HISM count, and total instances.

Questions

Frequently asked

What is the KBVEPerf plugin?

KBVEPerf is a lightweight, runtime-toggleable performance instrumentation layer for UE5. Scoped timers and counters feed per-name aggregates that drain to three sinks — the log, an on-screen overlay, and a live HTTP /perf JSON readout — so any KBVE plugin can be profiled by flipping a CVar.

What is the runtime cost of KBVEPerf?

It compiles out of Shipping builds via KBVEPERF_ENABLED=0. When compiled in but disabled at runtime it costs a single atomic load plus a branch per scope, and it can be toggled live with the kbve.perf CVar.

How do you read KBVEPerf results externally?

Set kbve.perf 1 to enable collection and the HTTP endpoint, then curl http://localhost:8099/perf for a JSON readout of per-op timings (count, last, max, avg, p95) and counter gauges, instead of relaying stat unit numbers by hand.