The functionality that works well as an on demand module are those that aren't needed by the majority of your users at install time. The following are a few examples for app features that would appropriate on demand modules:

- Editing and uploading a video in an app where the majority of users only watch videos
- Adding a recipe in an app, where most users only browse and follow others' recipes
- Help and support functionality when most users don't seek help, or don't seek it within the app
- Large libraries for less used functionality such as providing detailed bug capture and reporting
- Specific payment or checkout capabilities
- Very high-resolution media experiences or VR/AR features

In the typical case where these modules are relatively small (less than 10MB), and there aren't any network or other failures, users can download and use an on demand module very quickly. That is, the experience is typically no different than if the module had been present at app install.

This page describes best practices that help you do the following:

- Ensure your users are aware and feel in control of relatively larger module downloads which don't load instantly, or module install errors.
- Further optimize the module delivery experience, especially in situations where you can anticipate that a user will need a particular module.

After you've read through this guide, see these best practices in action by trying the[Play Core API sample app](https://github.com/android/app-bundle-samples/tree/main/DynamicFeatures).

## Keep the user informed

You should inform the user when a feature is not immediately available. If a user decides to download the feature from Google Play, display the progress of the download.

You can[monitor the request state](https://developer.android.com/guide/playcore/feature-delivery/on-demand#monitor_requests)to display the download progress and install state. However, the type of UI you want to display might depend on the size of the download:

- For smaller modules (\~10 MB or less) that can be installed very quickly, consider indicators such as spinners or a brief "downloading content" message.
- For larger modules that can take a few seconds or longer to download and install, consider showing a download and install progress bar, such as the one shown in figure 1.

![](https://developer.android.com/static/studio/images/projects/dynamic-delivery/progress_bar.png)

**Figure 1.**Displaying a message and progress bar when downloading and installing an on demand feature

<br />

## Communicate installation delays and failures gracefully

If a download fails or progresses slower than expected, clearly and transparently communicate to the user what's going on and what, if anything, they can do, as shown in figures 2 and 3. For example, if you[monitor the state of the download request](https://developer.android.com/guide/playcore/feature-delivery/on-demand#monitor_requests), and your app receives a`API_NOT_AVAILABLE`error, notify the user that their device doesn't support on demand downloads.  
![](https://developer.android.com/static/studio/images/projects/dynamic-delivery/failed_download.png)

**Figure 2.**Let the user know why a feature cannot be installed at this time  
![](https://developer.android.com/static/studio/images/projects/dynamic-delivery/large_download.png)

**Figure 3.**Explain to the user why a feature might be taking longer than expected to download

## Show value before permission is requested for large downloads

If an on demand module is large (\> 150MB), Google Play requires that the user first consent before downloading it.

Before you request the module, explain the value of the module to your users. Help them understand why you're making this request of them, as you would when requesting app permissions. Communicating openly with users increases the likelihood that they will accept the download.

For example, imagine you're building an e-commerce app and one of the features allows users to place furniture directly within their apartment using Augmented Reality (AR). You might include a message such as, "Would you like to see your new sofa in your living room? Install the augmented reality viewer now."

## Perform download and install in the background

Module download and installation should always occur in the background. That is, while a user is waiting for a feature to become available, you should allow them to continue using other parts of your app. And, when the feature is available, you should provide a notification that allows the user to switch to using that feature at their discretion.

As shown in figure 5, the user continues to use the app and receives a notification when the installation of an on demand feature is complete.

![](https://developer.android.com/static/studio/images/projects/dynamic-delivery/success_notification.png)

**Figure 5.**Rather than changing the user's context suddenly when a module installation is complete, notify the user that the requested feature is ready for them.

<br />

When the module is ready to use, notify the user and give them the choice whether to launch the feature. This pattern provides the user with context and control over their experience.

In some cases, you*could*launch the feature as soon as it's ready. However, because it might interrupt the user's experience, carefully consider whether this behavior is expected and appropriate.

## Free up device storage when a module is no longer needed

A useful capability of all feature modules is the ability to uninstall them, individually. If a feature module is no longer being used, you can reduce the size of your app on a user's device by requesting Google Play to[uninstall that module](https://developer.android.com/guide/playcore/dynamic-delivery#uninstall_modules).

For example, your app may have a robust onboarding flow, perhaps containing rich media. After a user has completed the onboarding flow, or after they've been active users for a certain amount of time, you can use the Play Feature Delivery API to request Google Play uninstall only that component of your app.

Keep in mind, you can also later uninstall modules that you include at initial app install. For example, a module that trains new users on how to use your app is valuable when users first use your app. However, to reduce app size, you can then uninstall it after they've completed the training.

## Advanced tips

Typically, you need to handle situations where the user explicitly signals intent to use the functionality of your on demand feature modules.

However, you might want to predict when a user is likely to engage with a feature*before*they signal to you that they want to use it. Using an app that allows you to download and create cooking recipes as an example, the following guidelines describe how to optimize the module delivery experience by anticipating user needs.

**Anticipate a user's need for a feature in the current session**. Consider if users only need to create an account for the recipe app when they want to create and share their own recipes with the community. You can use the account creation as a signal that the user is likely to want to add their own recipe start downloading the feature module before the user even taps on 'add recipe'. You can apply this approach to other user journeys in the app to make the feature download process more seamless.

**Anticipate a user's need for the feature in an upcoming session**. If you do not need your app to immediately download and install an on demand module, you can defer installation for when the app is in the background, and Google Play will handle the download and install for you. For example, imagine that you want to release new seasonal recipes for the cooking app, which aren't a high priority for the user's current session. You can request for Play to download and install these recipes when the app is in the background. This is especially useful for larger features (\>10MB) which aren't needed right away but will likely be needed in the future.
| **Note:** Requests for deferred installs are best-effort and you cannot track their progress. Before trying to access a module you had marked for deferred installation,[check that the module has been installed](https://developer.android.com/guide/playcore/feature-delivery/on-demand#manage_installed_modules). If it hasn't, you can always install it on-demand at that time.

**Anticipate a user's need for a feature ahead of app installation** . You might want to[add support for conditional delivery](https://developer.android.com/studio/projects/dynamic-delivery/conditional-delivery)to include your feature at install time based on user country, device hardware capability, and API level. For example, you might want to include recipes that use pork in conditional modules and omit that module from app install in regions that predominantly avoid pork dishes.