← Back to All Articles
Unity

Unity Performance Optimization: Profiling & Best Practices

Advanced profiling techniques, memory management, garbage collection minimization, and GPU draw call batching for production Unity games.

Summary

Unity performance work comes down to three budgets: CPU frame time, GC allocations, and GPU draw calls. Profiling with the Unity Profiler and Frame Debugger before changing code — rather than guessing — is what separates a stable 60 FPS build from one that stutters under load.

1. Profile Before You Optimize

The Unity Profiler's CPU, GPU, Memory and Rendering modules, plus the Frame Debugger, should be the first stop for any performance investigation — not code intuition.

Deep Profiling & the Frame Debugger: Deep Profiling instruments every managed call for exact allocation counts. The Frame Debugger steps through each draw call in a frame, showing precisely why the GPU did what it did — batched, instanced, or issued as a separate call.

2. Garbage Collection & Managed Allocations

Every managed allocation in Update() eventually triggers a GC pass, and GC pauses are one of the most common causes of frame spikes on mobile hardware.
// Object pool instead of Instantiate/Destroy per shot
public class BulletPool : MonoBehaviour {
  readonly Queue<GameObject> pool = new();
  [SerializeField] GameObject bulletPrefab;
  [SerializeField] int prewarm = 64;

  void Awake() {
    for (int i = 0; i < prewarm; i++) {
      var go = Instantiate(bulletPrefab);
      go.SetActive(false);
      pool.Enqueue(go);
    }
  }

  public GameObject Get() =>
    pool.Count > 0 ? pool.Dequeue() : Instantiate(bulletPrefab);

  public void Release(GameObject go) {
    go.SetActive(false);
    pool.Enqueue(go);
  }
}
Common sources of hidden per-frame allocation: GetComponent<T>() called every frame instead of cached in Awake(), LINQ inside Update(), string concatenation for UI text, and boxing value types into object parameters.

3. GPU Draw Call Batching

TechniqueHow It Reduces Draw CallsBest For
Static BatchingCombines non-moving meshes sharing a material into one draw call at build timeLevel geometry, props
GPU InstancingIssues one draw call for many copies of the same mesh with per-instance dataFoliage, crowds, particles
SRP BatcherReduces per-object render-state changes on URP/HDRP without merging meshesGeneral URP/HDRP scenes

About the author

Dharmik Gohil, founder of HEWN CRAFT.

Read more software and game development articles or explore our development services.