Overview
Memos is designed for efficiency, but production deployments can benefit from tuning based on workload characteristics. This guide covers database optimization, caching strategies, and infrastructure recommendations.Performance Architecture
Built-in Caching
Memos implements in-memory caching for frequently accessed data:Cache Configuration
Cached Resources
| Resource | Cache Key | TTL | Purpose |
|---|---|---|---|
| Instance Settings | setting_key | 10 min | Global config (logo, branding) |
| Users | user_id | 10 min | Authentication lookups |
| User Settings | user_id-setting_key | 10 min | User preferences |
Cache Invalidation
Caches are automatically invalidated on:- Update operations (UpsertInstanceSetting, UpdateUser, etc.)
- TTL expiration (10 minutes)
- Manual eviction (on delete)
Monitoring Cache Performance
Future enhancement: Add cache hit/miss metricsDatabase Optimization
SQLite Tuning
SQLite is Memos’ default database and performs well for small-to-medium deployments.Default Configuration
foreign_keys(0): Disabled for flexibilitybusy_timeout(10000): Wait up to 10s for locks (prevents “database is locked” errors)journal_mode(WAL): Write-Ahead Logging (better concurrency)mmap_size(0): Disable memory mapping (prevents OOM on some systems)
Performance Tuning
For higher write loads, consider:- Concurrent reads: Multiple readers don’t block
- Better write performance: Sequential writes to WAL file
- Crash safety: Atomic commits
SQLite Limitations
| Metric | Recommendation |
|---|---|
| Max DB Size | 281 TB (theoretical), 100GB (practical) |
| Concurrent Writers | 1 (serialized by WAL) |
| Concurrent Readers | Unlimited |
| Ideal Workload | Read-heavy, single-server |
- > 100GB database size
- High concurrent writes (multiple Memos instances)
- Need for replication/clustering
MySQL Tuning
Connection Settings
my.cnf Configuration
Indexes
Memos creates indexes automatically via migrations. Verify with:memo.creator_id- Fast lookups by usermemo.created_ts- Chronological sortingmemo.uid- Unique memo identifiermemo_relation.memo_id- Relation queries
PostgreSQL Tuning
Connection Settings
postgresql.conf Configuration
Vacuum and Analyze
Connection Pooling
Use PgBouncer for connection pooling:Query Optimization
Pagination Best Practices
Memos usesLIMIT/OFFSET for pagination:
Filtering Performance
Memos supports advanced filters:- Use
ExcludeContent: truewhen content not needed (reduces payload size) - Limit
VisibilityListto only necessary values - Add indexes on frequently filtered columns
Frontend Performance
React Query Optimization
- Increase
staleTimefor static data (reduce API calls) - Decrease
staleTimefor real-time data - Set
refetchOnWindowFocus: falsefor low-priority data
Code Splitting
Memos uses manual chunks for large dependencies:Lazy Loading
Load heavy components on demand:Infrastructure Optimization
Reverse Proxy Caching
Nginx Caching
Static Asset Caching
CDN Integration
Offload static assets to CDN: Cloudflare:- Add domain to Cloudflare
- Enable caching:
- Cache Level: Standard
- Browser Cache TTL: 4 hours
- Page Rules:
*memos.example.com/assets/*→ Cache Level: Cache Everything, Edge TTL: 1 month
Load Balancing
For high availability, run multiple Memos instances:Monitoring and Profiling
Application Metrics
Future enhancement: Expose Prometheus metricsDatabase Monitoring
SQLite
MySQL
PostgreSQL
System Monitoring
Resource Recommendations
Small Deployment (< 10 users)
- CPU: 1 core
- RAM: 512MB
- Storage: 10GB SSD
- Database: SQLite
- Example: Personal VPS, Raspberry Pi
Medium Deployment (10-100 users)
- CPU: 2 cores
- RAM: 2GB
- Storage: 50GB SSD
- Database: SQLite or MySQL
- Example: Small team, DigitalOcean Droplet
Large Deployment (100-1000 users)
- CPU: 4-8 cores
- RAM: 8-16GB
- Storage: 200GB SSD
- Database: MySQL or PostgreSQL (dedicated server)
- Load Balancer: 2+ Memos instances
- Example: Enterprise, AWS EC2
Container Resource Limits
Performance Checklist
- Enable WAL mode for SQLite (enabled by default)
- Configure database cache size (SQLite: cache_size, MySQL: innodb_buffer_pool_size, PostgreSQL: shared_buffers)
- Add indexes on frequently queried columns
- Use reverse proxy caching (nginx/Caddy)
- Enable compression (gzip/brotli)
- Offload static assets to CDN
- Implement connection pooling (PostgreSQL: PgBouncer)
- Monitor slow queries (database logs)
- Regular VACUUM/ANALYZE (PostgreSQL)
- Use pagination for large result sets
- Optimize React Query staleTime
- Enable lazy loading for heavy components
- Set appropriate cache TTLs
- Monitor resource usage (CPU, RAM, disk I/O)
- Implement health checks
Next Steps
Architecture
Understand Memos system architecture
Backup & Restore
Backup strategies for disaster recovery
Security
Security best practices and hardening
Monitoring
Set up monitoring and alerting