[Android 15](https://developer.android.com/about/versions/15)sets a default 60Hz refresh rate for games to optimize power consumption. To unlock higher frame rates like 120 FPS, you must now explicitly request them using the[Frame Rate API](https://developer.android.com/media/optimize/performance/frame-rate)or the Swappy library.

However, the system may override this request based on factors like battery level or device temperature. While higher refresh rates enhance visual smoothness, they also demand more power and generate additional heat. Therefore, it's crucial to offer users the option to choose their preferred refresh rate and carefully monitor performance to ensure a balanced user experience.

## Use the[`setFrameRate()`](https://developer.android.com/reference/android/view/Surface#setFrameRate(float,%20int))API

The[`setFrameRate()`](https://developer.android.com/reference/android/view/Surface#setFrameRate(float,%20int))API allows the game devs to use a specific display refresh rate. There are two steps to doing this:

1. Verify device and Android version compatibility.
2. Request high FPS using[`setFrameRate()`](https://developer.android.com/reference/android/view/Surface#setFrameRate(float,%20int)).

### Verify Device and Android Version Compatibility:

Use methods[`Display.getSupportedModes()`](https://developer.android.com/reference/android/view/Display#getSupportedModes())to determine if the device supports 90Hz, 120Hz, or other refresh rates. If the device is limited to 60Hz, it is not possible to exceed this limit.  

### Kotlin

    val display = windowManager.defaultDisplay
    val supportedModes = display.supportedModes
    for (mode in supportedModes) {
      Log.d("DisplayInfo", "Supported mode: ${mode.physicalWidth}x${mode.physicalHeight}, ${mode.refreshRate}Hz")
    }

### Request High FPS

Invoke[`setFrameRate()`](https://developer.android.com/reference/android/view/Surface#setFrameRate(float,%20int))when your rendering loop starts, during game window initialization, or when the target FPS needs to change the display refresh rate.

Even if you request a higher rate, the system might still limit the refresh rate to 60Hz due to factors like power saving mode or thermal throttling. If your game's rendering performance doesn't reach the target FPS, requesting higher refresh rate may consume unnecessary power consumption and increase the device's temperature.

The following snippet demonstrates how to avoid an overly high refresh rate with the`setFrameRate()`API.  

### Kotlin

    val targetFps = 120f
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
      window.setFrameRate(
          targetFps,
          Window.FrameRateCompatibility.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
          0
      )
    }

[The Framerate page](https://developer.android.com/media/optimize/performance/frame-rate)provides more detailed information for further reading.

## Use Frame pacing library

[The frame pacing library](https://developer.android.com/media/optimize/performance/frame-rate), or Swappy, is an open-source library designed to simplify[VSync](https://en.wikipedia.org/wiki/Vertical_blanking_interval)management and frame scheduling in C/C++ Android game engines. This tool streamlines the process of optimizing refresh rates, effectively acting as a higher-level abstraction layer over functionalities like[`setFrameRate()`](https://developer.android.com/reference/android/view/Surface#setFrameRate(float,%20int)). Furthermore, Swappy provides additional features that can enhance your game's overall smoothness and performance.

[The Swappy page](https://developer.android.com/media/optimize/performance/frame-rate)gives more detailed information.

## Additional Tips for Best Results

The following section lay out several top tips:

1. Dynamic Frame Rate Switching.
2. Performance Monitoring.
3. Provide FPS options based on maximum display refresh rate.

### Dynamic Frame Rate Switching

To optimize both performance and power consumption, consider implementing dynamic frame rate switching in your game. This technique lets you seamlessly transition between higher refresh rates like 120Hz for smoother gameplay during demanding scenes, and lower rates like 60Hz during less intensive moments or when battery life is a concern or targeting under 60FPS. Constantly running at 120Hz can lead to excessive[heat generation](https://developer.android.com/games/optimize/adpf/thermal)and rapid battery drain, potentially resulting in a negative user experience. By intelligently adjusting the refresh rate based on the current rendering load and device conditions, you can strike a balance between visual fidelity and[power efficiency](https://developer.android.com/games/optimize/power).

### Performance Monitoring

To ensure your game performs optimally at higher refresh rates, integrate performance monitoring tools such as a frame counter or performance overlay. These tools provide real-time feedback on your game's actual frame rate, allowing you to verify whether you're consistently achieving the target 120 FPS.

If your frame rate fluctuates significantly, consider targeting a lower achievable framerate on the given device. This can deliver a smoother experience without the performance hiccups that might occur when striving for the highest refresh rate.

### Provide FPS options based on maximum display refresh rate

Your game should detect the maximum display refresh rate supported by the current device, such as 60Hz, 90Hz, or 120Hz, and limit the FPS settings accordingly. For example, if the device only supports up to 60Hz, it is advisable to disable any options higher than 60FPS in the game settings to avoid confusing the player.