Skip to content

[Due for payment 2025-10-28] [$250] Fix IndexedDB transaction memory leak in multiMerge #72346

@mountiny

Description

@mountiny

Coming from slack here

Proposal: Fix IndexedDB transaction memory leak in multiMerge

Background:

Onyx uses IndexedDB (via idb-keyval) as the storage layer on web. The multiMerge operation is one of the most frequently called storage operations, executing thousands of times during app initialization for accounts with substantial data. Currently, multiMerge uses a manual transaction pattern where it directly accesses the IDBObjectStore via idbKeyValStore('readwrite', (store) => {...}) to perform read-then-write operations within a single transaction. This pattern creates a transaction object that remains in memory along with all its associated IDBRequest objects and promise chains. For heavy accounts in Expensify, a single page load can trigger thousands of multiMerge calls, each creating these transaction structures.

Problem:

When users with heavy accounts load the app, if Onyx performs thousands of multiMerge operations, then the manual transaction pattern retains 383MB+ of memory in IDBDatabase and IDBTransaction objects that are never garbage collected, causing the app to crash or become unresponsive.

Solution:

Fix the multiMerge implementation to eliminate manual transaction management and let idb-keyval handle transaction lifecycle automatically ends. The specific code change is moving the .then(() => undefined) outside the idbKeyValStore callback so the transaction can complete immediately after all put operations finish, rather than being kept alive by the outer promise chain.
Impact: Memory snapshots show this reduces the retained size from 383,727KB (36% of total heap) down to ~1,000KB (negligible). This also prevents the accumulation of 100,000+ IDBTransaction objects in memory.

Draf PR: Expensify/react-native-onyx#688

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~021976681088702441783
  • Upwork Job ID: 1976681088702441783
  • Last Price Increase: 2025-10-10
Issue OwnerCurrent Issue Owner: @kadiealexander

Metadata

Metadata

Labels

Awaiting PaymentAuto-added when associated PR is deployed to productionBugSomething is broken. Auto assigns a BugZero manager.DailyKSv2ExternalAdded to denote the issue can be worked on by a contributor

Type

No type
No fields configured for issues without a type.

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions