When people talk about render pipeline optimization, “use instancing” comes up as standard advice almost immediately. I wanted to actually test it myself rather than just repeat it.
I ran a direct comparison in Unreal Engine and learned a few things along the way that the advice alone doesn’t tell you!
The test is simple by design: spawn 10,000 cubes two different ways and compare the cost.
BP_Cube actors, spawned individually via SpawnActorFromClass in a loop, arranged in a 100×100 grid.Instanced Static Mesh component instead of being spawned as 10,000 separate actors.
BP_Cube actors, spawned individually via SpawnActorFromClass10,000 separate actors
Instanced Static Mesh component instead of being Both were measured using Unreal’s stat unit console command, run in Standalone Game mode rather than Play-In-Editor (PIE). This matters more than it sounds like it should — PIE carries editor overhead that skews the numbers, so Standalone gives a cleaner read on what the build would actually cost at runtime. I actually confirmed this the hard way: running the SM version in PIE first dropped the frame rate to single digits with a multi- second hitch on spawn, which was a good gut-check but not a fair number to report.
The first thing that jumps out when you flip between the two versions is frame rate. Averaged over three runs each:
Static Mesh: Frame: 15.24 ms FPS: 65.57
Instanced Static Mesh: Frame: 6.63 ms FPS: 150.74
That’s already a strong result — frame time more than halved. But frame time alone doesn’t tell you why.
The field that actually explains the improvement is a separate one from Draw (GPU-side draw time): it’s Draws, the draw call count.
Static Mesh: Draws: 9,923 (avg of 9,993 / 9,980 / 9,795)
Instanced Static Mesh: Draws: 38 (avg of 38 / 38 / 39)
That’s the mechanism the “use instancing” advice is usually gesturing at without spelling out: batching 10,000 individual actors into one instanced draw call collapsed the draw call count by roughly 99.6%! Ten thousand separate BP_Cube actors means ten thousand separate submissions to the renderer; one Instanced Static Mesh component with 10,000 instances means the GPU gets one batched draw call worth of setup instead. Frame time improvement is the effect: draw call count is the cause!
It’s worth being precise about what these two things are, because “instancing is faster” doesn’t mean much without the mechanism.
A Static Mesh is the mesh asset itself — geometry, UVs, material slots. When you place one in a level (or spawn it as an actor), you get a StaticMeshComponent, and that component is what tells the renderer “draw this mesh, at this transform.” Ten thousand individual BP_Cube actors means ten thousand separate StaticMeshComponents, each one submitted to the renderer on its own.
An Instanced Static Mesh component is a single component built for a different job: “draw this one mesh, many times, at these transforms.” Instead of ten thousand components, there’s one component holding a buffer of ten thousand transforms.
The reason this is faster comes down to where the cost actually lives. Issuing a draw call is CPU work. the CPU has to build and submit a command telling the GPU what to render and how. With 10,000 separate components, the CPU repeats that submission 10,000 times (this is exactly what shows up as elevated RHIT time in the Static Mesh numbers above). With an Instanced Static Mesh, the CPU submits one command — “draw this mesh N times, using this transform buffer” — and the GPU handles looping over the N instances itself, which is exactly the kind of parallel work GPUs are good at. One CPU submission instead of ten thousand is the entire reason the Draws count — and the frame time behind it — drops as much as it does.
My first instinct was to compute the improvement straight from the FPS numbers (62.48 → 163.50), but FPS and frame time aren’t linearly related, so taking a percentage difference of FPS values overstates the real gain. Frame time (ms) is the number to use:
(16.01 - 6.26) / 16.01 × 100 ≈ 60.9% improvement
Spawning 10,000 objects (or adding 10,000 instances) at BeginPlay creates a spike right at the moment of spawn — memory allocation adds noise to the very first frames. A single screenshot taken right after spawn risks capturing that spike rather than steady-state performance. I ran each version three times and read the stable, post-spawn numbers each time:
Static Mesh runs: 62.48 / 67.25 / 66.97 FPS
9,993 / 9,980 / 9,795 Draws
Instanced Static Mesh runs: 163.50 / 150.34 / 138.38 FPS
38 / 38 / 39 Draws
The Draws count barely moved between runs on either version — which is itself a useful sanity check that the number reflects something structural about the scene, not per-frame noise.
↓ Static Mesh (Three runs)

↓ Instance Static Mesh(Three runs)

| Metric | Static Mesh (10,000 individual actors) | Instanced Static Mesh |
|---|---|---|
| Draws (draw calls) | 9,923 | 38 |
| Frame time | 15.24 ms | 6.63 ms |
| FPS | 65.57 | 150.74 |
| Draw call reduction | — | ~99.6% |
| Frame time improvement | — | ~56.5% |
The headline isn’t not only “instancing is faster” but also collapsing 10,000 separate draw call submissions into 38 batched ones removes almost all of the CPU-side overhead of issuing each draw individually.
Frame time tells you something changed; Draws tells you what actually changed it.

Tested on Windows 11, Unreal Engine 5.7.4, Intel Core i7-8700 / RTX 2060 (6GB) / 32GB RAM,
in Standalone Game mode using the stat unit console command, averaged over three runs
per version.
If you’re running a similar comparison, I’d suggest reading the Draws
field, not just frame time or FPS. The count is what actually proves instancing is
doing its job, not just a side effect of it.