# Tencent MMKV: mmap-backed key-value storage for mobile apps

> MMKV replaces SharedPreferences and NSUserDefaults with an mmap-backed store that writes on every encode call. Here is how it works, how to install it, and where it stops being the right choice.

**Tencent/MMKV** — An efficient, small mobile key-value storage framework developed by WeChat. Works on Android, iOS, macOS, Windows, POSIX, and OHOS.

- Repository: https://github.com/Tencent/MMKV
- Stars: 18,754 · Forks: 1,989
- Language: C++
- License: NOASSERTION
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/tencent-mmkv

## What MMKV replaces, and who it is written for

MMKV is a key-value storage framework built inside WeChat and published by Tencent. The problem it targets is the one every mobile app hits early: you need to persist a handful of small values (a session token, a user preference, a last-sync timestamp) and the platform default is slow or awkward. On Android that default is SharedPreferences, which serializes to XML and expects you to call apply or commit. On iOS and macOS it is NSUserDefaults, which expects a synchronize call if you want a guarantee about when the write lands.

MMKV's audience is the app developer who writes these values often, reads them on startup, and does not want to think about flushing. The README states the library is used in the WeChat application and is available on Android, iOS/macOS, Windows, POSIX and HarmonyOS NEXT, with experimental Kotlin Multiplatform support. The repository also carries top-level directories for Android, iOS, POSIX, Win32, OpenHarmony, flutter and Python, so the binding surface is wider than the two main mobile platforms.

The design bet is that mmap plus protobuf beats the platform store on both write cost and code volume. That bet is the whole product. If your values are large blobs, or you need to query across keys, MMKV is aimed at a different job than yours.

## How mmap and protobuf produce a store with no sync call

The mechanism the README names is mmap: the file holding your keys and values is mapped into the process address space, so a write to the mapping is a write to the file. There is no separate buffer that has to be copied out later. That is why the documentation can say all changes are saved immediately and no sync or apply call is needed. The encode call is the write.

Values are encoded and decoded with protobuf. That choice matters for two reasons. It gives a compact on-disk representation, which is part of how the library keeps its binary footprint small (the README cites about 50K per architecture on Android and less than 30K on iOS/macOS, much less when zipped). It also gives a typed API: the tutorials use encode and decodeBool, decodeInt, decodeString on Android and setBool, getBoolForKey, setInt32, getInt32ForKey, setString, getStringForKey on iOS. The type is carried through the call rather than inferred from the value.

The README also states that MMKV supports concurrent read-read and read-write access between processes, and that the core contains process locks alongside the encode/decode helpers and mmap logic. So multi-process access is a documented capability, not an accident of the file format. What the README does not describe is what happens to in-flight writes if a process is killed mid-encode; the POSIX and Windows documentation is silent on that failure mode, and I would not assume durability semantics beyond what mmap and the process locks give you.

## Installing MMKV on Android and a first encode

On Android the artifact comes from Maven. The README gives a single dependency line for the app module's build.gradle, with a note to replace the version with any available one. The current release listed in the repository is v2.4.2.

```gradle
dependencies {
    implementation 'com.tencent:mmkv:2.4.2'
    // replace "2.4.2" with any available version
}
```

Version choice is not free. The README states that starting from v2.0.0, MMKV no longer supports 32-bit architectures or API level 22 and 21, and that projects needing those should use the v1.3.x LTS series. The repository lists both v2.4.2 and v1.3.17 as recent releases, which matches that advice: the 1.3 line is still being published.

Initialization goes in your Application class. MMKV.initialize returns the root directory it chose, and the README example prints it so you can see where files land.

```Java
public void onCreate() {
    super.onCreate();

    String rootDir = MMKV.initialize(this);
    System.out.println("mmkv root: " + rootDir);
    //……
}
```

After that you use the global instance directly. The README's example encodes a boolean, an int and a string, then decodes them back. There is no commit or apply between the encode and the read.

```Java
import com.tencent.mmkv.MMKV;

MMKV kv = MMKV.defaultMMKV();

kv.encode("bool", true);
boolean bValue = kv.decodeBool("bool");

kv.encode("int", Integer.MIN_VALUE);
int iValue = kv.decodeInt("int");
```

On iOS and macOS the install path is CocoaPods: run pod repo update, add pod 'MMKV' to the app target in your Podfile, run pod install, open the generated .xcworkspace, and import MMKV/MMKV.h. Initialization is [MMKV initializeMMKV:nil] in didFinishLaunchingWithOptions, and the global instance is [MMKV defaultMMKV]. The README does not document a Swift Package Manager path in the section shown, even though Package.swift exists at the repository root.

## The Kotlin Multiplatform package is experimental, and the README says so

MMKV ships a Kotlin Multiplatform artifact, com.tencent:mmkv-kmp:2.4.2, added to commonMain dependencies in the shared module's kotlin block. The README is unusually direct about its status: the v2.4.2 KMP package is experimental, targets Android and iOS, and its API and artifact layout may change in a future release.

Supported targets are listed as Android, iosArm64, iosSimulatorArm64 and iosX64. Notably absent from that list are the desktop and server targets that the core library supports through POSIX and Windows. So the KMP artifact is not a way to share one storage layer across a mobile app and a JVM backend; it covers the two mobile platforms.

The experimental label should be read literally. If you put mmkv-kmp in a shared module and the artifact layout changes in a later release, your build files change with it. The README points to a Kotlin Multiplatform guide under KMP/ for initialization and packaging details rather than inlining them here, so the setup steps are not in the main README.

## Where MMKV is the wrong tool

MMKV is key-value storage. The README never describes a query language, an index, a schema, or a transaction that spans multiple keys. If you need to filter records by a field, join two sets of data, or roll back a group of writes atomically, MMKV does not offer that and the documentation does not pretend otherwise. Reaching for it there means building the missing layer yourself on top of encode and decode calls.

Multi-process access is documented, but the README does not spell out the cost. Concurrent read-write between processes means locking, and locking means contention. The README states the capability and stops; it gives no guidance on how many processes can write before throughput degrades, and no guidance on lock timeout behavior. If your architecture has several processes writing the same keys on a hot path, the README does not give you the numbers to plan with.

The binary-size figures are the other constraint. About 50K per architecture on Android and less than 30K on iOS/macOS is small for an app, and the README notes it is much less when zipped into an APK or IPA. But it is per architecture, so a multi-ABI Android build multiplies it. For a library or an SDK that other apps embed, that multiplication is worth counting before you add the dependency.

Finally, the v2.0.0 break is real: dropping 32-bit and API 21 to 22 pushed projects onto the v1.3.x LTS line. If your app still ships to those devices, you are maintaining against an older branch, and the v2.4.x features are not available to you.

## MMKV against AsyncStorage and the platform stores

The comparison people search for is MMKV versus AsyncStorage. AsyncStorage is the React Native storage layer and it is asynchronous by design: reads and writes return promises and resolve on a separate thread, which is why the API is shaped around async and await. MMKV's API is synchronous. The Android tutorial calls encode and then decodeBool on the next line and expects a value. That difference is the whole argument. Synchronous access is simpler to reason about and removes a class of race conditions, but it means the call blocks the calling thread, so where you call it still matters.

Against SharedPreferences and NSUserDefaults the difference is the storage mechanism. Those serialize through the platform's own format and give you explicit flush points (apply or commit, synchronize). MMKV maps the file and treats the encode call as the write. The trade-off is that you no longer have a flush point to reason about, which is either the feature you wanted or the control you just gave up, depending on how your app handles process death.

There is also a Flutter binding in the repository (the flutter directory) and a Python binding (Python/), so the comparison is not strictly Android and iOS. The repository's Dockerfile builds the POSIX Go binding under POSIX/golang, and the Makefile exposes a golang target that runs docker buildx build with an optional PLATFORM argument and writes to ./output. That is the path for server-side or desktop use of the same core.

## Licence and upgrade cost

The README's badge links to LICENSE.TXT and labels the licence BSD 3-Clause. The repository metadata reports the licence as NOASSERTION, meaning the automated classifier did not map the file to a known identifier. Those two signals disagree, so read LICENSE.TXT yourself before you ship. This is a description of what the repository says, not legal advice.

BSD 3-Clause is permissive, which matters for the embedding case: it does not carry the source-disclosure obligations of a copyleft licence, but it does carry the notice and attribution conditions, and the third clause restricts use of contributor names for endorsement. How those conditions apply to your distribution is a question for whoever handles your legal review, not something the README answers.

Upgrade cost is driven by the version split. The v2 line is current (v2.4.2, released 2026-08-21) and the v1.3 line is still receiving releases (v1.3.17, released 2026-08-03), so the project is publishing to two branches. A project on v1.3.x that wants 32-bit or API 21 to 22 support cannot simply move to v2 without dropping those targets. The repository's last push was on 2026-09-14, so the codebase is being touched, but the README does not document a migration guide for the v1 to v2 jump, and the CHANGELOG.md at the repository root is the place that would carry one.

## Conclusion

Adopt MMKV when you are replacing SharedPreferences or NSUserDefaults in a single app that writes small values frequently and can accept the binary-size cost; the Android artifact is one Gradle line and the iOS artifact is one Podfile line. Do not adopt it as a database: the README describes key-value storage only, with no query language, no schema and no transactions across keys. Before committing, verify two things in your own build: that your minimum API level is above 22, since v2.0.0 dropped 32-bit architectures and API 21 to 22, and that the BSD 3-Clause terms in LICENSE.TXT match how you redistribute the library, because the repository metadata reports the license as NOASSERTION rather than naming it.

## FAQ

### What is MMKV?

MMKV is an efficient, small, easy-to-use mobile key-value storage framework used in the WeChat application, developed by Tencent. It uses mmap to keep memory synced with files and protobuf to encode and decode values.

### What is MMKV on my iPhone?

MMKV is available on iOS and macOS, where it is installed through CocoaPods by adding pod 'MMKV' to your app target. On iOS the global instance is [MMKV defaultMMKV], and all changes are saved immediately with no synchronize call needed.

### Which platforms does Tencent MMKV support?

The README lists Android, iOS/macOS, Windows, POSIX and HarmonyOS NEXT, with experimental Kotlin Multiplatform support targeting Android and iOS. The repository also contains bindings for Flutter and Python.

### Does MMKV need a sync or apply call after writing?

No. The README states that all changes are saved immediately and that no sync, apply or synchronize calls are needed, because MMKV uses mmap so the encode call itself is the write.

### Does MMKV support multiple processes?

Yes. The README states that MMKV supports concurrent read-read and read-write access between processes, and that the core contains process locks alongside the encode/decode helpers and mmap logic.

### Why can I not use MMKV v2 on a 32-bit Android device?

The README states that starting from v2.0.0, MMKV no longer supports 32-bit architectures or API level 22 and 21. Projects that need those should use the v1.3.x LTS series instead.

## Sources

- [Issues](https://github.com/Tencent/MMKV/issues)
- [README](https://github.com/Tencent/MMKV/blob/master/README.md)
- [Releases](https://github.com/Tencent/MMKV/releases)
- [Tencent/MMKV on GitHub](https://github.com/Tencent/MMKV)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/tencent-mmkv
