João Freitas

The following is a guide on how to debug and monitor an Android application performance impact if the device thermal state increases.

Stay organized with collections Save and categorize content based on your preferences.

This guide describes how to use the Android Dynamic Performance Framework (ADPF) to optimize games based on the dynamic thermal, CPU, and GPU management features on Android. The focus is on games, but you can also use the features for other performance-intensive apps.

ADPF is a set of APIs that allow games and performance-intensive apps to interact more directly with power and thermal systems of Android devices. With these APIs, you can monitor the dynamic behavior on Android systems and optimize game performance at a sustainable level that doesn’t overheat devices.

Mobile SoCs and Android have more dynamic performance behaviors than desktops and consoles. These behaviors include thermal state management, varying CPU and GPU clocks, and varying CPU core types. This combined with the increasingly diverse core topology of SoCs creates challenges when trying to ensure that your game can leverage this behavior without negatively impacting device performance. ADPF provides some of this information in order to make performance more predictable.

Here are the main ADPF features:

Thermal-state monitoring

Released: Android 11 (API level 30)

The potential performance of your app is limited by the thermal state of the device, which can vary based on characteristics such as weather, recent usage, and the device’s thermal design. Devices can only maintain high levels of performance for a limited amount of time before being thermally throttled. A key goal of your implementation should be to achieve performance goals without exceeding thermal limitations. Furthermore, when debugging performance issues, knowing when the thermal state of a device limits performance is important.

Game engines usually have runtime performance parameters that can adjust the workload the engine puts on the device. For example, these parameters can set the number of worker threads, worker-thread affinity for big and small cores, GPU fidelity options, and framebuffer resolutions.

When a device approaches an unsafe thermal state, your game can avoid being throttled by decreasing the workload through these parameters. To avoid throttling, you should monitor the thermal state of the device and proactively adjust the game engine workload. Once the device overheats, the workload must drop below the sustainable performance level in order to dissipate heat.


ADPF provides the PowerManager class for monitoring the thermal state of a device. Here are the main elements:

You can monitor the thermal state of the device by polling the getThermalHeadroom method. This method determines how long the device can maintain the current performance level without overheating. If the time is less than the amount needed to run the workload, then your game should decrease the workload to a sustainable level. For example, the game can shift to smaller cores, reduce the frame rate, or lower fidelity.

Note: If your game collects performance telemetry from players, the device’s thermal state is a good metric to include because it gives more context to any related issues.

CPU performance hints

Released: Android 12 (API level 31)

With CPU performance hints, a game can influence dynamic CPU performance behavior without overheating the device and wasting power. On most devices, Android dynamically adjusts the CPU clock speed and core type for a workload based on the previous demands. If a workload uses more CPU resources, the clock speed is increased and the workload is eventually moved to a larger core. If the workload uses less resources, then Android lowers resource allocation.

Clock speed

When Android devices dynamically adjust CPU clock speed, the frequency can change the performance impact of your code. Designing code that addresses dynamic clock speeds is important for maximizing performance, maintaining a safe thermal state, and using power efficiently. You can temporarily reduce jank and increase responsiveness by running your game at peak clock speeds, but it drains power and eventually leads to thermal throttling of the clocks. When CPU or GPU clocks are throttled, they perform below the sustainable level.

You cannot directly assign CPU frequencies in your app code. As a result, a common way for apps to attempt to run at higher CPU clock speeds is to run a busy loop in a background thread so the workload seems more demanding. This wastes power and increases the thermal load on the device when the app isn’t using the additional resources.

Core types

The CPU core types that your game runs on are another important performance factor. Android devices often change the CPU core assigned to a thread dynamically based on recent workload behavior. CPU core assignment is even more complex on SoCs with multiple core types. On some of these devices, the larger cores can only be used briefly without going into a thermally unsustainable state.

Your game shouldn’t try to set the CPU core affinity for the following reasons:


ADPF provides the PerformanceHintManager class so games can make performance hints to Android for CPU clock speed and core type. The OS can then decide how to best use the hints based on the SoC and thermal solution of the device. If your app uses this API along with thermal state monitoring, it can provide more informed hints to the OS instead of using busy loops and other coding techniques that can cause throttling.

This is how a game uses performance hints:

  1. Create hint sessions for key threads that behave similarly. For example:

    • Rendering threads get one session
    • IO threads get another session
    • Audio threads get a third session

    The game should do this early, at least 2ms and preferably more than 4ms before a session needs increased system resources.

  2. In each hint session, predict the duration needed for each session to run. The typical duration is equivalent to a frame interval, but the app can use a shorter interval if the workload does not vary significantly across frames.

Fixed-performance mode

Released: Android 11 (API level 30)

Android devices can change clocking dynamically based on the system load. This behavior is good for power savings during use, but can make it difficult to get reliable performance data. If you are trying to determine how fast a code fragment can run for regression prevention, or if an optimization is repeatable, your results won’t be reliable if they aren’t tested at fixed clock speeds. With fixed clocks, you can do accurate A/B testing of performance without changes in the CPU frequency being a factor.

Fixed-performance mode sets CPU and GPU clocks with an upper and lower bound. This mode does not disable other dynamic performance behaviors, such as core selection.

You can enable fixed-performance mode with the following adb command:

adb shell cmd power set-fixed-performance-mode-enabled [true|false]

A device that is running in fixed-performance mode can still overheat because the mode doesn’t put the device into a thermally-sustainable state. Because of this, we recommend the following for benchmark runs:

Sample app

The ADPF sample app demonstrates the basic use of the ADPF API. The sample displays the device’s thermal status using the ADPF getThermalHeadroom API and the thermal status API. The app also dynamically changes the workload based on the API’s hint and the PerformanceHintManager API to control render thread performance.


Integrating Adaptability Features Into Your Native Game codelab guides you to integrate ADPF features into your game with simple steps that you can follow at your own pace. At the end of the codelab, you will have integrated the following features and will better understand their functionalities:

Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.

#reads #google #android #cpu #monitor #thermal-state #performance