Quick answer: Stuttering is a frame-pacing problem: most frames are fine but occasional frames take far too long, causing visible hitches. The average FPS can look great while the game still stutters, because the problem is the spikes, not the average. Common causes are garbage collection pauses, loading assets or compiling shaders during play, and sudden bursts of work. Profile frame time (not average FPS), find what causes the spikes, and eliminate or spread that work.
Stuttering is uniquely annoying because the game can have a high average frame rate and still feel terrible, those occasional long frames are visible hitches that break the sense of smoothness. The key to fixing stuttering is understanding that it's about consistency, not average speed, and that the cause is whatever produces the occasional spike, not the steady-state cost.
Why Stuttering Happens
Stuttering is inconsistent frame timing: most frames complete quickly, but occasional frames take much longer, producing a visible hitch. Because it's the spikes that matter, the average FPS can look fine while the game stutters, which is why measuring average FPS misses the problem entirely. The causes are things that occasionally inject a big chunk of work into a single frame: garbage collection (a GC pause stalls a frame, common in managed engines), on-the-fly loading (loading an asset, texture, or level chunk during play blocks a frame), shader compilation (compiling a shader the first time it's used causes a hitch, the infamous 'shader stutter'), and sudden bursts of work (spawning many objects at once, a heavy computation on one frame).
Each of these is fine on average but catastrophic in the single frame it lands on. The pattern, smooth with occasional spikes, is the signature of stuttering, as opposed to a steady low frame rate.
How to Diagnose It
Measure frame time, not average FPS. A frame-time graph reveals stuttering instantly: smooth play shows a flat line, while stuttering shows spikes, occasional tall bars where a frame took far too long. The spikes are the problem, and their timing and a profiler tell you what's in those frames: a GC pause, an asset load, a shader compile, a work burst. Frame-time percentiles (p95/p99) also capture the bad-frame experience that averages hide.
Bugnet's performance monitoring captures performance data beyond averages, surfacing the bad-case frame experience (the spikes and hitches) and where it occurs, including on real player hardware where stutter may be worse than on your dev machine. Stutter that correlates with specific moments (entering an area, first use of an effect) points at on-demand loading or shader compilation at that moment.
How to Fix It
Eliminate or spread the spiky work. For garbage collection, reduce per-frame allocations so the GC runs less often (pool and reuse objects instead of allocating and discarding), which removes GC-pause stutter. For on-the-fly loading, preload or stream assets ahead of time so they're not loaded during the frame they're needed, load on a background thread or during loading screens, not mid-gameplay. For shader stutter, precompile or warm up shaders ahead of time (e.g. at load) so the first use doesn't compile and hitch. For work bursts, spread heavy work across multiple frames instead of doing it all in one (spawn over several frames, amortize computation).
The unifying principle: nothing should inject a big unbudgeted chunk of work into a single frame, anticipate the cost and pay it ahead of time or spread it out. After fixing, verify with frame-time profiling that the spikes are gone (flat frame-time line), not just that average FPS is high. Smooth frame pacing is what players feel as quality, and removing the spikes is what delivers it.
Stuttering is the spikes, not the average, occasional long frames from GC, loading, or shader compiles. Measure frame time, find the spike's cause, and pay that cost ahead of time.