Skip to main content

RxStorage

RxDB is not a self contained database. Instead the data is stored in an implementation of the RxStorage interface. This allows you to switch out the underlying data layer, depending on the JavaScript environment and performance requirements. For example you can use the SQLite storage for a capacitor app or you can use the LocalStorage RxStorage to store data in localstorage in a browser based application. There are also storages for other JavaScript runtimes like Node.js, React-Native, NativeScript and more.

Quick Recommendationsโ€‹

Configuration Examplesโ€‹

The RxStorage layer of RxDB is very flexible. Here are some examples on how to configure more complex settings:

Storing much data in a browser securelyโ€‹

Lets say you build a browser app that needs to store a big amount of data as secure as possible. Here we can use a combination of the storages (encryption, IndexedDB, compression, schema-checks) that increase security and reduce the stored data size.

We use the schema-validation on the top level to ensure schema-errors are clearly readable and do not contain encrypted/compressed data. The encryption is used inside of the compression because encryption of compressed data is more efficient.

import { wrappedValidateAjvStorage } from 'rxdb/plugins/validate-ajv';
import { wrappedKeyCompressionStorage } from 'rxdb/plugins/key-compression';
import { wrappedKeyEncryptionCryptoJsStorage } from 'rxdb/plugins/encryption-crypto-js';
import { getRxStorageIndexedDB } from 'rxdb-premium/plugins/storage-indexeddb';
 
const myDatabase = await createRxDatabase({
    storage: wrappedValidateAjvStorage({
        storage: wrappedKeyCompressionStorage({
            storage: wrappedKeyEncryptionCryptoJsStorage({
                storage: getRxStorageIndexedDB()
            })
        })
    })
});

High query Loadโ€‹

Also we can utilize a combination of storages to create a database that is optimized to run complex queries on the data really fast. Here we use the sharding storage together with the worker storage. This allows to run queries in parallel multithreading instead of a single JavaScript process. Because the worker initialization can slow down the initial page load, we also use the localstorage-meta-optimizer to improve initialization time.

import { getRxStorageSharding } from 'rxdb-premium/plugins/storage-sharding';
import { getRxStorageWorker } from 'rxdb-premium/plugins/storage-worker';
import { getRxStorageIndexedDB } from 'rxdb-premium/plugins/storage-indexeddb';
import { getLocalstorageMetaOptimizerRxStorage } from 'rxdb-premium/plugins/storage-localstorage-meta-optimizer';
 
const myDatabase = await createRxDatabase({
    storage: getLocalstorageMetaOptimizerRxStorage({
        storage: getRxStorageSharding({
            storage: getRxStorageWorker({
                workerInput: 'path/to/worker.js',
                storage: getRxStorageIndexedDB()
            })
        })
    })
});

Low Latency on Writes and Simple Readsโ€‹

Here we create a storage configuration that is optimized to have a low latency on simple reads and writes. It uses the memory-mapped storage to fetch and store data in memory. For persistence the OPFS storage is used in the main thread which has lower latency for fetching big chunks of data when at initialization the data is loaded from disc into memory. We do not use workers because sending data from the main thread to workers and backwards would increase the latency.

import { getLocalstorageMetaOptimizerRxStorage } from 'rxdb-premium/plugins/storage-localstorage-meta-optimizer';
import { getMemoryMappedRxStorage } from 'rxdb-premium/plugins/storage-memory-mapped';
import { getRxStorageOPFSMainThread } from 'rxdb-premium/plugins/storage-worker';
 
 
const myDatabase = await createRxDatabase({
    storage: getLocalstorageMetaOptimizerRxStorage({
        storage: getMemoryMappedRxStorage({
            storage: getRxStorageOPFSMainThread()
        })
    })
});

All RxStorage Implementations Listโ€‹

Memoryโ€‹

A storage that stores the data in as plain data in the memory of the JavaScript process. Really fast and can be used in all environments. Read more

LocalStorageโ€‹

The localstroage based storage stores the data inside of a browsers localStorage API. It is the easiest to set up and has a small bundle size. If you are new to RxDB, you should start with the LocalStorage RxStorage. Read more

๐Ÿ‘‘ IndexedDBโ€‹

The IndexedDB RxStorage is based on plain IndexedDB. For most use cases, this has the best performance together with the OPFS storage. Read more

๐Ÿ‘‘ OPFSโ€‹

The OPFS RxStorage is based on the File System Access API. This has the best performance of all other non-in-memory storage, when RxDB is used inside of a browser. Read more

๐Ÿ‘‘ Filesystem Nodeโ€‹

The Filesystem Node storage is best suited when you use RxDB in a Node.js process or with electron.js. Read more

Storage Wrapper Pluginsโ€‹

๐Ÿ‘‘ Workerโ€‹

The worker RxStorage is a wrapper around any other RxStorage which allows to run the storage in a WebWorker (in browsers) or a Worker Thread (in Node.js). By doing so, you can take CPU load from the main process and move it into the worker's process which can improve the perceived performance of your application. Read more

๐Ÿ‘‘ SharedWorkerโ€‹

The worker RxStorage is a wrapper around any other RxStorage which allows to run the storage in a SharedWorker (only in browsers). By doing so, you can take CPU load from the main process and move it into the worker's process which can improve the perceived performance of your application. Read more

Remoteโ€‹

The Remote RxStorage is made to use a remote storage and communicate with it over an asynchronous message channel. The remote part could be on another JavaScript process or even on a different host machine. Mostly used internally in other storages like Worker or Electron-ipc. Read more

๐Ÿ‘‘ Shardingโ€‹

On some RxStorage implementations (like IndexedDB), a huge performance improvement can be done by sharding the documents into multiple database instances. With the sharding plugin you can wrap any other RxStorage into a sharded storage. Read more

๐Ÿ‘‘ Memory Mappedโ€‹

The memory-mapped RxStorage is a wrapper around any other RxStorage. The wrapper creates an in-memory storage that is used for query and write operations. This memory instance stores its data in an underlying storage for persistence. The main reason to use this is to improve query/write performance while still having the data stored on disc. Read more

๐Ÿ‘‘ Localstorage Meta Optimizerโ€‹

The RxStorage Localstorage Meta Optimizer is a wrapper around any other RxStorage. The wrapper uses the original RxStorage for normal collection documents. But to optimize the initial page load time, it uses localstorage to store the plain key-value metadata that RxDB needs to create databases and collections. This plugin can only be used in browsers. Read more

Electron IpcRenderer & IpcMainโ€‹

To use RxDB in electron, it is recommended to run the RxStorage in the main process and the RxDatabase in the renderer processes. With the rxdb electron plugin you can create a remote RxStorage and consume it from the renderer process. Read more

Third Party based Storagesโ€‹

๐Ÿ‘‘ SQLiteโ€‹

The SQLite storage has great performance when RxDB is used on Node.js, Electron, React Native, Cordova or Capacitor. Read more

Dexie.jsโ€‹

The Dexie.js based storage is based on the Dexie.js IndexedDB wrapper library. Read more

MongoDBโ€‹

To use RxDB on the server side, the MongoDB RxStorage provides a way of having a secure, scalable and performant storage based on the popular MongoDB NoSQL database Read more

DenoKVโ€‹

To use RxDB in Deno. The DenoKV RxStorage provides a way of having a secure, scalable and performant storage based on the Deno Key Value Store. Read more

FoundationDBโ€‹

To use RxDB on the server side, the FoundationDB RxStorage provides a way of having a secure, fault-tolerant and performant storage. Read more