Skip to main contentSkip to contact
Ocean View Games
Ocean View
Games
Blog header banner

Managing Thermal Throttling in Unity Mobile Games

David Edgecombe

David Edgecombe

·8 min read

Your game runs at a locked 60 FPS for the first eight minutes. Then it drops to 45. Then 30. Then the device gets hot, the player gets frustrated, and your App Store reviews start mentioning "overheating." Congratulations: you have a thermal throttling problem, and a fixed quality preset is not going to solve it.

Thermal throttling is the single most common performance issue we see in mobile Unity projects at Ocean View Games. It is also the most misunderstood. Studios spend weeks optimising draw calls and shader complexity to hit 60 FPS in their first profiling pass, then ship a game that cannot sustain that frame rate for more than a few minutes on real hardware.

This post covers how thermal throttling actually works on mobile devices, why it makes traditional profiling misleading, and how to build systems that respond to it in real time. We have open-sourced the toolkit we use across our mobile projects, so you can integrate these systems directly into your own game.


Why Profiling in the First Minute Lies to You

Desktop profiling is straightforward: measure frame time, find the bottleneck, optimise it, ship it. The hardware runs at consistent clock speeds and the thermal environment is managed by fans and heatsinks.

Mobile devices have none of that. A phone is a sealed aluminium or glass slab with no active cooling. When the SoC generates sustained heat, the operating system reduces CPU and GPU clock speeds to prevent hardware damage. This is thermal throttling, and it is not a bug; it is a fundamental constraint of the platform.

The problem for game developers is that throttling is invisible to your profiler in the first few minutes of a session. Your game looks fast because the device has not heated up yet. The frame time you measured in your initial profiling pass is not the frame time your players will experience during a 20-minute session.

On RuneScape Mobile, this was one of our earliest and most painful lessons. A 20-year-old PC MMO generates sustained CPU load: networking, world simulation, hundreds of NPCs, chat, economy systems. The game ran well for the first 10 minutes on mid-range Android devices, then frame rates collapsed. Traditional profiling told us the game was fast; sustained play told a different story.


How Thermal Throttling Works on iOS and Android

Both platforms throttle differently, and understanding the mechanism matters for building effective countermeasures.

iOS

Apple provides a well-documented thermal notification system. ProcessInfo.thermalState reports four levels: nominal, fair, serious, and critical. Unity exposes this through Application.thermalState from Unity 2022 onwards. The transitions are relatively predictable: Apple's thermal management is conservative and escalates gradually, giving you time to respond.

The practical implication is that you can build a reliable state machine around iOS thermal levels. When the device reports "fair," you have a window to reduce workload before it escalates to "serious."

Android

Android is significantly harder. The thermal landscape is fragmented across thousands of device models from dozens of manufacturers. Samsung, Qualcomm, and MediaTek all implement thermal management differently. Some devices throttle aggressively at the first sign of sustained load; others let the SoC run hot until the frame rate falls off a cliff.

Android 12 introduced the PowerManager.ThermalStatusListener API, which provides similar granularity to iOS. Earlier Android versions offer limited thermal data, and you often need to rely on indirect signals: frame time degradation over a rolling window is the most reliable proxy for thermal state on older devices.


The Adaptive Approach

The solution is not to optimise harder for a single quality target. It is to build a system that monitors device state and adjusts quality dynamically based on what the hardware can actually sustain right now.

This is the approach we used on RuneScape Mobile and refined across subsequent projects including Domi Online and Nova Blast. The architecture has three layers: monitoring, decision-making, and response.

Layer 1: Monitoring

You need three independent data streams to make good quality decisions.

Thermal state tells you whether the device is already throttling or approaching throttle thresholds. On Unity 2022+, Application.thermalState gives you this directly. On older versions, you need to infer it from frame time trends.

Memory pressure tells you how close you are to the operating system killing your process. Mobile operating systems are ruthless: exceed your memory budget and your game is terminated with no warning. On Android, the budget varies dramatically by device; a low-end phone might give you 512 MB while a flagship gives you 3 GB. You need to know your budget and track against it continuously.

Frame timing tells you whether your current quality settings are sustainable. A single slow frame is noise. A rolling average that is drifting upward is a signal. The 95th percentile frame time is more useful than the average, because it captures the stutters that players actually notice.

We monitor all three independently because they fail independently. You can be within your memory budget while thermally throttling. You can have stable frame times while approaching your memory ceiling. Each data stream drives different responses.

Layer 2: Decision-Making

The monitoring data feeds into an adaptive quality manager that steps through predefined quality tiers. We typically define five: Ultra, High, Medium, Low, and Minimal. Each tier specifies concrete values for texture resolution, shadow distance, LOD bias, particle counts, and target frame rate.

The critical design detail is hysteresis. Without it, the system oscillates: quality drops because thermals are high, frame time improves, quality increases, thermals rise again, quality drops. The result is worse than staying at a fixed low quality.

Hysteresis means the system requires sustained stability at a lower tier before it considers stepping back up. In practice, we require 30 to 60 seconds of stable performance at the current tier before allowing an upgrade. Downgrades happen immediately when thresholds are breached; upgrades happen cautiously.

Layer 3: Response

When the quality tier changes, every system that contributes to workload needs to respond. This is where many implementations fall short: they adjust Unity's built-in QualitySettings but ignore game-specific systems.

In a typical mobile game, the most impactful levers are:

  • Shadow distance and resolution. Shadows are disproportionately expensive on mobile GPUs. Cutting shadow distance from 50 to 20 units and halving shadow map resolution can reclaim significant GPU time with minimal visual impact during gameplay.
  • LOD bias. Pushing LOD transitions closer means fewer triangles on screen. Players rarely notice during action gameplay.
  • Particle counts and simulation complexity. Particle systems are CPU-bound on mobile. Reducing max particle counts and simulation timestep frequency is an easy win.
  • Draw call batching aggressiveness. At lower quality tiers, you can increase static and dynamic batching thresholds or disable instancing for small meshes.
  • Target frame rate. Dropping from 60 to 30 FPS halves the GPU and CPU workload per second. This is the nuclear option, but on a device that is critically throttling, it is better than an unstable 40 FPS with constant stuttering.

Memory Budgeting: The Other Mobile Constraint

Thermal throttling gets the attention, but memory is where mobile games die silently. When your process exceeds the operating system's memory budget, the OS kills it instantly. No exception. No callback. No save opportunity. The player sees a crash, leaves a one-star review, and uninstalls.

The challenge is that the budget is not fixed. It varies by device model, by how many other apps are running, and by OS version. A game that runs fine on a developer's test device might crash consistently on a player's phone that has a messaging app, a music player, and three browser tabs open in the background.

Our approach is to define conservative per-platform memory budgets based on the devices we are actually targeting, then track against them continuously. For a game targeting broad Android compatibility, we typically budget 512 MB for low-end devices, 1 GB for mid-range, and 2 GB for iOS. These are not device memory totals; they are the budget our game should stay within.

The memory tracker monitors managed heap allocations, native memory, and graphics memory separately. When usage crosses a warning threshold (typically 75% of budget), the system starts unloading non-critical assets: distant LOD textures, cached audio clips, pooled objects that have not been used recently. At 90%, it triggers a more aggressive cleanup: forced garbage collection, unloading all unused assets, clearing object pools.

This is not about preventing memory leaks, though it catches those too. It is about maintaining a safety margin on devices where the available budget is smaller than you assumed during development.


Battery-Aware Scheduling

One more dimension that most mobile games ignore: battery impact. Players notice when a game drains their battery quickly, and it is a common reason for uninstalls that never shows up in crash analytics.

Heavy background operations, such as asset preloading, procedural generation, analytics uploads, and texture streaming, should be gated on battery state. If the device is at 15% battery and not charging, your game should not be speculatively preloading the next three levels in the background. That work can wait until the device is charging or the battery is healthy.

This is a simple system to implement and it has an outsized impact on player perception. A game that respects battery life earns goodwill that translates directly into retention and review scores.


Putting It Together

These systems are most effective when they run together as a unified performance management layer rather than as isolated utilities. The thermal monitor, memory tracker, and frame timer each provide one dimension of device health. The adaptive quality manager synthesises all three into a single quality decision. The battery scheduler independently gates background work.

The data flow looks like this: device sensors feed three monitors, which feed the quality manager, which adjusts Unity's quality settings and notifies game-specific systems. The battery scheduler operates independently, gating heavy background tasks based on power state.

We have packaged these systems as an open-source toolkit on GitHub. The repository includes production-ready implementations of all five components (ThermalThrottleMonitor, MemoryBudgetTracker, FrameTimingProfiler, AdaptiveQualityManager, and BatteryAwareScheduler), an Editor dashboard for real-time monitoring during development, and a comprehensive mobile optimisation guide covering best practices and profiling workflows.

The code is MIT-licensed and designed to drop into any Unity 2021.3+ project. Copy the Runtime folder into your Assets directory, wire the components together on a GameObject, and you have a complete performance management system running within minutes.


What This Does Not Solve

Adaptive quality management is not a substitute for fundamental optimisation. If your game is CPU-bound because your AI system runs pathfinding for 200 agents every frame, no amount of shadow distance reduction will help. If your draw calls are high because your scene graph is not batching-friendly, adjusting LOD bias will not fix the root cause.

These systems manage the thermal and memory constraints that are unique to mobile hardware. They assume your game is already reasonably optimised for its target frame rate. If you are not hitting your target on a cool device with a full battery, you have a profiling and optimisation problem, not a thermal management problem.

If you need help with the underlying optimisation work, our performance optimisation service includes deep profiling, thermal testing on real device matrices, and targeted fixes. We also offer technical audits that assess your project's mobile readiness across performance, memory, and thermal dimensions.

Share

Stop Searching. Start Building.

Ready to start your next project? Tell us about your game and we'll get back to you with a plan.

Start by telling us what kind of help you need.

Location

London, United Kingdom

Response Time

We typically respond within 24-48 hours

1
2
3
Step 1 of 3