rxdb icon indicating copy to clipboard operation
rxdb copied to clipboard

Replication Crashes on iPad with 500 MB Data: OPFS JSON Parse Error After Crash (RxDB 16.9.0)

Open morfees opened this issue 9 months ago • 23 comments

I’m encountering an issue when replicating a large dataset (approximately 500 MB) on an iPad. During replication, the device’s memory eventually becomes saturated, and the app crashes and restarts. After restarting, replication does not resume properly; instead, I receive the following error:

Image

Steps to Reproduce: 1. Replicate a collection of roughly 500 MB on an iPad (about 1 Gb with all the collections combined). 2. Allow replication to run until the iPad memory is saturated. 3. Once the memory is exhausted, the app crashes and restarts. 4. On restart, replication does not resume, and instead, the worker displays the error mentioned above.

Hypothesis: My suspicion is that due to the crash, the app did not manage to complete writing all the data into the OPFS storage. As a result, only part of the data gets stored, leading to a corrupted JSON file (with, for example, a missing closing bracket). When the replication resumes and attempts to read from this file, it runs into a parsing error because of the corrupted data.

Questions / Requests for Assistance: 1. Is it possible that an unexpected crash during replication would leave the OPFS storage in a corrupted state? 3. Are there recommended practices or changes in RxDB that could help prevent this issue? 4• Is there a way to safely reset the database or detect/recover from such a corruption when an app crash occurs? 5• Any suggestions on handling large replication tasks on resource-constrained environments like an iPad to avoid such crashes?

Additional Notes: • Since I cannot directly access the OPFS storage on the iPad to inspect the file contents, any guidance on remote debugging or logging would be helpful.

•	"rxdb": "16.9.0"
•	"rxdb-premium": "16.9.0"
•	Platform: iPad (using OPFS for storage)

I appreciate any help or suggestions on how to resolve this issue. Thank you!

morfees avatar Apr 10 '25 15:04 morfees

We write JSON of documents in blocks in a way where either the full json is stored or nothing. From my side this looks like a safari bug (still has to be fixed on the RxDB side). Do you think you can try to reproduce the problem im chrom on a desktop device?

pubkey avatar Apr 11 '25 13:04 pubkey

It was just a hypothesis, so I’m not entirely sure. As for reproducing the issue on Chrome for desktop, I haven’t been able to, my computer has significantly more RAM. The problem seems to occur specifically for users on iPads with 3 to 4 GB of RAM. It performs noticeably better on iPads with 6 GB of RAM.

morfees avatar Apr 11 '25 14:04 morfees

Its possible to simulate less ram by running the browser in a docker container where you can define how much ram can be used.

pubkey avatar Apr 11 '25 15:04 pubkey

@pubkey I was able to reproduce it on a chromium browser on ubuntu :

Image

I also have this error sometimes :

Image

Since swapping indexDB with OPFS (+sharding), the app has been unpredictable on the ipad, we didn't have these errors with indexDB, but we had to switch because indexDB couldn't handle the size of the data we replicate.

morfees avatar Apr 18 '25 04:04 morfees

I also feel like the app is using a lot more RAM with OPFS than with indexDB

morfees avatar Apr 18 '25 12:04 morfees

@pubkey I was able to reproduce it on a chromium browser on ubuntu :

Image

I also have this error sometimes :

Image

Since swapping indexDB with OPFS (+sharding), the app has been unpredictable on the ipad, we didn't have these errors with indexDB, but we had to switch because indexDB couldn't handle the size of the data we replicate.

For context and after more testing, I get the error in the second screenshot first and after reloading the page I get the error in the first screenshot.

morfees avatar Apr 18 '25 14:04 morfees

I also feel like the app is using a lot more RAM with OPFS than with indexDB

with the OPFS storage, the is a memory leak somewhere, with IndexDB storage our app rarely goes above 1GB of ram for some users, but with OPFS storage like in this example it went above 9GB, we had to restart the app.

Image

morfees avatar Apr 18 '25 20:04 morfees

does a restart fix the memory and it goes back to normal? Or will it start up again with the same amount of memory usage? OPFS stores the index-string-to-document-position-mapping in memory, this is intentional but it should not raise to 9gb with any sane amount of data.

Do you have any indication if the memory goes up either on reads or on writes?

pubkey avatar Apr 19 '25 08:04 pubkey

does a restart fix the memory and it goes back to normal? Or will it start up again with the same amount of memory usage?

For context the screenshot was taken using dev mode, not on users' devices, but even on the ipad we are seeing some app crashes due to high memory usage, so it restart until it saturated again. I will share our experience below.

Do you have any indication if the memory goes up either on reads or on writes?

Aside from the initial replication where most of the writing happens, our app is mostly read-heavy with some minimal writings for time to time.

Just to share the broader experience for context of the users of our PWA in prod: • The original reason we switched to OPFS was because some iPad users couldn’t use the app at all with IndexedDB, they had large profiles (~300–500MB in one collection), and Safari’s storage limits were preventing replication. • Those users were falling back to using desktop browsers (Chrome, Edge), but we wanted to support them properly on iPad, so OPFS seemed like the right move.

After switching: • OPFS alone didn’t help with the large collection, we still couldn’t insert everything. • So we added sharding (10 shards, per the docs), and that allowed us to finally replicate the full data.

But then we ran into this memory issue: • Now it affects most of the users, even those who had no problems before. • We added key compression hoping to reduce memory load, but it either didn’t help or made things worse. • Some collections couldn’t use compression because they include a "|v" field, which clashes with how compressed keys are prefixed. The error message was clear, but is there a workaround to make it work ?

The frustrating part is that the migration made things worse for users who were previously fine, and it still doesn’t fix things for the ones we were targeting.

We’re now testing a rollback to IndexedDB but now with sharding + key compression, this is the result of initial tests: • On iPads where the app worked before, it still works fine. • For the users we were targeting with this migration, some are now able to use the app, and the rest can use it with crashes from time to time, which in ideal. • The app is noticeably slower compared to OPFS. (confirms what the docs say)

We’d love your input on whether this approach makes sense, and whether there’s anything else we could try to stabilize it further.

Thanks again!

morfees avatar Apr 19 '25 17:04 morfees

Can you reproduce the memory leak without dev-mode? If it really is a memory-leak in the OPFS storage, let's find it together and I will fix that. This is the most likely case that would make it work for your users.

pubkey avatar Apr 19 '25 23:04 pubkey

Can you reproduce the memory leak without dev-mode? If it really is a memory-leak in the OPFS storage, let's find it together and I will fix that. This is the most likely case that would make it work for your users.

When we test the app on an iPad (outside of dev mode), we can clearly see that it consumes significantly more RAM when using OPFS storage. Using tools like Device Monitor, RAM usage stays at around 98% consistently. It could be a memory leak, but it might also be that OPFS storage is just very memory-intensive. Debugging this is tricky though, as we only have access to the minified code and not the version with source maps.

morfees avatar Apr 19 '25 23:04 morfees

Do you have any handy tools to track memory usage ?

morfees avatar Apr 19 '25 23:04 morfees

Do you have any handy tools to track memory usage ?

I only use chrome devtools with the memory profiler.

Can you post your schema? Or send it to me via discord if it contains private information.

The questions is if the memory is really leaking with OPFS or if you store have data that just has a high memory footprint because of how OPFS stores index-to-doc-mappings in memory.

pubkey avatar Apr 20 '25 20:04 pubkey

@pubkey I have sent you the schema on discord.

morfees avatar Apr 23 '25 20:04 morfees

You schema has uid: { type: "string", maxLength: 100 } which means each in-memory index string will use 100*2byte for the primary key. Are your primary keys really that long? You can save memory by only having like maxLength: 32 for uuids.

Your schema does not have any indexes. This further indicates that there indeed is a memory-leak in OPFS storage itself.

pubkey avatar Apr 24 '25 10:04 pubkey

The length will not exceed 20, we will change that.

Your schema does not have any indexes. This further indicates that there indeed is a memory-leak in OPFS storage itself.

We don't use indexes for this collection because we query all the data at once

morfees avatar Apr 24 '25 14:04 morfees

This issue has been automatically marked as stale because it has not had recent activity. It will be closed soon. Please update it or it may be closed to keep our repository organized. The best way is to add some more information or make a pull request with a test case. Also you might get help in fixing it at the RxDB Community Chat If you know you will continue working on this, just write any message to the issue (like "ping") to remove the stale tag.

stale[bot] avatar May 02 '25 13:05 stale[bot]

Hi @pubkey, just following up to see if there’s any progress on this issue or anything I can do to help debug it.

We’re eager to use OPFS storage, since IndexedDB has been unreliable for us, sometimes when the app crashes, unsynced data can be lost permanently.

Please let me know if I can provide any logs or help reproduce the problem. Thanks!

morfees avatar Jun 28 '25 13:06 morfees

Hi @morfees Sorry I forgot to reply. This has been fixed on a dev-branch but releasing it will require a major version increement because it is a breaking change. The issue was how the meta-index for documents was stored where multiple documents have the same index value and then creating a memory leak on cleanup.

A major release is planned for the start of august.

pubkey avatar Jun 30 '25 11:06 pubkey

Thanks for the reply, looking forward to it!

morfees avatar Jul 01 '25 20:07 morfees

Hello @pubkey, is there a way to test this in the 17.0.0-beta.x version before the next major release ?

morfees avatar Jul 21 '25 09:07 morfees

Hi @pubkey, Just following up on the meta-index fix. You mentioned the release was planned for early August, do you have a specific timeline for that? In the meantime, if there’s a 17.0.0-beta.x version available, we’d be happy to test it so we can start preparing the migration on our side.

Thanks!

morfees avatar Aug 04 '25 15:08 morfees

it will take at least 4 weeks. There are more things that are considered breaking change which have to be added

pubkey avatar Aug 12 '25 10:08 pubkey