Skip to main content

Mobile Game Performance: FPS, Memory and Battery

A practical guide to frame time, CPU and GPU bottlenecks, texture memory, thermal throttling and repeatable Android and iOS game benchmarks.

R
Written by Reiko

Average FPS conceals interruptions and uneven pacing during sustained play. Short freezes during a camera turn, rising memory after each level and a hot phone after ten minutes are different performance problems. Improving an Android or iOS game starts by measuring the affected part of the session and identifying which resource is limiting it.

Translate the FPS target into a frame-time budget

Frame time is the interval associated with producing or presenting a frame, depending on the measurement. The simple target calculation is 1,000 milliseconds divided by the intended frames per second. It provides a useful starting point for profiling.

Target rate

Time per frame

What the number means

30 FPS

33.33 ms

One new frame approximately every 33 milliseconds

60 FPS

16.67 ms

Half the interval available at 30 FPS

90 FPS

11.11 ms

Less processing time per frame than at 60 FPS

120 FPS

8.33 ms

A demanding target requiring suitable hardware and display support

CPU and GPU work can overlap in a pipelined renderer. Do not automatically add their measured times and compare the sum with 16.67 ms. Inspect how the engine schedules work and where one stage waits for another. A 12 ms CPU workload and a 12 ms GPU workload may overlap, while a synchronisation stall can still prevent timely presentation.

Frame pacing describes how evenly frames reach the display. Google's Android Frame Pacing library, also called Swappy, helps OpenGL and Vulkan games coordinate presentation. Integration details depend on the engine. A consistent 30 FPS mode may be a better device-specific choice than a target of 60 FPS that repeatedly falls behind.

Find the bottleneck before changing visual quality

Capture a repeatable section: the same level, camera path, number of enemies and graphics preset. Record CPU time, GPU time and presentation intervals separately where tools permit. On Android, Perfetto and engine profilers help investigate scheduling and stalls. On iOS, use Xcode Instruments and Metal profiling tools alongside the engine's measurements.

Observed symptom

Possible cause

Useful experiment

Frame time improves when render resolution drops

Pixel shading, fill rate or bandwidth pressure

Compare GPU time in the same scene

Spikes grow with enemy count

Simulation, AI or physics work

Profile those CPU systems individually

A pause occurs on first appearance of an effect

Asset loading or shader work

Compare first and subsequent appearances

Memory rises after every level transition

Retained assets, caches or a leak

Compare snapshots after repeated transitions

These observations suggest experiments; they do not prove the cause. Reducing resolution changes several parts of a workload, and a frame can involve both CPU and GPU limits. Confirm the explanation with a trace before committing to an expensive rewrite.

Calculate texture memory before reducing every asset

An uncompressed 2,048 by 2,048 RGBA texture with four bytes per pixel contains 16,777,216 bytes, or 16 MiB, at its base level. A complete mipmap chain adds approximately one third, bringing the texture payload to about 21.33 MiB. Twenty such textures would occupy roughly 426.7 MiB for those mip levels alone.

This calculation excludes alignment, metadata, temporary copies and other engine allocations. It also assumes uncompressed RGBA data; a GPU-compressed format changes the result. A small PNG file on disk does not establish how much memory its decoded runtime texture consumes.

Inspect the actual import settings and GPU format. ASTC and ETC2 are relevant Android texture-compression formats, but support and fallback behaviour must match the devices and graphics APIs you target. Check visual damage around text, gradients, normal maps and transparent edges rather than choosing compression solely by file size.

  • Reduce dimensions for assets that occupy few pixels on screen.

  • Unload assets that no active scene or planned transition needs.

  • Inspect whether both compressed and expanded copies remain resident.

  • Use mipmaps selectively according to how the texture is sampled.

  • Measure peak memory during scene transitions, when old and new content may overlap.

Test sustained performance and thermal throttling

A cold phone can run a demanding scene faster than the same phone after sustained load. Thermal throttling changes available performance to manage heat. Android's Dynamic Performance Framework includes thermal signals that can inform workload adaptation. The game still needs its own policy for reducing effects, resolution or frame-rate targets.

For a project-level experiment, run the same 20-minute route and compare the first two minutes with the last five. This duration is a suggested test design, not a platform requirement or a guarantee of thermal stability. Record ambient conditions, screen brightness, charging status and graphics settings so later comparisons mean something.

Avoid a quality setting that switches up and down every few seconds. Add a controlled recovery policy and test the transition itself. Lowering texture quality may require reloads, whereas adjusting a rendering effect may be possible during play. Keep control responsiveness and essential information intact at every quality tier.

Report percentiles and spikes alongside averages

Sort a sufficiently large sample of comparable frame times to calculate percentiles. A p95 of 22 ms means approximately 95% of samples are at or below 22 ms. It does not mean that 95% of sessions reached 60 FPS, and a percentile of CPU work is not automatically a percentile of displayed frame intervals.

Consider an illustrative capture with most frames around 16 ms and several frames lasting 100 ms during a level transition. An average alone can conceal that interruption. Keep the p50, p95, p99, maximum interval and the location of long frames, with loading and active gameplay identified separately.

Use a benchmark record that another developer can repeat

  1. Record the device, system version, build identifier and graphics configuration.

  2. Start from a defined save and execute the same input sequence.

  3. Capture a warm-up period separately from the measured route.

  4. Repeat the experiment and compare distributions, not one favourable run.

  5. Change one suspected cause, then repeat under the same conditions.

Use a release-like build for performance comparisons. Development tools and sanitizers can materially alter timing and memory use. Battery-percentage changes are also coarse measurements: a short test showing a one-point drop cannot establish a precise energy cost. Use longer controlled runs and appropriate platform instrumentation.

Distinguish download size, startup time and resident memory

A small installation can still load too many decoded assets into memory. Conversely, a large content library may remain manageable if only the required level is resident. Measure the initial download, optional content, first playable moment and peak memory as separate quantities.

For a transfer example, 100 MB of decimal data contains 800 megabits. At a sustained 20 megabits per second, the ideal transfer takes 40 seconds. Actual loading also includes protocol overhead, variable throughput, verification, decompression and asset preparation. Do not advertise the calculated transfer time as a measured launch time.

If a progress bar reaches 100% before decompression finishes, explain the remaining stage. Keep the interface responsive while preparing content and make an interrupted download resumable where the delivery system permits. Avoid downloading the entire catalogue before a player can try the opening level when later content can be acquired safely on demand.

When is the optimisation ready to ship?

An improvement is ready when it survives the representative device matrix, preserves visual and gameplay correctness and remains useful during sustained play. Record the original symptom, measured cause, change and before-and-after evidence. If a faster build introduces missing textures or lost progress, it has failed the release criteria despite better frame times.

For a graphics change, preserve the original capture and compare frame-time distributions in the same scene. Record device model, display refresh setting, battery state and a short warm-up interval. If one optimization improves a median but creates a longer p99 stall, decide against the actual player experience rather than reporting only the new average. Repeat on a second device class before applying the setting to every phone.

Did this answer your question?