Troubleshoot build performance with Build Analyzer

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

You can use the Build Analyzer to inspect the build performance of your project. The performance of your build might be affected by several factors that can change between builds. For each build you perform, the Build Analyzer tries to present the most important information so that you can quickly identify and resolve regressions in your build performance.

This page provides an overview of the Build Analyzer and some guidance on how to use the tool to improve the build performance of your project. For additional strategies on improving build performance, read Optimize your build speed.

The data that the analyzer presents changes based on each build. Particularly with large, complex builds, many factors can change between builds, thus changing the data that the analyzer surfaces to you as important factors in the build’s duration. So, it can be useful to build your project multiple times and compare the data in the analyzer to identify patterns.

Get started

Each time you build your app, the Build Analyzer creates a report and displays data from the latest report in the Build window.

To get started, proceed as follows:

  1. If you haven't already done so, build your app in one of the following ways:
    • Click Build > Make Project from the menu bar.
    • To build an Android App Bundle or APK, click Build > Build Bundle(s) / APK(s) > Build Bundle(s) or Build > Build Bundle(s) / APK(s) > Build APK(s) from the menu bar.
  2. To open the Build window, select View > Tool Windows > Build from the menu bar.
  3. To view the build report in the Build Analyzer, click the Build Analyzer tab in the Build window.

View plugins with tasks determining the build’s duration

When you first open the Build Analyzer after completing a build, the window displays an overview of the build analysis, as shown in figure 1.

Figure 1. The Build Analyzer overview page gives a summary of the findings.

To see a breakdown of plugins with tasks determining the build's duration, click Plugins with tasks impacting build duration on the overview page. You can also select Tasks from the dropdown and confirm that Group by plugin is selected.

Figure 2. The Build Analyzer provides a breakdown of plugins most responsible for your build's duration.

The tasks pane shows the tasks contributing to the build duration. Any tasks with issues have a warning icon next to them.

The graph shows the how much the task is contributing to the overall build duration.

The details pane details more information about detected issues for the selected task.

Each node displays the total time taken to execute the direct children of the node. These durations help you focus on inspecting the tasks with the highest impact on your build’s duration.

View tasks determining the build’s duration

To view a breakdown of the tasks that are contributing to your build's duration, click Tasks impacting build duration on the overview page. You can also select Tasks from the dropdown and confirm that Group by plugin is unselected.

Figure 3. The Build Analyzer provides a breakdown of tasks most responsible for your build's duration.

Gradle determines task execution by task interdependencies, project structure, and CPU load, and executes tasks either sequentially or in parallel. For a given build, the Build Analyzer highlights the set of sequentially executed tasks that determined the duration of the current build. Addressing inefficiencies in these highlighted tasks is the best starting point for reducing your overall build time.

You might see a different set of tasks determining build duration with each build you execute. For example, if you make changes to the build configuration, run a build with a different set of tasks—such as an incremental build—or run a build under different constraints, the Build Speed window might highlight a different set of tasks that most impacted that build's duration. Because of this variability, you might want to use the Build Speed window across multiple builds to consistently reduce build duration.

Each task listed is color-coded as follows:

  • Light blue: The task belongs to the Android Gradle plugin, Java Gradle plugin, or Kotlin Gradle plugin.
  • Blue: The task belongs to a third-party or custom plugin, such as a plugin you applied after creating a new project using Android Studio.
  • Purple: The task does not belong to a plugin but is used to dynamically modify project properties at runtime. For example, tasks that you might define within your build.gradle files.
  • Gray: The task, relative to other tasks highlighted by the analyzer, does not have a high impact on the build's duration.

You can click on each child task to learn more about its execution. For example, the analyzer provides additional detail such as the parent plugin, task type, other tasks that caused this task to run, and whether the task was executed incrementally, as shown in figure 2. The analyzer might also raise warnings that might help you configure the task to run more efficiently.

Inspect warnings

If the Build Analyzer detects that some tasks could be configured to run more efficiently, it provides a warning.

For example, a task that does not use the appropriate Gradle APIs to specify its inputs and outputs isn't able to take advantage of incremental builds. If your build includes such tasks, the Build Analyzer might flag the tasks with an Always-run warning, because they must execute with every build, regardless of whether their inputs change.

To see all the warnings the analyzer has identified for your build, click on All warnings on the overview page or select Warnings from the dropdown. The Warnings view shows the warnings grouped by category. For example, the Always-run node groups tasks that the analyzer determines are not properly configured for incremental builds.

When you click a child node, the analyzer describes the nature of the warning and possible steps you can take to resolve the issue. Additionally, if the task belongs to a plugin you applied to your project, the analyzer provides a Generate report link, as shown in figure 4.

Figure 4. Detailed information about Build Analyzer warnings.

When you click the Generate report link, a dialog appears with additional information that might help the plugin developer resolve the issue in a new version of the plugin. Click Copy to save the text to your clipboard to more easily paste the information into a bug report to the plugin developer.

Warning types

The Build Analyzer reports the following warning types:

  • Always run tasks: An always running task makes other tasks run on every build, which is unnecessary. There are two main reasons why you might see this warning:

    • (More common) You did not declare task inputs and outputs correctly. If this is the case, you should properly declare the inputs and outputs for your tasks. This means declaring inputs and outputs yourself where you can or changing plugin versions if the tasks triggering the warning are from third-party plugins.

    • (Less common) A task has upToDateWhen set to false, which should be avoided. It could be that there is some logic that evaluates to false or that upToDateWhen is hardcoded to be false. If there is logic that evaluates to false, this outcome might be intentional, and you might choose to ignore the warning. If upToDateWhen is hardcoded to be false, you should remove the hardcoding from your code.

  • Task setup issues: This warning is generated for tasks that declare the same directory as outputs. This means that those tasks outputs are most likely not being preserved between builds and those tasks always run, even when there are no changes. To address this warning you should declare different output directories for your tasks. This means declaring different output directories yourself where you can or changing plugin versions if the tasks triggering the warning are from third-party plugins.

  • Non-incremental annotation processor: This warning is generated in situations where an annotation processor is non-incremental and causes the JavaCompile task to always run non-incrementally. To address this warning, switch to an incremental annotation processor.

  • Configuration cache: This warning is presented if configuration caching is not enabled for your project. The Build Analyzer walks through a sequence of builds to check whether your project is compatible with configuration caching. If the compatibility checks are successful, you can turn configuration caching on from the Build Analyzer.

  • Check Jetifier: This warning is presented if the enableJetifier flag is present and enabled in your project; that is, if you have android.enableJetifier=true in your gradle.properties file. The Build Analyzer can perform a check to see whether the flag can be safely removed to enable your project to have better build performance and migrate away from the unmaintained Android Support libraries.

Check download impact

Build Analyzer provides a summary of time spent downloading dependencies and a detailed view of downloads per repository. To check the impact of downloads, select Downloads from the dropdown.

You can use this information to determine whether unexpected dependency downloads are negatively impacting your build performance. This is especially important during incremental builds, which shouldn't consistently download artifacts.

Specifically, you can use this information to identify configuration issues, such as use of dynamic versions of dependencies that cause unexpected downloads. Also, if you see a high number of failed requests for a specific repository, it could indicate that the repository should be removed or moved lower in your repository configuration.

Figure 5. The Build Analyzer shows the impact of downloads on build duration.