Articles · GuidesUpdated October 2026

Async storage keeps your app's data on the phone, unencrypted, and the backup takes a copy.

Async storage is the small key-value box a React Native app uses to remember things between launches, and Expo's own reference describes it in four words: asynchronous, unencrypted, persistent, key-value. Unencrypted is the one that matters. The library writes the string you give it and adds no protection of its own. Everything else the app saves sits in the same private folder on the phone: the local database, the files it downloads, the images it caches. That folder is exactly what a device backup is for, and on both platforms the backup is already running. Every figure and quote below was read on 17 October 2026.

What follows is where each kind of data actually lands, which parts of it a backup copies and which parts it leaves behind, and what the user sees when that copy is restored onto a new phone. Then the one key in your app config that decides the Android half of it, and why it is set to on before you touch anything.

Start here

The short version

On the device is not the same as only on the device.

Your app owns a private folder on the phone and writes everything there. Nothing else can read it. That part is true and it is the reason local-first apps have so little to declare. The part people miss is that both operating systems copy most of that folder into the owner's cloud account on a schedule, by default, and your unencrypted key-value store goes with it.

So there are really two decisions, not one. Which of your values are secrets, because those belong in an encrypted store rather than in async storage. And which of your files are worth preserving, because the backup rules on both platforms are drawn around the difference between data a user made and data the app can fetch again. Get the second one right and the directory layout does the work for you.

Where does a React Native app actually keep its data?

Inside one private container that belongs to your app and nothing else. The operating system hands every app its own at install time, and your code can only write inside it. There is no shared documents folder, no drive letter, no place a second app can wander into. When your app saves something it is saving in there, and when the app is deleted the container goes with it.

An Expo project reaches into that container through a few named doors, and the difference between them is the whole subject. Expo's FileSystem reference calls one of them the document directory, a place to store files that are safe from being deleted by the system. It calls another the cache directory, a place to store files that can be deleted by the system when the device runs low on storage. A third is the bundle, which holds the assets shipped with the app and is read only. The current reference names the first two as properties on a Paths object. If your project imports from the legacy entry point you will see older names for the same two places, so look for both when you are reading code you did not write.

Async storage is the fourth door, and it is the one generated code reaches for first because it is the easiest. It stores strings against keys: a theme choice, the last screen, a flag saying the tour has been seen. It is not part of React Native itself any more. The React Native documentation page for AsyncStorage now reads Removed from React Native and points you at the community packages instead, last updated 12 August 2026. In your project it is therefore an ordinary dependency listed in package.json, which is worth knowing before you decide whether to keep it. If the framework words are still new, start with what React Native is and then getting started with Expo, which covers the toolchain wrapped around it.

Two things follow from that layout and people get both wrong. The first is that private to your app does not mean hidden from the person holding the phone. The second is that this container is precisely what a device backup exists to copy. Which brings us back to the word in Expo's own one-line description of the library.

Expo SDK reference, Async Storage, read 17 October 2026

What does unencrypted actually cost you?

Expo is blunt about it. Async Storage is asynchronous, unencrypted, persistent, key-value storage, in the SDK reference's own words. Unencrypted means the library does not scramble the value. It saves the string you handed it. There is no key, no password and nothing to decrypt, so there is also nothing standing between the value and anything that can read the app's files.

For almost everything an app remembers, that is fine. A unit preference is not a secret. The cost appears when something that is a secret ends up in the same box because the same two lines of code were already there. A session token. A key the app was handed at sign-in. A PIN the user chose. Any of those sitting in async storage is sitting in the container in the form you wrote it.

Who can read it is a longer list than people expect. Anyone with an unlocked phone and developer tools attached. Anyone who gets at a copy of the backup, which is the next section. And on iOS the user themselves, if the project turned on file sharing: Expo's FileSystem reference documents an option that makes the app's Documents directory accessible to users through the Files app, iTunes File Sharing and other file management tools. That option exists so an app can hand files to the person. It also hands them everything else stored beside those files.

For credentials the answer is not a different directory, it is a different store. Google's Auto Backup documentation says it outright: to back up user credentials and authentication tokens, do not store them in shared preferences or a file, and use the Block Store APIs instead. Expo ships an encrypted store for the same reason, SecureStore, which keeps values in the iOS keychain and in Android shared preferences encrypted with the Android Keystore system. Move the two or three values that matter into it and leave the other two hundred keys where they are. A key you baked into the app at build time is a separate problem with a separate answer, because it travels inside the shipped bundle rather than in the app's data folder.

The privacy claim is where this catches honest people out. An app that keeps everything on the phone collects nothing, and that is a real and defensible position to be in. It is not the same thing as the data never leaving the phone, because the backup leaves the phone on the owner's behalf, into the owner's own cloud account, by default. If your app, your store listing or your privacy policy says data stays on your device, read that sentence again next to your own backup settings and check that it is still true. Be precise about the word unencrypted as well. It describes the library, not the phone, and whatever the operating system does underneath stops mattering the moment a second copy of that data exists somewhere else.

Expo SDK reference, Async Storage, read 17 October 2026

What happens to that data when the phone is backed up?

Most of it is copied to a cloud account, on a schedule, without you choosing anything. This is the part that catches out people who read on the device and heard stays on the device.

On Android the mechanism is Auto Backup, and Google's documentation, last updated 26 February 2026, is specific about it. Apps that target Android 6.0, API level 23, or higher automatically participate. The manifest flag android:allowBackup turns it on and off, and the default value is true. Every app can allocate up to 25 MB of backup data per app user, held in a private folder in the user's Google Drive account, which does not count against their personal Drive quota and costs them nothing. The backup is end-to-end encrypted on devices running Android 9 or higher using the device's PIN, pattern or password, and Google says the backup data cannot be read by the user or other apps on the device. Only the most recent backup is stored, and making a new one deletes the previous one.

What goes in is listed by name, which is unusually helpful. Shared preferences files. Files in your app's internal storage reached through getFilesDir or getDir. Files in the directory returned by getDatabasePath, which Google notes includes anything created with the SQLiteOpenHelper class, so your local database is in the backup. Files on external storage under getExternalFilesDir. What stays out is listed too: the directories returned by getCacheDir, getCodeCacheDir and getNoBackupFilesDir, which Google describes as needed only temporarily and intentionally excluded. If the app goes over the quota the system calls onQuotaExceeded and does not back the data up to the cloud at all.

On iPhone the mechanism is iCloud Backup, and Apple's developer documentation page on optimizing your app's data for iCloud Backup, read on 17 October 2026, describes the same shape. When iCloud Backup is in an enabled state it periodically creates a backup of the device, including your app's data. The container provides two directories for data the system is free to throw away, the temporary directory and the caches directory, the system periodically purges them, and iCloud Backup excludes them by default. For anything else you want left out you set a resource value on the file or the folder, and Apple adds a warning people skip over: that value exists only to provide guidance to the system about which files and directories it can exclude, and it is not a mechanism to guarantee those items never appear in a backup or on a restored device. Apple also notes that certain file operations reset resource values, so you set it again each time you save the file.

One key in an Expo project decides the Android half of this. The app config reference documents android.allowBackup, says it allows your user's app data to be automatically backed up to their Google Drive, and says that if it is set to false, no backup or restore of the application will ever be performed, which Expo suggests for an app that deals with sensitive information. Its default is the Android default, which is true. You set it in the app config rather than hand editing a native manifest, so it is a one-key change in a file you already own. iOS has no equivalent single switch, which is why the directory you chose for a file matters more there.

Check yours

Where each thing belongs, and what a backup does with it

Tick what your app keeps on the phone. The answers follow the rules each platform publishes for its own backup.

Nothing ticked. An app that stores nothing at all has no backup question to answer, and it also forgets everything every time it is closed.

Android Developers, back up user data with Auto Backup, last updated 26 February 2026, read 17 October 2026

What breaks when a backup lands on a new phone?

A restore gives the app its files back. It does not give the app its assumptions back, and the gap between those two is where the bugs live.

Start with the sharpest one. On Android an encrypted value does not make the trip, and this is deliberate. Expo's SecureStore reference says the Auto Backup system has to be configured to exclude its shared preferences entries, because it is impossible to decrypt them after restoring the backup, since those entries are deleted from the Android Key Store when the app is uninstalled. It adds that if your app has no custom backup configuration, the library configures that exclusion for you. So the new phone arrives with the complete local database, every preference and every unsent draft, and no token. The app opens with a full history and a signed-out user. If your code treats having data as proof of having a session, this is exactly where it does something strange, and the person reporting it will tell you the app broke when they got a new phone.

Then staleness. Only the most recent backup is stored, so the restored copy is as old as the last backup run, and anything the user changed afterwards is simply not in it. An app that treats its local rows as authoritative will quietly serve the old version of the world. An app that checks with a server on launch will not. If your app has no server at all, which is a reasonable choice, then say so in the interface rather than letting the user assume a restore is a sync.

Then the quota, which bites in a way nobody expects. A cache sitting in the wrong directory counts against the 25 MB, and once the app goes over it there is no cloud backup at all. That is the worst of both outcomes: you were paying the privacy cost of having the data copied and getting none of the benefit. Keeping throwaway files in the cache directory is not tidiness, it is what keeps the backup working.

One Android detail is easy to miss. For apps targeting Android 12 or higher, Google notes that on devices from some manufacturers setting android:allowBackup to false disables cloud-based backup and restore such as Google Drive backups, but does not disable device-to-device transfers for the app. Turning the flag off is not a promise that the data never moves. Google also points out that users can see a list of apps that have been backed up in the Google Drive app, so none of this is invisible to the person whose data it is.

Test the restore instead of reasoning about it. Google publishes a procedure for testing backup and restore, and running it once tells you more than a week of thinking. If the restored install opens to a blank screen or falls over on launch, that has stopped being a backup question and become a debugging a crash question, and the stack trace will tell you which key your code expected to find.

Android Developers, back up user data with Auto Backup, last updated 26 February 2026, read 17 October 2026

The same folder, treated differently by each platform

The questioniPhone, iCloud BackupAndroid, Auto BackupSame on both
On before you touch anythingYes, whenever the owner has iCloud Backup turned onYes, for anything targeting Android 6.0 or higherYes
Ordinary app files and the local databaseIncludedIncluded, with shared preferences and SQLite files namedYes
The cache directoryLeft out, and the system purges it anywayLeft out, along with the code cache and no-backup directoriesYes
A published size cap per appNo figure on the backup guidance page25 MB per app, per userNo
Turning it off for the whole appNo single switch. You flag files and folders, and Apple calls that guidanceOne key in the app config, android.allowBackup, set to falseNo

The row about a size cap is a difference in documentation, not necessarily a difference in behaviour. Google publishes a figure. Apple's backup guidance page does not carry one, and we did not find a published per-app cap for iCloud Backup, so treat the empty cell as unknown rather than as unlimited.

Where this lands if a builder generated your app

None of this layout belongs to the builder. Newly is an AI app builder: you describe an app in plain English and it writes a real React Native and Expo project you own. The document directory, the cache directory, async storage and both backup systems are the platform's, and they behave identically whether a person typed the code or an agent did. What generation changes is only the speed at which you arrive at a project with real data in it and no decision yet made about that data.

It also means the levers are reachable. The project has two-way GitHub sync, so the app config is a file you can open, edit and push, and the Android backup switch is one key inside it. Newly uploads iOS builds to TestFlight, publishes to Google Play internal testing and builds a standalone Android APK, so you can install a build on a second device and watch a restore for yourself. It does not submit to the App Store on your behalf, because Apple requires the owner of the content to submit. It is $25 a month with no free tier, and none of that changes what it costs to publish an app, which is a separate bill from the stores.

The honest limit is this. No builder can tell which of your values are secrets. It cannot know that one string is a bank token and another is the name of a colour. Reading your own storage calls and sorting the keys into two piles takes about five minutes, and it is worth doing before the first real user rather than after the first awkward email.

Questions people ask about where app data lives

Inside one private container the operating system gives your app at install time. An Expo project reaches into it through a few named places. The document directory, which Expo's FileSystem reference describes as a place to store files that are safe from being deleted by the system. The cache directory, which the same reference describes as a place to store files that can be deleted by the system when the device runs low on storage. The read-only bundle, which holds the assets shipped with the app. And async storage, a key-value box for small strings. No other app can read any of it, and there is no shared folder on the phone that your code writes to by default.

Sort your keys into two piles, then build

Secrets into an encrypted store, everything else into async storage, throwaway files into the cache directory. Three rules, and the backup on both platforms then does the right thing on its own.

Start building