Cutting Draw Calls in Unity for Mobile
Draw calls are rarely the only problem, but they are often the first one on low-end phones. Here is how to measure them, which batching tools to reach for, and the habits that keep them down.

Unity draw call optimization on mobile comes down to three moves: measure batches and SetPass calls with the Frame Debugger, share materials so objects can batch, and pick the right batching method. In URP that usually means the SRP Batcher for most objects, static batching for scenery, and GPU instancing for many identical meshes.
Measure before you change anything
Draw calls only matter if they are your bottleneck. On low-end Android, they often are, because the CPU spends time preparing each one. But confirm it first.
Open the Game view and click Stats. Watch two numbers: Batches and SetPass calls. SetPass calls are shader or material changes, and they are usually the more expensive of the two.
Then open Window > Analysis > Frame Debugger and step through a frame. It shows every draw and often tells you why two draws were not combined. That reason line is the most useful thing in this whole process.
Profile on the device, not the editor
Editor numbers are a guide, not the truth.
Build with Development Build and Autoconnect Profiler ticked, run on your slowest test phone, and check the CPU timeline. If rendering is a small slice of the frame, draw calls are not your problem. Our guide to debugging frame drops on Android covers the device setup.
The batching options and when to use each
Unity has several ways to combine draws. They suit different kinds of objects.
| Method | Best for | Where to turn it on |
|---|---|---|
| SRP Batcher | Most objects in URP with compatible shaders | URP Asset settings |
| Static batching | Scenery that never moves | Mark objects Batching Static |
| GPU instancing | Many copies of one mesh and material | Material checkbox |
| Sprite atlases | 2D sprites and UI | Sprite Atlas asset |
| Dynamic batching | Very small meshes, legacy setups | URP Asset, usually left off |
In URP, the SRP Batcher is on by default in recent versions. It does not reduce the draw count shown in Stats, but it makes each draw much cheaper by cutting state changes. Check the Frame Debugger to see which objects it is batching.
Material habits that matter most
Most batching breaks come from materials, not meshes. A few habits keep them intact.
Share materials across objects. Ten crates using ten separate copies of a material break static batching and instancing. One shared material keeps both working.
Use sharedMaterial when you only read it. Touching renderer.material creates a new instance silently, and that instance breaks batching for that object.
// Creates a copy of the material on first access. Avoid in hot paths.
var tint = rend.material.color;
// Reads the shared asset. No copy, batching stays intact.
var sharedTint = rend.sharedMaterial.color;
Be careful with MaterialPropertyBlock in URP. Unity's documentation notes that renderers using a property block are not compatible with the SRP Batcher. If you need per-object colours on many copies, GPU instancing with per-instance properties is usually the better route.
Textures and atlases
Every unique texture tends to mean a unique material, which means another SetPass call. Packing textures together reduces that.
For 2D, create an atlas with Assets > Create > 2D > Sprite Atlas, drag your sprite folders in, and confirm the packer is enabled under Project Settings > Editor > Sprite Packer Mode. Our post on tilemap optimization for mobile shows how this applies to level art.
For 3D, a shared texture atlas across props lets them use one material. It is extra work in the art pipeline, so save it for the objects that appear most often on screen.
UI is a hidden source of draws
Canvas UI can add a surprising number of batches. A few rules help:
- Split static UI and changing UI into separate canvases, so one update does not rebuild everything.
- Keep UI sprites in one atlas where possible.
- Avoid overlapping elements that force Unity to break the batch order.
- Turn off Raycast Target on images and text that do not need clicks.
We cover the rest in Unity UI performance on mobile.
A rough working budget
There is no single correct number of draw calls for mobile. It depends on the device, the shaders, and everything else in the frame.
A practical approach: pick your weakest supported phone, build a test scene with your heaviest view, and find where the frame rate starts to drop. That point is your budget. Write it down and check new content against it every week.
The best budget is the one you measured yourself on the slowest phone you support. Borrowed numbers from forums rarely match your game.
What we would do
We would start every optimisation pass with the Frame Debugger, read the reason Unity gives for each broken batch, and fix the top three causes. In most mobile projects those are duplicated materials, too many unique textures, and a single huge UI canvas.
Then we would set a measured batch budget on a real low-end phone and check it in every weekly build, so the number never drifts back up.
The short version
- Confirm on a device that rendering is the bottleneck before optimising draws.
- Use the Frame Debugger to see why batches break. Fix the most common reason first.
- In URP, rely on the SRP Batcher, static batching for scenery, and instancing for repeats.
- Share materials, read
sharedMaterial, and atlas textures and sprites. - Measure your own batch budget on your slowest supported phone.
If your game still stutters on low-end Android after a pass like this, send us a build and we will take a look.
Related reading: Unity mobile performance on low-end Android, Shader basics for devs, Android device fragmentation guide
Got a game idea? We build it.
You bring the concept. We design, build, test and launch it, and you own 100% of the finished game.
Share Your Game Idea →