Intelligent Caching System
Lokus v1.3.4 introduced a sophisticated intelligent caching system that dramatically improves performance by eliminating redundant file system operations.
The Intelligent Caching System was introduced in v1.3.4 (PR #242) and provides 85-90% reduction in file system calls.
Overview
The caching system implements a 5-minute Time-To-Live (TTL) cache that stores workspace file listings in memory, eliminating the need for repeated file system scans during normal operation.
Performance Impact
Real-world performance improvements in v1.3.4:
| Operation | Before (v1.3.3) | After (v1.3.4) | Improvement |
|---|---|---|---|
| Command Palette (first open) | ~200-400ms | ~200-400ms | Baseline |
| Command Palette (subsequent) | ~200-400ms | Instant | ~95% faster |
| Split View (same file) | ~400ms | ~200ms | 50% faster |
| Split View (different file) | ~400ms | ~200ms | 50% faster |
| Bases View (reopen) | Full scan | Cached | 90% faster |
| Tab Switching | Reloads | Cached | Instant |
Overall Result: Most file operations become instant after initial load, dramatically improving the user experience during normal workflows.
How It Works
Cache Architecture
The caching system operates at multiple levels:
1. BasesDataManager Cache
Location: src/bases/data/index.js
class BasesDataManager {
constructor(options = {}) {
this.fileListCache = null; // Cache storage
this.fileListCacheTime = 0; // Timestamp of cache
this.options = {
cacheTimeout: 5 * 60 * 1000, // 5 minutes in milliseconds
...options
};
}
async getAllFiles() {
// Check cache first (5 minute TTL)
const now = Date.now();
const cacheAge = now - this.fileListCacheTime;
if (this.fileListCache && cacheAge < this.options.cacheTimeout) {
console.log('📋 Cache hit! Using cached file list');
return this.fileListCache;
}
console.log('🔄 Cache miss or expired, loading from backend...');
// Fetch from backend
const files = await invoke('read_workspace_files', {
workspacePath: this.workspacePath
});
// Cache the results
this.fileListCache = processedFiles;
this.fileListCacheTime = now;
return processedFiles;
}
}2. Command Palette Optimization
Location: src/components/CommandPalette.jsx
Before (v1.3.3): Loaded files on every open and fileTree change
After (v1.3.4): Only loads if cache is empty
// Load files only if not already cached
useEffect(() => {
if (basesFiles.length === 0) {
// Cache miss - load from backend
loadFiles();
} else {
console.log('📋 Using cached basesFiles for command palette');
}
}, []); // Removed fileTree from dependencies3. Split View Optimization
Result: Reuses cached data when opening split views, eliminating duplicate file system calls.
Cache Lifecycle
- Initial Load: First file operation triggers backend scan and caches results
- Cache Hit: Subsequent operations use cached data (instant response)
- TTL Expiration: After 5 minutes, cache expires
- Refresh: Next operation triggers fresh backend scan and updates cache
- Repeat: Cycle continues for optimal balance of freshness and performance
Benefits
1. Reduced File System I/O
- 70-80% reduction in
read_workspace_filesbackend calls - 90% reduction in duplicate file system operations
- Lower disk I/O improves battery life on laptops
- Reduced wear on SSDs
2. Instant Response Times
After initial load, operations become effectively instant:
- Command Palette: Opens immediately (no delay)
- File Browser: Instant file list population
- Bases View: Immediate display of data
- Tab Operations: No reload delays
3. Better User Experience
- Snappy Interface: Operations feel instantaneous
- Smooth Workflow: No interruptions from loading delays
- Predictable Performance: Consistent speed after warm-up
- Reduced Frustration: No more waiting for repetitive operations
4. Resource Efficiency
- Lower CPU Usage: Fewer file system operations
- Reduced Memory Allocations: Reuse existing data structures
- Better Battery Life: Less disk I/O on laptops
- Cooler Operation: Reduced CPU usage means less heat
Cache Strategies
Time-To-Live (TTL) Cache
What It Is: Data is cached for a fixed duration (5 minutes), then expires.
Why 5 Minutes:
- Balance: Fresh enough for most workflows, long enough for significant benefit
- File Changes: Most users don’t add/remove files every few minutes
- Memory: Reasonable memory footprint for typical workspaces
- Predictable: Consistent behavior across sessions
Trade-offs:
- Stale Data: New files added externally won’t appear for up to 5 minutes
- Memory Usage: Cache occupies memory (negligible for most workspaces)
- Complexity: Additional cache management logic
Cache Invalidation
The cache automatically invalidates (clears) in these scenarios:
- TTL Expiration: After 5 minutes, cache is considered stale
- Explicit Reload: User-triggered workspace refresh
- Workspace Change: Switching to different workspace
- App Restart: Cache doesn’t persist across sessions (by design)
Note: File changes made within Lokus automatically update the cache, so you’ll always see your own changes immediately.
What’s Cached
Cached Data:
- File paths and names
- File metadata (size, dates, extensions)
- Directory structure
- Basic file properties
Not Cached:
- File contents (loaded on-demand)
- Frontmatter (parsed when needed)
- Full property indexes (computed separately)
Performance Monitoring
Console Logging
Cache operations are logged to the console for debugging:
// Cache hit
📋 Cache hit! Using cached file list
// Cache miss
🔄 Cache miss or expired, loading from backend...
// Command palette cache
📋 Using cached basesFiles for command palette
// Bases cache status
📋 Cache hits in BasesDataManagerOpen Developer Console (⌘+Shift+I on macOS, F12 on Windows/Linux) to monitor cache behavior.
Performance Testing
To verify cache improvements:
- First Open: Open Command Palette (⌘+K) - note delay
- Second Open: Open again immediately - should be instant
- Bases View: Open Bases, close, reopen - second time is instant
- Split View: Open split view multiple times - faster each time
- Check Console: Look for cache hit messages
Measuring Performance
// Measure command palette open time
const start = performance.now();
// Open command palette
const end = performance.now();
console.log(`Command palette opened in ${end - start}ms`);
// First time: ~200-400ms
// Second time: <10ms (instant)Optimization Tips
Maximize Cache Benefits
- Keep Workspace Open: Don’t restart Lokus unnecessarily
- Work Continuously: Cache remains hot during active use
- Batch File Operations: Add multiple files at once to minimize reloads
- Use Internal Operations: File operations in Lokus update cache immediately
Large Workspaces
For workspaces with 1,000+ files:
- Initial cache load may take longer (one-time cost)
- Cache provides even greater benefits (more files = more savings)
- Consider using Bases source folders to limit scope
- Add exclude patterns for node_modules, .git, etc.
Memory Considerations
Cache memory usage is minimal:
- Small Workspace (100 files): ~10KB
- Medium Workspace (1,000 files): ~100KB
- Large Workspace (10,000 files): ~1MB
- Expiration: Cache clears after 5 minutes of inactivity
Even for very large workspaces, cache memory overhead is negligible compared to the performance benefits.
Advanced Configuration
Adjusting Cache Timeout
For advanced users, cache timeout can be configured:
// In BasesDataManager initialization
const manager = new BasesDataManager({
cacheTimeout: 10 * 60 * 1000 // 10 minutes
});
// Shorter for rapidly changing workspaces
const manager = new BasesDataManager({
cacheTimeout: 2 * 60 * 1000 // 2 minutes
});Disabling Cache
For testing or troubleshooting:
// Set timeout to 0 to effectively disable caching
const manager = new BasesDataManager({
cacheTimeout: 0 // No caching, always fresh
});Manual Cache Control
Programmatic cache management:
// Clear cache manually
basesDataManager.fileListCache = null;
basesDataManager.fileListCacheTime = 0;
// Force refresh
await basesDataManager.getAllFiles(); // Bypasses cache
// Check cache age
const age = Date.now() - basesDataManager.fileListCacheTime;
console.log(`Cache age: ${age}ms`);Troubleshooting
Cache Not Working
Symptoms: Operations still slow after first use
Solutions:
- Check Console: Look for cache hit messages
- Verify Version: Ensure you’re on v1.3.4 or later
- Check Configuration: Verify cacheTimeout is set
- Restart App: Clear any state issues
- Check Workspace: Ensure workspace is properly initialized
Stale Data
Symptoms: New external files don’t appear
Reasons:
- Files added outside Lokus (other apps, terminal)
- Cache hasn’t expired yet (< 5 minutes)
Solutions:
- Wait 5 Minutes: Cache will auto-refresh
- Reload Workspace: Use workspace reload command
- Restart Lokus: Clears cache immediately
- Use Lokus: Create files in Lokus to auto-update cache
Excessive Memory Usage
Symptoms: Lokus using too much memory
Unlikely Cause: Cache is minimal (< 1MB even for large workspaces)
Real Causes:
- Many open tabs (each loads full content)
- Large images in notes
- Graph view with thousands of nodes
- Memory leak (unrelated to cache)
Solutions:
- Close unused tabs
- Optimize image sizes
- Limit graph view scope
- Restart Lokus periodically
Best Practices
For Users
- Let It Cache: Give operations a moment to complete first time
- Reuse Operations: Benefit from cache by repeating operations
- Don’t Restart Unnecessarily: Cache is lost on restart
- Monitor Performance: Check console to verify cache hits
For Developers
- Respect Cache: Don’t bypass cache unless necessary
- Update Cache: When modifying files, update cache
- Document Changes: Note cache-affecting code changes
- Test Both Paths: Test cache hits and misses
- Profile Performance: Measure improvements quantitatively
For Plugin Developers
If you’re developing plugins:
// Access cache through BasesDataManager
const manager = basesDataManager;
const files = await manager.getAllFiles(); // Uses cache
// Force refresh if needed
manager.fileListCache = null;
const freshFiles = await manager.getAllFiles();
// Check if cache is valid
const isCacheValid = manager.fileListCache &&
(Date.now() - manager.fileListCacheTime) < manager.options.cacheTimeout;Backward Compatibility
The caching system is fully backward compatible:
- No API Changes: Existing code continues to work
- Progressive Enhancement: Automatically faster without code changes
- Graceful Degradation: Falls back to direct load if cache unavailable
- Configuration Optional: Works with default settings
Future Enhancements
Planned improvements for the caching system:
- Smart Invalidation: Detect file system changes and invalidate automatically
- Persistent Cache: Cache survives app restarts (with validation)
- Tiered Caching: Multiple cache layers for different data types
- Cache Preloading: Predictively load likely-needed data
- Compression: Compress cached data for larger workspaces
- Statistics: Cache hit rate and performance metrics dashboard
Related Features
The caching system complements other performance features:
- Quantum Search - Fast full-text search
- Optimization Techniques - General performance tuning
- Large Workspaces - Managing thousands of files
- Bases System - Database-like queries benefit from caching
Impact Summary: The intelligent caching system represents one of the most significant performance improvements in Lokus history, making the app feel dramatically faster during everyday use without any user configuration required.