Skip to main content

Performance Optimization Examples

Examples of optimizing Strata Storage for maximum performance.

Batch Operations

import { Strata } from 'strata-storage';

const storage = new Strata();

// Inefficient: Multiple awaits
async function slowSave(items: any[]) {
for (const item of items) {
await storage.set(item.key, item.value);
}
}

// Efficient: Parallel operations
async function fastSave(items: any[]) {
await Promise.all(
items.map(item => storage.set(item.key, item.value))
);
}

// Most efficient: Batch API
async function batchSave(items: any[]) {
await storage.setMany(items);
}

Memory Caching

class CachedStorage {
private storage: Strata;
private cache = new Map<string, any>();
private cacheSize = 0;
private maxCacheSize = 10 * 1024 * 1024; // 10MB

async get(key: string) {
// Check memory cache first
if (this.cache.has(key)) {
return this.cache.get(key);
}

// Load from storage
const value = await this.storage.get(key);

if (value !== null) {
this.addToCache(key, value);
}

return value;
}

private addToCache(key: string, value: any) {
const size = JSON.stringify(value).length;

// Evict if needed
while (this.cacheSize + size > this.maxCacheSize && this.cache.size > 0) {
const firstKey = this.cache.keys().next().value;
this.evictFromCache(firstKey);
}

this.cache.set(key, value);
this.cacheSize += size;
}

private evictFromCache(key: string) {
const value = this.cache.get(key);
if (value) {
this.cacheSize -= JSON.stringify(value).length;
this.cache.delete(key);
}
}
}

Lazy Loading

class LazyStorage {
private storage: Strata;
private loaded = new Set<string>();
private loading = new Map<string, Promise<any>>();

async get(key: string) {
// Return loading promise if already in progress
if (this.loading.has(key)) {
return this.loading.get(key);
}

// Return cached if already loaded
if (this.loaded.has(key)) {
return this.storage.get(key);
}

// Start loading
const loadPromise = this.loadValue(key);
this.loading.set(key, loadPromise);

try {
const value = await loadPromise;
this.loaded.add(key);
return value;
} finally {
this.loading.delete(key);
}
}

private async loadValue(key: string) {
// Simulate expensive load operation
const value = await this.storage.get(key);

// Post-process if needed
if (value && value.compressed) {
return this.decompress(value.data);
}

return value;
}
}

Indexed Queries

// Configure with indexes for better query performance
const storage = new Strata({
adapters: {
indexedDB: {
indexes: [
{ name: 'byType', keyPath: 'value.type' },
{ name: 'byStatus', keyPath: 'value.status' },
{ name: 'byCreated', keyPath: 'value.created' },
{ name: 'byUserId', keyPath: 'value.userId' }
]
}
}
});

// Fast queries using indexes (conditions match the stored value by bare field name)
const activeUsers = await storage.query({
status: 'active'
});

// Compound queries
const recentActiveUsers = await storage.query({
status: 'active',
created: { $gt: Date.now() - 86400000 }
});

Compression Strategy

class SmartCompression {
private storage: Strata;

async set(key: string, value: any, options?: any) {
const size = JSON.stringify(value).length;

// Only compress large data
const shouldCompress = size > 1024; // 1KB threshold

return this.storage.set(key, value, {
...options,
compress: shouldCompress
});
}

async bulkCompress(pattern: string) {
// query() matches stored values, not the storage key — list keys and
// filter them by pattern, then re-store the large ones compressed.
const re = new RegExp(pattern);
const keys = (await this.storage.keys()).filter((k) => re.test(k));

await Promise.all(
keys.map(async (key) => {
const value = await this.storage.get(key);
if (value && JSON.stringify(value).length > 1024) {
await this.storage.set(key, value, { compress: true });
}
})
);
}
}

Read-Through Cache

class ReadThroughCache {
private storage: Strata;
private fetchers = new Map<string, () => Promise<any>>();

register(pattern: RegExp, fetcher: () => Promise<any>) {
this.fetchers.set(pattern.source, fetcher);
}

async get(key: string) {
// Check cache first
const cached = await this.storage.get(key);
if (cached !== null) {
return cached;
}

// Find matching fetcher
for (const [pattern, fetcher] of this.fetchers) {
if (new RegExp(pattern).test(key)) {
const value = await fetcher();

// Cache the result
await this.storage.set(key, value, {
ttl: 300000 // 5 minutes
});

return value;
}
}

return null;
}
}

Debounced Writes

class DebouncedStorage {
private storage: Strata;
private pendingWrites = new Map<string, any>();
private writeTimer: NodeJS.Timeout | null = null;

async set(key: string, value: any, options?: any) {
this.pendingWrites.set(key, { value, options });

if (this.writeTimer) {
clearTimeout(this.writeTimer);
}

this.writeTimer = setTimeout(() => {
this.flushWrites();
}, 100); // 100ms debounce
}

private async flushWrites() {
const writes = Array.from(this.pendingWrites.entries());
this.pendingWrites.clear();

await Promise.all(
writes.map(([key, { value, options }]) =>
this.storage.set(key, value, options)
)
);
}
}

Storage Metrics

class MetricStorage {
private storage: Strata;
private metrics = {
reads: 0,
writes: 0,
hits: 0,
misses: 0,
errors: 0
};

async get(key: string) {
this.metrics.reads++;

try {
const value = await this.storage.get(key);

if (value !== null) {
this.metrics.hits++;
} else {
this.metrics.misses++;
}

return value;
} catch (error) {
this.metrics.errors++;
throw error;
}
}

getMetrics() {
const hitRate = this.metrics.reads > 0
? (this.metrics.hits / this.metrics.reads) * 100
: 0;

return {
...this.metrics,
hitRate: `${hitRate.toFixed(2)}%`
};
}
}

See Also