The New Default. Your hub for building smart, fast, and sustainable AI software
Table of Contents
and 6 more
React Native Async Storage is a simple, asynchronous key-value storage system for persisting small amounts of data on mobile devices. It allows apps to save and retrieve information such as user preferences, app settings, and cached data – even after the app has been closed or restarted. Originally bundled with React Native, it is now maintained as a community package.
For developers building cross-platform mobile apps, reliable data persistence is essential for a seamless user experience. Async Storage addresses this need with a lightweight, non-blocking API that works across iOS and Android.
Executive Summary
Async Storage is a lightweight key-value store for React Native that persists simple data like user preferences and flags across app sessions. It stores data as unencrypted strings with a 6 MB default limit. For sensitive data, use expo-secure-store or react-native-keychain.
For complex or large datasets, use SQLite or Realm. The current version is v3.1.1 (June 2026), which introduced scoped storage and renamed batch methods – but the default export singleton API used in most existing codebases still works.
Version note (June 2026): Version 3 introduced several breaking changes from v2: batch methods multiGet, multiSet, and multiRemove were renamed to getMany, setMany, and removeMany; mergeItem and multiMerge were removed; and new storage instances are now created with createAsyncStorage("name") for scoped isolation. The default export singleton (import AsyncStorage from '...') still works and covers the use cases in this guide. Android v3 installs require an additional build.gradle step – see the v3 docs for details.
When building mobile apps, one key aspect developers must consider is how to ensure their apps retain data. Even after the app has been closed or restarted, this capability ensures a seamless user experience and ongoing data management. React Native, a popular framework for cross-platform app development, addresses this need by providing community-maintained packaged Async Storage. React Native Async Storage stands out as an effective and lightweight tool for handling simple key-value data pairs. This blog post explores what React Native Async Storage is and provides a step-by-step guide to implementing and using it efficiently in projects.
Understanding React Native Async Storage
Async Storage is a simple yet powerful key-value storage system in React Native. It works like an asynchronous, mobile counterpart of web Local Storage. It allows the app to save and retrieve small amounts of data like user preferences, simple app settings, or cached data for offline functionality.
In older React Native versions, it came included in projects by default, but now it is a community-maintained package. Source
Async Storage's straightforward API makes it accessible to developers, providing essential functions such as storing, retrieving, deleting, and clearing all data to easily manage information. This simplicity is balanced by its non-blocking, asynchronous nature, which ensures that data operations do not interfere with the main thread or app performance.
Although primarily suited for storing lightweight data, Async Storage can also store more complex data structures, such as JSON objects. Leveraging Async Storage, React Native developers can create apps with improved offline capabilities and a more seamless user experience, ensuring that important data is retained between sessions.
How Does React Native Async Storage Work?
Async Storage is persistent storage, meaning data saved there is stored on the device's physical memory and remains available across app launches. This makes it a perfect solution for storing data that should be kept, regardless of whether the React mobile app is active, inactive, or not running at all.
Key-Value Pair Storage
Async Storage operates on a simple key-value pair storage system, similar to JavaScript's localStorage but with added capabilities for mobile environments.
Each piece of data is linked to a unique key – a string used as an identifier to store, retrieve, or delete the data. The value is also stored as a string, so developers should serialize more complex data structures, such as arrays or objects, using JSON.stringify() and parse them back with JSON.parse() upon retrieval.
This approach allows for flexibility in data storage while maintaining simplicity. For instance, an app can store a user's preferred language as a key-value pair such as (preferredLanguage, English), enabling it to quickly access and apply the setting when the app is reopened.
Data Persistence
Another main feature of Async Storage is its ability to persist data, meaning that data stored remains available even after the app is closed or the device is restarted. Stored locally on the device's file system and separate from the app's volatile memory – cleared when the app restarts – Async Storage ensures that user preferences, small caches, or other important non-volatile data stay consistent across sessions.
This feature is essential to the user experience; for example, storing a user's onboarding status lets an app remember whether the user has completed the initial walkthrough or tutorial.
Asynchronous Operations
Async Storage functions asynchronously, not blocking the app's main thread while reading or writing data. This is essential for app performance and responsiveness, especially on devices with limited resources. Because the operations are asynchronous, React Native developers interact with Async Storage using Promises or async/await syntax. This keeps the app's UI smooth and fluid, as data operations do not cause delays or freezing.
Where Is Data Stored on the Device?
Definitely not inside the application. On iOS, there are two possible locations where data saved to Async Storage can be stored. If data does not exceed 1024 characters, it is stored in a common manifest.json file; if it is bigger, it is stored in individual, dedicated files. Source
On Android, all the data stored in Async Storage is saved in the phone's SQLite database.
There are also some restrictions on how much data and big entries can be kept in Async Storage. This is mainly due to limitations in SQLite's storage capacity. The default limit is 6 MB for the total amount of data and 2 MB per record.
The Async Storage library allows users to adjust the total storage size by setting an AsyncStorage_db_size_in_MB flag. Source
However, it is important to keep in mind that the available space on the device's memory should not be exceeded when testing the limit.
React Native Async Storage: Use Cases, Limitations, and Security Considerations
Before choosing Async Storage for your project, it helps to understand where it works well, where it doesn't, and what security trade-offs to account for.
Where Async Storage Works Best
Async Storage works best for lightweight, non-sensitive data that should persist between sessions.
Typical use cases include storing user preferences (language, theme, notification settings), caching onboarding or tutorial completion status, persisting simple app state (last viewed screen, selected filters), supporting offline mode – libraries like TanStack Query use Async Storage to cache query results for offline access(source) – and storing non-sensitive feature flags or configuration values.
What Async Storage Cannot Do
Async Storage is not a general-purpose database. Its constraints are important to understand before choosing it.
String-only storage means all values must be strings. Objects and arrays require JSON.stringify() / JSON.parse(), which adds overhead and has no built-in schema validation.
Size limits apply: the default total storage cap is 6 MB, with a 2 MB limit per individual record. These can be adjusted on Android via the AsyncStorage_db_size_in_MB flag, but pushing against device storage limits is not recommended.
There is no querying or indexing – data can only be retrieved by its exact key. There is no way to search, filter, or run queries across stored data.
There is no encryption – data is stored in plaintext on the device's file system. Any data stored in Async Storage should be considered readable.
Async Storage is also not suited for relational or complex data. For structured datasets, relationships, or anything requiring queries, use SQLite or Realm instead.
Async Storage | SQLite | Realm | expo-secure-store | |
Data model | Key-value (strings) | Relational (SQL) | Object-oriented | Key-value (strings) |
Best for | Preferences, flags, small cache | Structured data, queries | Complex objects, offline-first | Tokens, secrets, credentials |
Storage limit | 6 MB default | Device storage | Device storage | ~2 KB per item (iOS) |
Encryption | No | Optional (SQLCipher) | Optional (encrypted Realm) | Yes (native keystore) |
Querying | By key only | Full SQL | Object queries | By key only |
Setup complexity | Minimal | Moderate | Moderate | Minimal |
Why Async Storage Is Not Safe for Sensitive Data
Async Storage is unencrypted. Even though each app has its own sandboxed storage, storing sensitive information like authentication tokens, API keys, or personal data in Async Storage is not safe. Source
On rooted or jailbroken devices, sandboxing can be bypassed, exposing anything stored in plaintext. Login tokens, session data, and secrets should never be placed in Async Storage – see the "Secure Storage in React Native" section below for the right alternatives.
Setting Up React Native Async Storage: Step-by-Step Guide
Follow this Async Storage React Native tutorial to set up the tool smoothly and use it in your React Native app or Expo project. The process is straightforward.
Start by installing the library. Run the following command in your project directory (you can also add it to your Expo project):
npm install @react-native-async-storage/async-storageAndroid note (v3+): Version 3 requires an additional step in your android/build.gradle file – add a reference to the local Maven repository included in the package. See the v3 installation guide for the exact snippet. Expo managed workflow handles this automatically.
Importing Async Storage:
import AsyncStorage from '@react-native-async-storage/async-storage';When using the library, there is one important thing to remember – Async Storage can only store string data. So, if you need to store a JSON object, remember to serialize it first.
How to Use Async Storage in React Native
The API is simple. Below are three functions that cover the most common operations: saving, retrieving, and removing data. One thing to remember: Async Storage can only store string data, so if you need to store a JSON object, serialize it first.
Saving data to Async Storage
async function saveDataToAsyncStorage(key: string, data: SomeData) {
try {
if (data) {
await AsyncStorage.setItem(key, JSON.stringify(data));
}
} catch (error) { // handle error }
}Getting data from Async Storage
async function getDataFromAsyncStorage(key: string) {
try {
const data = await AsyncStorage.getItem(key);
// if your data was a json object remember to parse it
if (data) { return JSON.parse(data); }
} catch (error) { // handle error }
}Removing data from Async Storage
async function clearAsyncStorage(key: string) {
try {
await AsyncStorage.removeItem(key);
} catch (error) { // handle error }
}By following these steps, you can effectively implement and manage data storage in your React Native app. If the functions presented are insufficient for your use case, Async Storage has comprehensive documentation on their API.
Hook support – a much-requested feature for reactive storage access – was shipped as part of v3. Check the v3 release notes for the hooks API.
Secure Storage in React Native
As mentioned earlier in the article, sensitive information – such as user tokens – should not be stored in Async Storage. So, where should it be stored? The short answer is in one of the dedicated React Native libraries. There are several options, such as expo-secure-store or react-native-keychain.
While their APIs look almost identical to the Async Storage API, it's good to know they are different under the hood. These libraries keep the data in a dedicated, encrypted place specifically designed for sensitive information. This ensures that the data is securely stored within the system and prevents other apps on the device from accessing it.
On iOS, data saved in the secure storage is kept in Keychain Services and Secured Shared Preferences on Android.
Best Practices for Using Async Storage in React Native
Keep stored data small and simple
Async Storage is designed for lightweight key-value pairs, not large datasets.
Store user preferences, flags, and small cached values. If you find yourself storing hundreds of keys or megabytes of data, that is a signal to migrate to SQLite or Realm.
Staying within the 6 MB default limit is not just a technical constraint – it is a design principle.
Use secure alternatives for sensitive data
Never store authentication tokens, API keys, passwords, or personal health/financial data in Async Storage.
Use expo-secure-store for Expo projects or react-native-keychain for bare React Native projects. These libraries encrypt data at rest using the platform's native secure storage (iOS Keychain, Android Keystore).
Structure data with JSON consistently
Since Async Storage only accepts strings, adopt a consistent pattern for serializing and deserializing complex data.
Always wrap storage operations with JSON.stringify() and JSON.parse(), and validate the parsed output. A corrupted or unexpected value can crash your app if you parse it without checking.
Handle errors on every operation
Every Async Storage call can fail – the device may be out of storage, the key may not exist, or the data may be corrupted.
Always wrap operations in try/catch blocks. Silent failures in storage operations lead to bugs that are difficult to reproduce and diagnose, especially across different devices and OS versions.
Use multiGet and multiSet for batch operations
When reading or writing multiple keys at once, use multiGet and multiSet instead of calling getItem and setItem in a loop – or getMany and setMany if you're on v3. Batch operations are more performant and reduce the number of bridge crossings between JavaScript and native code, which matters on lower-end devices.
When to Use React Native Async Storage – and When Not To
Async Storage solves a specific problem well: persisting small, non-sensitive key-value data across app sessions with minimal setup. For user preferences, feature flags, onboarding state, and lightweight caching, it remains the standard choice in the React Native ecosystem.
Where it falls short is equally important to understand. It offers no encryption, no querying, no indexing, and a relatively low storage ceiling. Using it beyond its intended scope – storing tokens, caching large datasets, or managing relational data – does not just underperform; it introduces real security and reliability risks.
The right approach is to treat Async Storage as one tool in a broader data management strategy: Async Storage for simple persistence, a secure storage library for credentials and secrets, and SQLite or Realm for structured or large-scale data. Knowing where each fits is what separates a functional app from a well-architected one.
Monterail's Experience with React Native Data Persistence
Building React Native applications that handle real-world scale requires making exactly these kinds of storage decisions early – not retrofitting them after performance or security problems emerge.
Monterail built the Beryl bike-sharing app in React Native to serve hundreds of thousands of simultaneous users across UK cities. At that scale, data persistence decisions – what goes in Async Storage, what needs secure storage, what requires a proper database – are architectural commitments that affect performance, security, and maintainability throughout the product lifecycle.
If you're building a React Native application and want a team experienced with these trade-offs, Monterail's mobile development team can help you make the right architectural decisions from the start.
Key Takeaways
Async Storage is a persistent, asynchronous key-value store – the mobile equivalent of localStorage, maintained as a community package since being removed from React Native core. The current version is v3.1.1.
It is best suited for lightweight data: user preferences, feature flags, onboarding state, and small caches. The default storage limit is 6 MB total, 2 MB per record.
Async Storage is not secure – all data is stored unencrypted in plaintext. Never use it for tokens, passwords, API keys, or any sensitive information.
Use secure alternatives for credentials: expo-secure-store (Expo) or react-native-keychain (bare RN) encrypt data using native platform keystores.
For complex or large data, use a proper database: SQLite or Realm provide querying, indexing, and higher storage capacity that Async Storage cannot match.
React Native Async Storage FAQ





