Concept
First, we need to understand the purpose of DataStore.
Currently, in Android apps, there are 5 ways to store data, with SharedPreferences being the simplest for storing data. It only consists of key and value, where the value can be an integer, string, etc.

When the app is opened for the first time, it reads all values from the SharedPreferences XML file and loads them into RAM. This file reading process happens on the UI Thread. If there are too many values and the task takes more than 5 seconds, it will cause an ANR (Application Not Responding) error.
And DataStore was created to replace SharedPreferences.
DataStore is a solution for storing data as key-value pairs or typed objects with protocol buffers.
Of course, DataStore is still only for storing simple structured data. It uses Coroutines and Flow to store data asynchronously and consistently.
DataStore has 2 types: Preferences DataStore and Proto DataStore. Let’s look at the comparison table:
| Preferences DataStore | Proto DataStore |
|---|---|
| Store and access data by key | Store instances of a custom data type |
| No need to define data type in advance | Must define data type in advance with protocol buffers |
| No type safety | Has type safety |
Preferences DataStore
Create
To use Preferences DataStore, we need to create an instance of DataStore<Preferences> using a property delegate with the preferencesDataStore keyword.
| |
Read
First, there are 7 functions corresponding to 7 data types:
intPreferencesKey()longPreferencesKey()doublePreferencesKey()floatPreferencesKey()booleanPreferencesKey()stringPreferencesKey()stringSetPreferencesKey()
When reading data, use the function corresponding to the value you want to store. For example, to store a counter variable as an integer to count how many times the user opens the app:
| |
The difference from SharedPreferences is that here, data is returned as a Flow. Now, upper layers like Repository can observe data consistently, regardless of whether it comes from DataStore, Room database, or Server, because everything is returned as a Flow.
Write
To write data, use the edit function, which is quite similar to SharedPreferences.
| |
Proto DataStore
Before learning about Proto DataStore, let’s take a look at protocol buffers.
Protocol buffers
This is a data format that is independent of programming language or platform. It’s like JSON but much smaller and faster. Protocol buffers are also said to be the most widely used data format at Google.
- Used to store compact data
- Fast parsing
- Supports many programming languages like C++, C#, Dart, Go, Java, Kotlin, Python
- Optimizes functionality through auto-generated classes
For example, a message about user info with name, id, and email:
| |
To compare the performance of Protocol buffers and JSON, let’s make 500 GET requests from one Spring Boot app to another, with and without data compression. Here are the results:

We can see Protocol buffer is 5 to 6 times faster than JSON.
Create
To use Proto DataStore, you must define the data type with a proto file settings.pb in the folder app/src/main/proto/ like this:
| |
Next, declare an object implementing the Serializer<T> class, where T is the data type defined in the proto file.
| |
Finally, use the property delegate with the dataStore keyword to create an instance of DataStore<T>.
| |
Read
Similar to Preferences DataStore, use DataStore.data to return a Flow.
| |
Write
To write data to Proto DataStore, use the updateData() function.
| |
Comparison with SharedPreferences

Migrate from SharedPreferences to Preferences DataStore
To migrate, pass SharedPreferencesMigration to the produceMigrations parameter. DataStore will automatically migrate for you.
| |
Migrate from SharedPreferences to Proto DataStore
First, declare UserProfile and UserProfileSerializer as above. Then write a mapping function to migrate from key-value pairs in SharedPreferences to the data type in Proto DataStore.
| |
References
- https://developer.android.com/topic/libraries/architecture/datastore
- https://protobuf.dev/programming-guides/proto3
- https://android-developers.googleblog.com/2020/09/prefer-storing-data-with-jetpack.html
- https://stackoverflow.com/questions/9986734/which-android-data-storage-technique-to-use
- https://auth0.com/blog/beating-json-performance-with-protobuf
- https://proandroiddev.com/is-jetpack-datastore-a-replacement-for-sharedpreferences-efe92d02fcb3
- https://kinya.hashnode.dev/migrating-sharedpreferences-to-datastore-ckxzlvda101by8rs1c8bg4wdx
- https://amitshekhar.me/blog/jetpack-datastore-preferences
