DocumentationGitHub
Introduction
  • Getting Started
Core Concepts
  • Store & Collections
  • Indexes
  • Queries
  • Live Queries
Guides
  • CRUD Patterns
  • Pagination & Sorting
  • Search
  • Persistence
  • Performance
API Reference
  • Store API
  • Collection API
  • Query API
  • React Hooks
Introduction
  • Getting Started
Core Concepts
  • Store & Collections
  • Indexes
  • Queries
  • Live Queries
Guides
  • CRUD Patterns
  • Pagination & Sorting
  • Search
  • Persistence
  • Performance
API Reference
  • Store API
  • Collection API
  • Query API
  • React Hooks

Performance

Ramify DB is designed for speed, operating entirely in-memory. However, as datasets grow, following performance best practices ensures your application remains buttery smooth.

Performance Strategies

1. Strategic Indexing

Indexes are the single most important factor for read performance in where queries.

  • Always index fields used in where clauses for exact-match filtering (equals, anyOf, allOf).
  • Note: Indexes do NOT improve sorting. Sorting uses JavaScript's Array.sort() on the filtered results, regardless of whether the field is indexed. Indexes only optimize the initial filtering step.
  • Over-indexing Warning: Each index slows down write operations because every add/update/delete must update all indexes. However, memory impact is minimal since indexes store references to documents, not copies.

2. Batch Operations

When inserting or updating multiple records, always use bulk methods (bulkAdd, bulkPut, bulkDelete).

  • Why? Each individual operation triggers index updates and event emissions (for Live Queries). Bulk methods coalesce these into a single event and optimized index build, which is significantly faster.

3. Optimize Live Queries

Live Queries are powerful but come with overhead.

  • Granularity: Subscribe to specific datasets rather than whole collections if possible.
  • Component Design: Avoid having hundreds of small components each with their own useLiveQuery. Instead, query data higher up the tree and pass it down via props.
  • Selective Subscriptions: Subscribing to data that rarely changes still consumes cycles. Only use Live Queries for data that requires reactive updates.

Benchmark

Benchmarked using Benchmark.js for statistically significant results.

Environment

  • CPU: Apple M4 (10 cores)
  • RAM: 16.00 GB
  • OS: darwin arm64
  • Runtime: Node.js v22.19.0
  • Flags: None

Memory Usage

ScenarioHeap Used (MB)
Empty DB12.17
After Load (100k records)99.00

Results

Dataset: 100k messages

Operationms/opOps/sec±%Samples
get(id)0.00003429,174,7610.6596
bulkGet(50 ids)0.004326231,1420.9499
has(id)0.000003287,643,3154.9982
count()0.000004285,249,2333.9580
where(criteriaObject)9.6912311035.2269
where(index).equals()9.2084641095.2767
where(index).anyOf()29.178278345.9058
where(multiEntry).allOf()11.292184892.4878
add(doc)0.003467288,45012.0470
put(doc)0.004037247,6844.4591
update(id, changes)0.00003132,547,1990.7398
bulkPut(100 docs)0.4217612,37116.8186
bulkUpdate(50 ids)0.004415226,4770.2592
where(index).modify()28.333660351.0459
delete(id)0.00003528,208,3911.4988
bulkDelete(100 ids)0.006415155,881101.7993

All benchmarks run until achieving statistical significance.

PreviousPersistence
NextStore API