This guide provides strategies for optimizing the performance of NebulaDB in your applications.
NebulaDB is designed to be fast by default, with in-memory operations and efficient data structures. However, as your data grows or your application becomes more complex, you may need to optimize for specific use cases.
Before optimizing, establish a baseline by measuring current performance:
// Measure query performance
console.time('Query');
const results = await collection.find({ /* your query */ });
console.timeEnd('Query');
// Measure insert performance
console.time('Insert');
await collection.insert({ /* your document */ });
console.timeEnd('Insert');
// Measure update performance
console.time('Update');
await collection.update({ /* query */ }, { /* update */ });
console.timeEnd('Update');
For more comprehensive benchmarking, use the benchmarking tools in the benchmarks directory.
Indexes are the most effective way to improve query performance:
// Create an index on frequently queried fields
collection.createIndex({ name: 'email_idx', fields: ['email'], type: 'unique' });
// Create a compound index for queries that filter on multiple fields
collection.createIndex({ name: 'user_location_idx', fields: ['country', 'city'], type: 'compound' });
// GOOD: Specific query that can use an index
await users.find({ email: 'user@example.com' });
// AVOID: Complex queries that can't use indexes efficiently
await users.find({ $or: [{ name: { $regex: '^A' } }, { age: { $gt: 30 } }] });
$or// Instead of this
for (const item of items) { await collection.insert(item); }
// Do this
const promises = items.map(item => collection.insert(item));
await Promise.all(promises);
async function getPage(collection, query, page, pageSize) {
const allDocs = await collection.find(query);
const start = (page - 1) * pageSize;
return allDocs.slice(start, start + pageSize);
}
const page1 = await getPage(users, { active: true }, 1, 10);
Before: 1,000 todos, no indexes, full collection scan — ~50ms queries
After: Index on completed + dueDate — ~5ms queries (10x improvement)
Before: 100,000 records, MemoryAdapter, all data loaded at once — high memory
After: Switched to SQLiteAdapter, pagination, indexes — 80% less memory, 60% faster loads
Performance optimization is an iterative process. Start with the simplest optimizations (like adding indexes) and measure the impact before moving to more complex strategies. Remember that premature optimization can lead to unnecessary complexity.