docs/rx-storage-performance.md
Explore real-world benchmarks comparing RxDB's persistent and semi-persistent storages. Discover which storage option delivers the fastest performance.
import { PerformanceChart } from '@site/src/components/performance-chart'; import { PERFORMANCE_DATA_NODE, PERFORMANCE_METRICS, PERFORMANCE_DATA_BROWSER, PERFORMANCE_DATA_SERVER } from '@site/src/components/performance-data';
A big difference in the RxStorage implementations is the performance. In difference to a server side database, RxDB is bound to the limits of the JavaScript runtime and depending on the runtime, there are different possibilities to store and fetch data. For example in the browser it is only possible to store data in a slow IndexedDB or OPFS instead of a filesystem while on React-Native you can use the SQLite storage.
Therefore the performance can be completely different depending on where you use RxDB and what you do with it. Here you can see some performance measurements and descriptions on how the different storages work and how their performance is different.
The "normal" storages are always persistent. This means each RxDB write is directly written to disc and all queries run on the disc state. This means a good startup performance because nothing has to be done on startup.
In contrast, semi-persistent storages like memory mapped store all data in memory on startup and only save to disc occasionally (or on exit). Therefore it has a very fast read/write performance, but loading all data into memory on the first page load can take longer for big amounts of documents. Also these storages can only be used when all data fits into the memory at least once. In general it is recommended to stay on the persistent storages and only use semi-persistent ones, when you know for sure that the dataset will stay small (less than 2k documents).
In the following you can find some performance measurements and comparisons. Notice that these are only a small set of possible RxDB operations. If performance is really relevant for your use case, you should do your own measurements with usage-patterns that are equal to how you use RxDB in production.
Here the following metrics are measured:
findByIds() call.findByIds() call per document.find() call.find() calls that run in parallel. Each fetching 25% of the documents.count() call. Here we measure 4 runs at once to have a higher number that is easier to compare.The performance patterns of the browser based storages are very diverse. The IndexedDB storage is recommended for mostly all use cases so you should start with that one. Later you can do performance testings and switch to another storage like OPFS or memory-mapped.
<PerformanceChart title="Browser Storages" data={PERFORMANCE_DATA_BROWSER} metrics={PERFORMANCE_METRICS} />For most client-side native applications (react-native, electron, capacitor), using the SQLite RxStorage is recommended as a solid baseline. For React Native and Expo applications specifically, the new Expo Filesystem RxStorage bypasses the bridge and offers significantly better CPU and I/O performance. For non-client side applications like a server, use the MongoDB storage instead.
<PerformanceChart title="Node/Native Storages" data={PERFORMANCE_DATA_NODE} metrics={PERFORMANCE_METRICS} />When using RxDB on backend servers, you have different options compared to client-side applications. The Filesystem Node storage is a great choice for standalone Node.js processes utilizing local disk storage. The MongoDB storage provides solid performance for heavy server workloads. The FoundationDB storage is very fast and works well for distributed systems. For purely in-memory operations, the Memory storage offers the lowest latency.
<PerformanceChart title="Server Storages" data={PERFORMANCE_DATA_SERVER} metrics={PERFORMANCE_METRICS} />IndexedDB sits securely in the middle of browser storage performance. It is significantly slower than the fully synchronous LocalStorage memory cache, but it completely avoids blocking the main UI thread. However, compared to modern APIs like the Origin Private File System (OPFS), IndexedDB's complex internal B-tree implementations combined with serialization overhead make it significantly slower for high-throughput I/O operations and raw bulk writes.
</details>