Phones: heat and battery
Minute 1 and minute 20
A co-op session of Shard Garden lasts about 40 minutes. In minute 1, Remy's phone runs a steady 60 FPS. By minute 20, it is at 38 FPS and warm in the hand. Nothing in the code changed.
All the chips' work turns into heat, and a phone has little room to lose it. So it slows its own chips to cool down: thermal throttling. Android's guide says how much depends on the weather, recent use and the phone's design.
A game tested for one minute on a cool phone has measured its best moment, not a real session.
Android: thermal headroom
From Android 11, PowerManager.getThermalHeadroom(seconds) forecasts how hot the phone will be. 0.0 means no throttling, and 1.0 means heavy throttling, the severe status. If getThermalHeadroom(30) returns 0.8, the phone is expected to be 0.2 away from severe throttling in 30 seconds.
The statuses run from THERMAL_STATUS_NONE through light, moderate, severe, critical and emergency, to shutdown. Google's advice: lower the frame rate or the detail before the phone gets there, and don't ask more than once every 10 seconds.
Bug hunt
1// runs 60 times a second2fun onFrame() {3 val h = powerManager4 .getThermalHeadroom(10)5 if (h > 0.85f)6 lowerQuality()7 drawGarden()8}
In Remy's build, the headroom always comes back as NaN (not a number). Which lines are the problem?
- Lines 3 and 4
- Lines 5 and 6
- Line 7
Show the answer
Lines 3 and 4
Lines 3 and 4 ask 60 times a second. Asked more often than once every 10 seconds, the API returns NaN. Check it on a 10-second timer and keep the latest value.
iPhone: the thermal state
On iPhones, ProcessInfo.thermalState has four levels:
- nominal: within normal limits.
- fair: slightly raised. Apple says to put off background work like prefetching.
- serious: high, and performance drops. Apple's list includes lowering the target frame rate from 60 to 30 FPS, and using fewer particles or lower-resolution textures.
- critical: cut the processor, graphics and network work to the minimum the player needs.
On the web
- Compute PressureSince Chrome 125, a PressureObserver reports how hard the device is working. Chrome names games among its main uses, for example switching to lower-quality assets.
- Hidden means pausedrequestAnimationFrame pauses in background tabs, and the visibilitychange event lets us pause the music and the network too.
Tune it
My iPhone just reported thermalState serious in the middle of a co-op match. What should the game do?
Which response fits Apple's advice?
- Drop to 30 FPS and draw fewer sparkle particles until the phone cools
- Switch to 120 FPS to finish the wave faster
- Kick the player out of the match
Show the answer
Drop to 30 FPS and draw fewer sparkle particles until the phone cools
Apple lists both for the serious state: a lower target frame rate and fewer particles. The match goes on, a bit less shiny, instead of overheating or ending.
Battery is heat you can see
- Still screens, fewer framesA menu that isn't moving doesn't need 60 new frames a second.
- Let players chooseAndroid's Game Mode API lets a game respond to the player's choice of performance or battery life.
- Test like a playerEvery release candidate plays a 40-minute session on a budget phone, and we write down the frame times at minute 1 and minute 40.
Quick check
If getThermalHeadroom returns 0.9, the phone is 0.1 away from severe throttling.
- True
- False
Show the answer
True
1.0 means the severe status. 0.9 leaves 0.1 to go, so it is time to lower the workload before players feel it.
From one phone to thousands
Every phone talks to our servers. When thousands join at once, the servers have limits of their own.
Bolt says: Next: load testing, where we find those limits before players do.
Fact-checked 11 October 2026
- Android Developers: Thermal API developer.android.com
- Android Developers: Android Dynamic Performance Framework developer.android.com
- Apple Developer: ProcessInfo.ThermalState developer.apple.com
- Apple Developer: ProcessInfo.ThermalState.serious developer.apple.com
- Chrome for Developers: Compute Pressure API developer.chrome.com
- MDN: Window.requestAnimationFrame() developer.mozilla.org
- MDN: Page Visibility API developer.mozilla.org