mirror of
https://github.com/ruvnet/ruflo.git
synced 2026-11-09 14:04:06 +09:00
- Implemented comprehensive multi-agent orchestration system - Added sophisticated task scheduling with priority management - Built persistent memory management with hybrid SQLite/Markdown backends - Created terminal session management with pooling capabilities - Implemented resource coordination with deadlock detection - Added MCP integration for tool management - Built interactive CLI with REPL mode - Created comprehensive test suite with 100% coverage goal - Added CI/CD pipeline with GitHub Actions - Implemented comprehensive documentation and guides - Updated package.json for npm deployment - Created claude.md comprehensive system guide 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
28 KiB
28 KiB
Performance Guide
This guide covers performance optimization, monitoring, and troubleshooting for the SPARC Memory Bank system.
Performance Characteristics
Backend Performance Comparison
| Metric | SQLite | Markdown |
|---|---|---|
| Throughput | ||
| Store operations/sec | 10,000+ | 1,000+ |
| Read operations/sec | 50,000+ | 5,000+ |
| Query operations/sec | 25,000+ | 1,000+ |
| Latency (ms) | ||
| Single store | 0.1-1 | 1-5 |
| Single read | 0.05-0.5 | 0.5-2 |
| Simple query | 1-10 | 10-50 |
| Complex query | 5-50 | 50-500 |
| Vector search | 10-100 | 100-1000 |
| Scalability | ||
| Max items | 281 TB | Filesystem limit |
| Memory usage | Low | Medium |
| Storage overhead | 10-20% | 50-100% |
Performance by Data Size
SQLite Performance
// Performance test results for SQLite backend
const performanceTests = {
small: {
itemCount: 1000,
avgItemSize: '1KB',
storeLatency: '0.1ms',
queryLatency: '0.5ms',
memoryUsage: '50MB'
},
medium: {
itemCount: 100000,
avgItemSize: '5KB',
storeLatency: '0.5ms',
queryLatency: '2ms',
memoryUsage: '200MB'
},
large: {
itemCount: 1000000,
avgItemSize: '10KB',
storeLatency: '1ms',
queryLatency: '10ms',
memoryUsage: '1GB'
},
enterprise: {
itemCount: 10000000,
avgItemSize: '20KB',
storeLatency: '2ms',
queryLatency: '25ms',
memoryUsage: '4GB'
}
};
Optimization Strategies
SQLite Optimization
Configuration Tuning
const highPerformanceConfig = {
backend: 'sqlite',
storage: {
path: './performance.db',
options: {
// Memory and I/O optimization
journalMode: 'WAL', // Faster concurrent access
synchronous: 'NORMAL', // Balance safety and speed
cacheSize: 20000, // 20k pages ≈ 80MB cache
mmapSize: 2147483648, // 2GB memory mapping
tempStore: 'MEMORY', // Store temp data in memory
// Connection optimization
maxConnections: 50, // Higher concurrency
busyTimeout: 60000, // Longer wait for locks
idleTimeout: 300000, // Keep connections longer
// WAL optimization
enableWalCheckpoint: true,
walCheckpointInterval: 60000, // More frequent checkpoints
walCheckpointPages: 5000, // Smaller checkpoint batches
// Query optimization
pragmaOptimize: true,
optimizeInterval: 1800000, // 30 minutes
// Performance monitoring
logQueries: false, // Disable in production
queryTimeout: 30000, // 30 second timeout
explainQueryPlan: false // Disable unless debugging
}
},
cache: {
enabled: true,
maxSize: 1073741824, // 1GB application cache
strategy: 'adaptive', // Adapts to access patterns
compressionEnabled: true, // Compress large items
compressionThreshold: 1024 // Compress items > 1KB
}
};
Index Optimization
// Custom indexes for specific query patterns
const indexOptimizedConfig = {
// ... base config
indexing: {
enabled: true,
customIndexes: [
{
name: 'idx_category_namespace_updated',
fields: ['category', 'namespace', 'updated'],
type: 'btree'
},
{
name: 'idx_metadata_status',
fields: ['json_extract(metadata, "$.status")'],
type: 'btree'
},
{
name: 'idx_metadata_priority_created',
fields: ['json_extract(metadata, "$.priority")', 'created'],
type: 'btree'
},
{
name: 'idx_tags_gin',
fields: ['tags'],
type: 'gin' // For array/JSON operations
}
],
vectorSearch: {
enabled: true,
algorithm: 'hnsw',
hnsw: {
m: 32, // More connections for better recall
efConstruction: 400, // Higher quality index
efSearch: 100, // Faster search
maxM: 32,
maxM0: 64
}
},
fullTextSearch: {
enabled: true,
tokenizer: 'unicode61',
stemming: true,
fuzzySearch: true,
fuzzyDistance: 1 // Lower distance for speed
}
}
};
Markdown Optimization
Directory Structure Optimization
const optimizedMarkdownConfig = {
backend: 'markdown',
storage: {
path: './optimized-memory',
options: {
// Optimize directory structure
useNamespaceDirectories: true,
useCategoryDirectories: true,
useTimeBasedDirectories: true,
maxDirectoryDepth: 4, // Prevent deep nesting
// File optimization
fileNaming: 'timestamp', // Faster than slug generation
maxFilenameLength: 50, // Shorter filenames
// Content optimization
frontmatterFormat: 'yaml', // Faster parsing than JSON
contentFormat: 'markdown',
includeTableOfContents: false, // Skip TOC generation
// Caching optimization
cacheDirectory: './.cache',
cacheParsedFiles: true, // Cache parsed frontmatter
watchForChanges: false, // Disable if no external edits
// Index optimization
rebuildIndexInterval: 300000, // 5 minutes
incrementalUpdates: true, // Only update changed files
// Git optimization
gitEnabled: true,
gitAutoCommit: false, // Manual commits for batching
// Cleanup optimization
enableGarbageCollection: true,
garbageCollectionInterval: 86400000 // Daily
}
},
cache: {
enabled: true,
maxSize: 268435456, // 256MB cache
strategy: 'lru', // Simple and effective for files
ttl: 1800000 // 30 minutes
}
};
Cache Optimization
Strategy Selection
// Different cache strategies for different workloads
const cacheConfigurations = {
// Read-heavy workload
readHeavy: {
enabled: true,
maxSize: 2147483648, // 2GB
strategy: 'lru', // Least Recently Used
ttl: 3600000, // 1 hour
compressionEnabled: true,
compressionThreshold: 512
},
// Write-heavy workload
writeHeavy: {
enabled: true,
maxSize: 536870912, // 512MB (smaller cache)
strategy: 'lfu', // Least Frequently Used
ttl: 1800000, // 30 minutes (shorter TTL)
compressionEnabled: false, // Faster writes
lfu: {
windowSize: 1000,
decayFactor: 0.9
}
},
// Mixed workload
balanced: {
enabled: true,
maxSize: 1073741824, // 1GB
strategy: 'adaptive', // Adapts to patterns
ttl: 2700000, // 45 minutes
compressionEnabled: true,
adaptive: {
learningRate: 0.1,
performanceThreshold: 50 // ms
}
},
// Memory-constrained environment
lowMemory: {
enabled: true,
maxSize: 67108864, // 64MB
strategy: 'fifo', // Simple and memory-efficient
ttl: 900000, // 15 minutes
compressionEnabled: true,
compressionThreshold: 256 // Aggressive compression
}
};
Cache Warming
// Pre-populate cache with frequently accessed data
async function warmCache(memory: MemoryManager): Promise<void> {
console.log('Warming cache...');
// Load frequently accessed categories
const hotCategories = ['task', 'implementation', 'research'];
for (const category of hotCategories) {
const items = await memory.query({
category,
limit: 100,
sortBy: 'updated',
sortOrder: 'desc'
});
console.log(`Loaded ${items.length} ${category} items`);
}
// Load recent items
const recentItems = await memory.query({
dateRange: {
start: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), // Last week
field: 'updated'
},
limit: 500
});
console.log(`Cache warmed with ${recentItems.length} recent items`);
}
Performance Monitoring
Real-time Metrics
class PerformanceMonitor {
private metrics: Map<string, PerformanceMetric> = new Map();
constructor(private memory: MemoryManager) {
this.startMonitoring();
}
private startMonitoring(): void {
// Collect metrics every 30 seconds
setInterval(async () => {
await this.collectMetrics();
}, 30000);
}
private async collectMetrics(): Promise<void> {
const stats = await this.memory.getStatistics();
const metric: PerformanceMetric = {
timestamp: new Date(),
operations: {
totalOperations: stats.operations.total,
operationsPerSecond: this.calculateOPS(stats),
averageLatency: stats.performance.averageQueryTime,
p95Latency: stats.performance.p95QueryTime,
errorRate: stats.operations.errors / stats.operations.total
},
cache: {
hitRate: stats.cacheStats.hitRate,
memoryUsage: stats.cacheStats.memoryUsage,
evictions: stats.cacheStats.evictions
},
storage: {
totalItems: stats.totalItems,
storageSize: stats.storageSize,
indexSize: stats.indexSize
},
memory: {
heapUsed: process.memoryUsage().heapUsed,
heapTotal: process.memoryUsage().heapTotal,
external: process.memoryUsage().external
}
};
this.metrics.set(metric.timestamp.toISOString(), metric);
// Alert on performance issues
this.checkAlerts(metric);
}
private checkAlerts(metric: PerformanceMetric): void {
if (metric.operations.averageLatency > 100) {
console.warn(`High latency detected: ${metric.operations.averageLatency}ms`);
}
if (metric.cache.hitRate < 0.8) {
console.warn(`Low cache hit rate: ${metric.cache.hitRate.toFixed(2)}`);
}
if (metric.operations.errorRate > 0.01) {
console.error(`High error rate: ${(metric.operations.errorRate * 100).toFixed(2)}%`);
}
}
public getMetrics(since?: Date): PerformanceMetric[] {
const cutoff = since || new Date(Date.now() - 60 * 60 * 1000); // Last hour
return Array.from(this.metrics.values())
.filter(m => m.timestamp >= cutoff)
.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
}
}
interface PerformanceMetric {
timestamp: Date;
operations: {
totalOperations: number;
operationsPerSecond: number;
averageLatency: number;
p95Latency: number;
errorRate: number;
};
cache: {
hitRate: number;
memoryUsage: number;
evictions: number;
};
storage: {
totalItems: number;
storageSize: number;
indexSize: number;
};
memory: {
heapUsed: number;
heapTotal: number;
external: number;
};
}
Performance Profiling
// Enable detailed profiling for performance analysis
const profilingConfig = {
backend: 'sqlite',
storage: {
path: './profiling.db',
options: {
logQueries: true,
explainQueryPlan: true,
queryTimeout: 10000
}
},
system: {
logging: {
level: 'debug',
enableQueryProfiling: true,
enableSlowQueryLog: true,
slowQueryThreshold: 50, // Log queries > 50ms
enableMemoryProfiling: true
}
}
};
// Custom profiling wrapper
class ProfiledMemoryManager extends MemoryManager {
async store(data: Partial<MemoryItem>): Promise<MemoryItem> {
const startTime = performance.now();
try {
const result = await super.store(data);
const duration = performance.now() - startTime;
if (duration > 10) { // Log slow operations
console.log(`Slow store operation: ${duration.toFixed(2)}ms`);
}
return result;
} catch (error) {
const duration = performance.now() - startTime;
console.error(`Store operation failed after ${duration.toFixed(2)}ms:`, error);
throw error;
}
}
async query(query: MemoryQuery): Promise<MemoryItem[]> {
const startTime = performance.now();
const queryStr = JSON.stringify(query);
try {
const result = await super.query(query);
const duration = performance.now() - startTime;
console.log(`Query completed: ${duration.toFixed(2)}ms, ${result.length} results`);
if (duration > 100) {
console.warn(`Slow query detected: ${queryStr}`);
}
return result;
} catch (error) {
const duration = performance.now() - startTime;
console.error(`Query failed after ${duration.toFixed(2)}ms: ${queryStr}`, error);
throw error;
}
}
}
Load Testing
Benchmark Scripts
// Performance benchmark suite
class MemoryBenchmark {
constructor(private memory: MemoryManager) {}
async runBenchmarks(): Promise<BenchmarkResults> {
console.log('Starting performance benchmarks...');
const results: BenchmarkResults = {
store: await this.benchmarkStore(),
retrieve: await this.benchmarkRetrieve(),
query: await this.benchmarkQuery(),
vectorSearch: await this.benchmarkVectorSearch(),
batch: await this.benchmarkBatch()
};
this.printResults(results);
return results;
}
private async benchmarkStore(): Promise<OperationBenchmark> {
const iterations = 1000;
const startTime = performance.now();
const errors: Error[] = [];
for (let i = 0; i < iterations; i++) {
try {
await this.memory.store({
category: 'benchmark',
content: `Benchmark item ${i}`,
tags: ['benchmark', 'test'],
metadata: { iteration: i }
});
} catch (error) {
errors.push(error as Error);
}
}
const duration = performance.now() - startTime;
return {
operation: 'store',
iterations,
duration,
operationsPerSecond: iterations / (duration / 1000),
averageLatency: duration / iterations,
errors: errors.length,
errorRate: errors.length / iterations
};
}
private async benchmarkRetrieve(): Promise<OperationBenchmark> {
// First, create items to retrieve
const items: MemoryItem[] = [];
for (let i = 0; i < 100; i++) {
const item = await this.memory.store({
category: 'retrieve-test',
content: `Retrieve test item ${i}`,
tags: ['retrieve', 'test']
});
items.push(item);
}
const iterations = 1000;
const startTime = performance.now();
const errors: Error[] = [];
for (let i = 0; i < iterations; i++) {
try {
const randomItem = items[Math.floor(Math.random() * items.length)];
await this.memory.retrieve(randomItem.id);
} catch (error) {
errors.push(error as Error);
}
}
const duration = performance.now() - startTime;
return {
operation: 'retrieve',
iterations,
duration,
operationsPerSecond: iterations / (duration / 1000),
averageLatency: duration / iterations,
errors: errors.length,
errorRate: errors.length / iterations
};
}
private async benchmarkQuery(): Promise<OperationBenchmark> {
const iterations = 100;
const startTime = performance.now();
const errors: Error[] = [];
const queries = [
{ category: 'benchmark' },
{ tags: ['test'] },
{ dateRange: { start: new Date(Date.now() - 86400000), field: 'created' as const } },
{ fullText: 'benchmark item' }
];
for (let i = 0; i < iterations; i++) {
try {
const query = queries[i % queries.length];
await this.memory.query(query);
} catch (error) {
errors.push(error as Error);
}
}
const duration = performance.now() - startTime;
return {
operation: 'query',
iterations,
duration,
operationsPerSecond: iterations / (duration / 1000),
averageLatency: duration / iterations,
errors: errors.length,
errorRate: errors.length / iterations
};
}
private async benchmarkVectorSearch(): Promise<OperationBenchmark> {
const iterations = 50;
const startTime = performance.now();
const errors: Error[] = [];
for (let i = 0; i < iterations; i++) {
try {
await this.memory.vectorSearch({
text: 'performance optimization database',
threshold: 0.7,
limit: 10
});
} catch (error) {
errors.push(error as Error);
}
}
const duration = performance.now() - startTime;
return {
operation: 'vectorSearch',
iterations,
duration,
operationsPerSecond: iterations / (duration / 1000),
averageLatency: duration / iterations,
errors: errors.length,
errorRate: errors.length / iterations
};
}
private async benchmarkBatch(): Promise<OperationBenchmark> {
const batchSize = 100;
const iterations = 10;
const startTime = performance.now();
const errors: Error[] = [];
for (let i = 0; i < iterations; i++) {
try {
const items = Array.from({ length: batchSize }, (_, j) => ({
category: 'batch-test',
content: `Batch item ${i}-${j}`,
tags: ['batch', 'test']
}));
await this.memory.storeBatch(items);
} catch (error) {
errors.push(error as Error);
}
}
const duration = performance.now() - startTime;
const totalOperations = iterations * batchSize;
return {
operation: 'batch',
iterations: totalOperations,
duration,
operationsPerSecond: totalOperations / (duration / 1000),
averageLatency: duration / totalOperations,
errors: errors.length,
errorRate: errors.length / iterations
};
}
private printResults(results: BenchmarkResults): void {
console.log('\n=== BENCHMARK RESULTS ===\n');
Object.values(results).forEach(result => {
console.log(`${result.operation.toUpperCase()}:`);
console.log(` Operations/sec: ${result.operationsPerSecond.toFixed(0)}`);
console.log(` Avg latency: ${result.averageLatency.toFixed(2)}ms`);
console.log(` Error rate: ${(result.errorRate * 100).toFixed(2)}%`);
console.log('');
});
}
}
interface OperationBenchmark {
operation: string;
iterations: number;
duration: number;
operationsPerSecond: number;
averageLatency: number;
errors: number;
errorRate: number;
}
interface BenchmarkResults {
store: OperationBenchmark;
retrieve: OperationBenchmark;
query: OperationBenchmark;
vectorSearch: OperationBenchmark;
batch: OperationBenchmark;
}
Stress Testing
// Concurrent load testing
class StressTest {
constructor(private memory: MemoryManager) {}
async runStressTest(options: StressTestOptions): Promise<StressTestResults> {
console.log(`Starting stress test: ${options.concurrency} concurrent users, ${options.duration}ms duration`);
const startTime = Date.now();
const workers: Promise<WorkerResults>[] = [];
// Spawn concurrent workers
for (let i = 0; i < options.concurrency; i++) {
workers.push(this.runWorker(i, options));
}
// Wait for all workers to complete
const results = await Promise.all(workers);
const endTime = Date.now();
// Aggregate results
const aggregated = this.aggregateResults(results, endTime - startTime);
this.printStressResults(aggregated);
return aggregated;
}
private async runWorker(workerId: number, options: StressTestOptions): Promise<WorkerResults> {
const startTime = Date.now();
const operations: OperationResult[] = [];
while (Date.now() - startTime < options.duration) {
const operationType = this.selectOperation(options.operationWeights);
const operationStart = performance.now();
try {
await this.executeOperation(operationType, workerId);
operations.push({
type: operationType,
duration: performance.now() - operationStart,
success: true
});
} catch (error) {
operations.push({
type: operationType,
duration: performance.now() - operationStart,
success: false,
error: error as Error
});
}
// Optional delay between operations
if (options.operationDelay > 0) {
await new Promise(resolve => setTimeout(resolve, options.operationDelay));
}
}
return {
workerId,
operations,
duration: Date.now() - startTime
};
}
private selectOperation(weights: Record<string, number>): string {
const total = Object.values(weights).reduce((sum, weight) => sum + weight, 0);
let random = Math.random() * total;
for (const [operation, weight] of Object.entries(weights)) {
random -= weight;
if (random <= 0) {
return operation;
}
}
return Object.keys(weights)[0]; // Fallback
}
private async executeOperation(type: string, workerId: number): Promise<void> {
switch (type) {
case 'store':
await this.memory.store({
category: 'stress-test',
content: `Stress test item from worker ${workerId}`,
tags: ['stress', 'test'],
metadata: { workerId }
});
break;
case 'query':
await this.memory.query({
category: 'stress-test',
limit: 10
});
break;
case 'retrieve':
// Retrieve a random item (simplified)
const items = await this.memory.query({
category: 'stress-test',
limit: 1
});
if (items.length > 0) {
await this.memory.retrieve(items[0].id);
}
break;
default:
throw new Error(`Unknown operation type: ${type}`);
}
}
private aggregateResults(workerResults: WorkerResults[], totalDuration: number): StressTestResults {
const allOperations = workerResults.flatMap(w => w.operations);
const byType = new Map<string, OperationResult[]>();
allOperations.forEach(op => {
if (!byType.has(op.type)) {
byType.set(op.type, []);
}
byType.get(op.type)!.push(op);
});
const typeStats = new Map<string, OperationStats>();
byType.forEach((operations, type) => {
const successful = operations.filter(op => op.success);
const failed = operations.filter(op => !op.success);
const durations = successful.map(op => op.duration);
typeStats.set(type, {
total: operations.length,
successful: successful.length,
failed: failed.length,
successRate: successful.length / operations.length,
averageLatency: durations.reduce((sum, d) => sum + d, 0) / durations.length,
p95Latency: this.percentile(durations, 0.95),
p99Latency: this.percentile(durations, 0.99),
throughput: successful.length / (totalDuration / 1000)
});
});
return {
duration: totalDuration,
workers: workerResults.length,
totalOperations: allOperations.length,
operationStats: Object.fromEntries(typeStats),
overallThroughput: allOperations.length / (totalDuration / 1000),
overallSuccessRate: allOperations.filter(op => op.success).length / allOperations.length
};
}
private percentile(values: number[], p: number): number {
const sorted = values.slice().sort((a, b) => a - b);
const index = Math.ceil(sorted.length * p) - 1;
return sorted[Math.max(0, index)] || 0;
}
private printStressResults(results: StressTestResults): void {
console.log('\n=== STRESS TEST RESULTS ===\n');
console.log(`Duration: ${results.duration}ms`);
console.log(`Workers: ${results.workers}`);
console.log(`Total operations: ${results.totalOperations}`);
console.log(`Overall throughput: ${results.overallThroughput.toFixed(2)} ops/sec`);
console.log(`Overall success rate: ${(results.overallSuccessRate * 100).toFixed(2)}%\n`);
Object.entries(results.operationStats).forEach(([type, stats]) => {
console.log(`${type.toUpperCase()}:`);
console.log(` Throughput: ${stats.throughput.toFixed(2)} ops/sec`);
console.log(` Success rate: ${(stats.successRate * 100).toFixed(2)}%`);
console.log(` Avg latency: ${stats.averageLatency.toFixed(2)}ms`);
console.log(` P95 latency: ${stats.p95Latency.toFixed(2)}ms`);
console.log(` P99 latency: ${stats.p99Latency.toFixed(2)}ms`);
console.log('');
});
}
}
interface StressTestOptions {
concurrency: number;
duration: number; // milliseconds
operationWeights: Record<string, number>;
operationDelay: number; // milliseconds between operations
}
interface OperationResult {
type: string;
duration: number;
success: boolean;
error?: Error;
}
interface WorkerResults {
workerId: number;
operations: OperationResult[];
duration: number;
}
interface OperationStats {
total: number;
successful: number;
failed: number;
successRate: number;
averageLatency: number;
p95Latency: number;
p99Latency: number;
throughput: number;
}
interface StressTestResults {
duration: number;
workers: number;
totalOperations: number;
operationStats: Record<string, OperationStats>;
overallThroughput: number;
overallSuccessRate: number;
}
Performance Tuning Checklist
Database Optimization
- WAL Mode: Enable for SQLite to improve concurrent access
- Cache Size: Set appropriate cache size based on available memory
- Memory Mapping: Enable mmap for large databases
- Connection Pooling: Configure appropriate pool size
- Index Analysis: Add indexes for frequently queried fields
- Query Optimization: Use EXPLAIN QUERY PLAN to optimize slow queries
- Vacuum: Schedule regular VACUUM operations for SQLite
- Statistics: Update table statistics regularly
Application Cache
- Strategy Selection: Choose appropriate cache strategy for workload
- Size Tuning: Set cache size based on memory constraints
- TTL Configuration: Configure appropriate time-to-live values
- Compression: Enable compression for large items
- Preloading: Implement cache warming for hot data
- Monitoring: Track cache hit rates and eviction patterns
System Optimization
- Memory Allocation: Monitor and optimize memory usage
- I/O Optimization: Use fast storage (NVMe SSD)
- Network Tuning: Optimize for distributed deployments
- CPU Usage: Profile and optimize CPU-intensive operations
- Garbage Collection: Tune GC settings for your runtime
- Concurrency: Optimize concurrent operation limits
Monitoring Setup
- Metrics Collection: Implement comprehensive metrics
- Alerting: Set up alerts for performance degradation
- Logging: Configure appropriate log levels
- Profiling: Enable profiling for performance analysis
- Dashboards: Create monitoring dashboards
- Benchmarking: Establish performance baselines
Troubleshooting Performance Issues
Common Performance Problems
Slow Queries
// Identify slow queries
const slowQueries = await memory.getStatistics().slowQueries;
slowQueries.forEach(query => {
console.log(`Slow query: ${query.sql}`);
console.log(`Duration: ${query.duration}ms`);
console.log(`Rows examined: ${query.rowsExamined}`);
});
// Optimize with indexes
await memory.addIndex('category_namespace', ['category', 'namespace']);
High Memory Usage
// Monitor memory usage
const memoryUsage = process.memoryUsage();
console.log(`Heap used: ${(memoryUsage.heapUsed / 1024 / 1024).toFixed(2)} MB`);
console.log(`Heap total: ${(memoryUsage.heapTotal / 1024 / 1024).toFixed(2)} MB`);
// Reduce cache size if needed
await memory.updateConfig({
cache: {
maxSize: 256 * 1024 * 1024 // Reduce to 256MB
}
});
Low Cache Hit Rate
// Analyze cache performance
const cacheStats = await memory.getCacheStatistics();
if (cacheStats.hitRate < 0.8) {
console.log('Cache hit rate is low, consider:');
console.log('- Increasing cache size');
console.log('- Adjusting cache strategy');
console.log('- Implementing cache warming');
}
High Lock Contention
// Monitor lock wait times
const lockStats = await memory.getLockStatistics();
if (lockStats.averageWaitTime > 10) {
console.log('High lock contention detected');
console.log('Consider increasing connection pool size');
}