Creuto is now an OpenAI Select Partner Read More
Google Play memory limits start February 2027: P90 caps per RAM tier, 200 MB background bitmaps and 25% R8. Why React Native apps fail by default.

A fresh React Native project ships with R8 switched off. The template's android/app/build.gradle still reads def enableProguardInReleaseBuilds = false, and from February 2027 that one line can put an app below Google Play's new floor. Google Play memory limits arrive the same month: memory usage and bitmap memory become core vitals, measured at the 90th percentile per device RAM tier, and apps with more than 10 MB of DEX code must hit 25% optimization, shrinking and obfuscation. By the end of this post you will know the exact thresholds, which ones cross-platform apps are most exposed to, and what to check in Play Console before January's data is the data Play judges.
The source for everything below is Google's own Play Console technical quality requirements page, announced on 26 August 2026, and the Android vitals documentation. Facts are as of 9 November 2026.
| Requirement | Starts | Who it applies to |
|---|---|---|
| Memory usage (Anonymous RSS + swap) thresholds | February 2027 | Apps and games, phones and tablets, separate limits for each |
| Bitmap memory usage thresholds | February 2027 | Apps and games, phones and tablets |
| Minimum 25% DEX optimization, shrinking and obfuscation | February 2027 | Apps with more than 10 MB DEX, games with more than 50 MB DEX, all form factors |
| Zero-Tap Sign-In restoration | April 2027 | Apps with optional or mandatory sign-in; games exempt for now |
Play measures two new memory metrics, and both sit under a new Memory heading in Android vitals and in the Play Developer Reporting API. The first is memory usage as Anonymous RSS plus swap. Google's memory usage metric page defines it as every memory page not backed by a file on storage, such as heap and mmap allocations, including pages the system has compressed into zRAM. Code and assets loaded from the APK do not count. Your Java heap, your native allocations and anything a JavaScript or Dart runtime allocates through malloc do.
The second is bitmap memory usage. It is wider than it sounds: the bitmap memory documentation says it includes bitmaps allocated with malloc and bitmaps backed by shared memory or graphics buffers, which is why it does not always track the Anonymous RSS figure.
Play evaluates both the way it already evaluates crash and ANR rates. It uses the last 28 days of data and compares the 90th percentile against the threshold, so 10% of sampled readings can sit above the line before you are in breach. Play hasn't named a day in February, but a 28-day window means the data judged in early February is mostly collected in January. That shortens the real deadline more than the headline date suggests.
These are the 90th percentile limits for apps (not games) from the Play Console Help page. A dash means Play sets no threshold for that cell.
| Device RAM tier (total memory) | Foreground | User-perceived services | Background | Cached |
|---|---|---|---|---|
| 0-4 GB (under 3,200 MB) | - | - | - | - |
| 4 GB (3,200-4,800 MB) | 2 GB | 1 GB | 1 GB | - |
| 6 GB (4,800-6,800 MB) | 2.25 GB | 1.25 GB | 1.25 GB | - |
| 8 GB (6,800-9,216 MB) | 2.25 GB | 1.5 GB | 1.5 GB | - |
| 12 GB (9,216-14,336 MB) | 3.25 GB | 1.75 GB | 1.75 GB | - |
| 16 GB (14,336-18,432 MB) | 4.25 GB | 2 GB | 2 GB | - |
| Above 18,432 MB | - | - | - | - |
Games get higher limits; on the 4 GB tier, for example, a game's foreground limit is 2.25 GB and its background limit 2.0 GB. Play decides app or game from the category you set in Store settings, and the Help page warns that switching category to reach the looser numbers violates the Metadata policy.
Bitmap thresholds are the same across RAM tiers and differ only by app state. There is no foreground limit. In user-perceived services and background the line is 200 MB at P90, and in the cached state it is 400 MB, per the technical quality requirements. Google's reasoning is blunt: an app cannot render a bitmap while its UI is invisible, so holding one in the background is pure cost to the rest of the device.
The limits are not Android 17-only, either. Android's own memory limiter applies on Android 17 and later, but the Help page says Play evaluates every app version where it has data, which for both memory metrics means Android 13 and above.
From February 2027, any upload of an app with more than 10 MB of DEX code needs at least 25% on each of optimization, obfuscation and shrinking. Play shows your DEX size and the three percentages for every bundle in the app bundle explorer. Google recommends R8 but accepts any shrinker, and it warns that a CI or enterprise build can differ slightly from the one you test locally, so check the uploaded bundle, not your laptop's.
Here is where cross-platform stacks split.
enableProguardInReleaseBuilds = false and wires it to minifyEnabled. The React Native signed APK guide still calls enabling it optional and warns that it "often requires configuration specific to each native library".android.enableMinifyInReleaseBuilds and defaults it to false. You switch it on through the expo-build-properties config plugin, alongside enableShrinkResourcesInReleaseBuilds.Whether a React Native app trips the rule depends on whether it crosses the 10 MB DEX floor, which comes down to its native dependencies. We have not seen a public figure for a typical React Native DEX size, so do not assume either way: open the app bundle explorer and read the number. If it is over 10 MB and minify is off, your obfuscation score is the problem.
Flutter is the mirror image. Its Dart code is compiled ahead of time into native machine code, not DEX, so the DEX rule touches only the embedding and plugins. Flutter's exposure is on the memory side instead: by the metric's own definition, the Dart heap and the engine's native allocations are anonymous memory, so they count toward Anonymous RSS.
Flipping the flag is easy. Shipping the result is the work. Since Android Gradle Plugin 8.0, R8 runs in full mode by default, which makes stricter assumptions about reflection. A React Native app reaches Java and Kotlin classes through its native modules, and the React Native docs already warn that each native library can need its own rules in proguard-rules.pro. The failure mode is a release build that crashes at runtime on a class R8 stripped or renamed, which no debug build will show you.
Grab's case study shows both the cost and the payoff. Grab is a native app with over 10 million lines of code, not a cross-platform one, so treat it as evidence for R8 and profiles in general. Per the Android Developers Blog write-up from 19 October 2026, enabling R8 in compat mode with Baseline and Startup Profiles cut user-perceived ANRs by about 25% and improved cold start by about 27%. Moving to full mode added a further 10% ANR reduction and 10% startup improvement, for roughly 32.5% fewer ANRs and 35% faster cold starts overall. Its scores after full mode were 72% optimization, 73% shrinking and 79.6% obfuscation, about three times Play's floor. Grab also isolated reflection-heavy classes with targeted keep rules rather than broad exceptions, which is the approach we would copy.
Google has already shipped the tooling, so there is no reason to wait for enforcement to see where you stand. In order:
Once a threshold is exceeded, Play shows a warning on the vitals overview page, and it also flags unoptimized bitmaps, limited DEX optimization and limited split-bundle usage. Locally, adb shell dumpsys meminfo <package> gives a breakdown of Private Dirty (Anon RSS), Swap Dirty and bitmaps, and Perfetto's heapprofd samples native and Java allocations with low overhead.
Google's advice for native apps is to decode images at the size they are displayed, use a memory-conscious loader such as Coil or Glide, release bitmaps on TRIM_MEMORY_UI_HIDDEN, and never hold static references to bitmaps or views. Cross-platform apps have equivalents, but they are not the defaults.
| Stack | Image pipeline on Android | What to change |
|---|---|---|
React Native core Image | Fresco | Keep resizeMethod off none, which the Image docs call unsafe; use resize when the source is much larger than the view |
Expo expo-image | Glide | Default cachePolicy is disk; avoid memory or memory-disk for large galleries, and call Image.clearMemoryCache() when a heavy screen closes |
Flutter Image | Engine decode, Dart ImageCache | Set cacheWidth and cacheHeight to decode at display size; the default ImageCache cap is 100 MiB, so lower it or clear it when the app is backgrounded |
One honest gap: Google's bitmap metric is defined in Android terms, and neither Google nor Flutter has said how decoded images in Flutter's engine are attributed between bitmap memory and Anonymous RSS. Until the Console shows you, plan for them to count somewhere.
The strongest argument for doing nothing is that the numbers are generous. A 2 GB foreground limit on a 4 GB phone is a lot of memory for a booking or ordering app, the lowest RAM tier has no threshold at all, and Play judges P90, not your worst session. Most well-built apps will pass the foreground column.
The argument breaks on the background columns. On a 4 GB device the limit drops to 1 GB the moment your app leaves the screen, and bitmaps must fall below 200 MB. Everything your app keeps alive after the user switches away counts against that lower line: a JavaScript or Dart heap, an image cache sized for scrolling, and whatever your SDKs hold. The other weak point is the tail: P90 over 28 days means a leak that only shows in long sessions can push you over even when a fresh launch looks clean.
The stakes are real. The vitals page says Play may reduce visibility and show a warning on your store listing, and the Help page says the requirements "are not optional" and can affect publishing capabilities. The announcement says further detail will come later this year, so treat the exact penalty as unconfirmed, not as absent.
Zero-Tap Sign-In is the April 2027 requirement that apps with any sign-in restore the user's signed-in state automatically when they move to a new Android device through device-to-device transfer or cloud backup. Google's route is the Restore Credentials API in Credential Manager, available from Android 9. Apps without accounts are out of scope, and so are games for now.
Two details matter for planning. A Block Store integration counts only if it was in production by 30 September 2026, so new work should go straight to Credential Manager. And restoring identity is enough: the Help page says a "Welcome back" state meets the requirement, and MFA step-up stays your decision. For React Native and Flutter teams the work is a native call at startup and after sign-in, so check whether your auth library exposes it before you write a bridge.
The order matters because January's data is largely what Play reads in early February. Turn on R8 first if the app bundle explorer shows more than 10 MB of DEX, because keep-rule fixes need a full release cycle of testing. Then pull the Memory section of Android vitals, filtered to the 4 GB and 6 GB tiers and the background state, since that is where the margins are thinnest. Fix image decode sizes and background cache release next, and leave Zero-Tap Sign-In for the quarter after.
If your Android app was built in React Native or Flutter and nobody has looked at its release config since launch, this is the review it needs. Our React Native app development and Flutter app development teams can run this audit on an existing app, and our React Native vs Flutter verdict for 2027 covers how each stack ages. For a scoped R8, memory and sign-in readiness review before the February window, talk to our mobile app development team.
Google Play's new memory limits are 90th percentile thresholds for Anonymous RSS plus swap, set per device RAM tier and app state, such as 2 GB in the foreground and 1 GB in the background on 4 GB phones. Bitmap memory is capped at 200 MB in background and user-perceived service states.
Google Play memory thresholds take effect from February 2027 for apps and games on phones and tablets. Play judges a rolling 28 days of data, so the readings evaluated in early February are largely collected in January, which leaves less time to fix problems than the headline date suggests.
The 25% optimization requirement means every app upload with more than 10 MB of DEX code, or a game with more than 50 MB, must reach at least 25% on optimization, shrinking and obfuscation. Google recommends R8 but accepts any shrinker, and Play Console shows the scores in the app bundle explorer.
React Native apps with more than 10 MB of DEX code effectively need R8 enabled from February 2027, because the default template sets enableProguardInReleaseBuilds to false. Expo's bare template also defaults minify to false. Check your DEX size in Play Console's app bundle explorer before deciding.
Memory usage appears under the Memory heading in the Android vitals overview in Play Console. You can filter memory usage and bitmap memory usage by app state, device RAM tier, Android version and release, and a P99-to-P50 ratio of 3.5 or more suggests a memory leak.
Zero-Tap Sign-In is a Google Play requirement from April 2027 that apps with sign-in automatically restore a user's signed-in state on a new Android device. Google's route is the Restore Credentials API in Credential Manager, available from Android 9. Games and apps without accounts are currently out of scope.
Ready to take the first step towards unlocking opportunities, realizing goals, and embracing innovation? We're here and eager to connect.