Performance Optimization
Optimize Borg UI for large repositories, fast archive browsing, and efficient backups.Redis Cache Configuration
Redis caching provides 600x faster archive browsing for large repositories (60-90 seconds → 100ms).Quick Performance Comparison
| Archive Size | Files | Without Cache | With Redis Cache |
|---|---|---|---|
| Small | 1,000 | ~1 second | 100ms |
| Medium | 100,000 | ~10 seconds | 100ms |
| Large | 1,000,000 | 60-90 seconds | 100ms |
| Very Large | 10,000,000 | 10-15 minutes | 1 second |
How Caching Works
Architecture (fromapp/services/cache_service.py):
- Primary backend: Redis (persistent, distributed)
- Fallback backend: In-memory LRU cache (automatic if Redis unavailable)
- Compression: Automatic for archives 100KB (70-80% size reduction)
- Cache key format:
archive:{repo_id}:{archive_name}
- First browse: Run
borg list, serialize JSON, compress if 100KB, store in Redis - Subsequent browses: Retrieve from Redis, decompress, deserialize → instant results
- Expiration: Entries auto-expire after TTL (default: 2 hours)
- Eviction: LRU eviction when cache size limit reached
Local Redis Setup (Included)
The recommended installation includes Redis with no configuration needed. docker-compose.yml (already configured):maxmemory 2gb: Limit Redis memory usageallkeys-lru: Evict least-recently-used keys when memory fullsave "": Disable RDB snapshots (cache-only, not persistent)appendonly no: Disable AOF (faster, cache can be rebuilt)
Redis is already configured in the recommended installation. No setup needed unless you need more than 2GB cache.
External Redis for Large Repositories
Use cases:- Repositories with 1M+ files
- Multiple large archives
- Need more than 2GB cache
- Shared cache across multiple Borg UI instances
- Go to Settings → Cache
- Enter Redis URL:
redis://192.168.1.100:6379/0 - Increase Max Cache Size to 20480 MB
- Click Save Settings
Cache Statistics
View in UI:- Go to Settings → Cache
- Shows: backend type, hit rate, memory usage, entry count, connection info
app/services/cache_service.py:270-310):
Operation Timeouts
Configure timeouts for Borg operations to handle large repositories and slow networks.Default Timeouts
Fromapp/config.py:90-98 and migration 053_add_operation_timeouts.py:
| Operation | Default | Use Case |
|---|---|---|
mount_timeout | 120s (2 min) | Archive browsing via FUSE mount |
info_timeout | 600s (10 min) | Repository info, cache building |
list_timeout | 600s (10 min) | Listing archives, archive contents |
init_timeout | 300s (5 min) | Creating new repositories |
backup_timeout | 3600s (1 hour) | Backup operations |
source_size_timeout | 3600s (1 hour) | Calculating source size with du |
When to Increase Timeouts
Large repositories (100,000 files):info_timeout: Increase to 1800s (30 min) for repositories with very large cachelist_timeout: Increase to 1800s if listing archives takes 10 minutes
mount_timeout: Increase to 300s (5 min)info_timeout: Increase to 1800s (30 min)list_timeout: Increase to 1800s (30 min)
source_size_timeout: Increase to 7200s (2 hours) for 100TB+ sources
Configure Timeouts
Via Web Interface (Recommended):- Go to Settings → System
- Expand Operation Timeouts section
- Adjust timeout values
- Click Save Settings
UI settings in database take precedence over environment variables (from
app/services/backup_service.py:32-72).- Database settings (set via UI)
- Environment variables
- Config defaults
Memory Optimization
Redis Memory Management
LRU Eviction Policy: Redis usesallkeys-lru to automatically evict least-recently-used entries when maxmemory limit is reached.
Memory calculation:
In-Memory Cache Fallback
Configuration (app/services/cache_service.py:340-477):
- Default size: 2GB (configurable via
CACHE_MAX_SIZE_MB) - Automatic eviction: LRU (oldest entries removed when full)
- No persistence: Lost on restart
- Redis unavailable (connection refused, timeout)
- Redis health check fails 3+ times consecutively
- Redis URL set to
disabled
Browse Memory Limits
For very large archives (10M+ files): Browsing archives with millions of files can consume significant memory during JSON parsing. Monitor memory usage:- Use Redis cache (parses once, serves from cache)
- Increase container memory limit
- Browse subdirectories instead of root
- Use Borg CLI for very large listings
Backup Performance
Parallel Backups
Maximum concurrent backups:Source Size Calculation
Purpose: Calculate total source size before backup for accurate progress percentage and ETA. Implementation (app/services/backup_service.py:433-567):
- Local directories: Fast (1 second for small, ~10 seconds for 1TB)
- Remote SSH: Depends on network latency and remote disk speed
- Very large sources (100TB+): Can take 30+ minutes
- Runs in background (doesn’t block backup start)
- Uses configurable timeout (
source_size_timeout) - Skips if timeout exceeded (backup continues without ETA)
Compression and Deduplication
Borg compression algorithms (set during repository creation):| Algorithm | Speed | Ratio | Use Case |
|---|---|---|---|
none | Fastest | 1:1 | Pre-compressed data (videos, images) |
lz4 | Very fast | ~2:1 | General purpose, minimal CPU |
zstd,3 | Fast | ~3:1 | Recommended default |
zstd,10 | Moderate | ~4:1 | More compression, more CPU |
zlib,6 | Slower | ~3.5:1 | Legacy compatibility |
lzma,6 | Slowest | ~5:1 | Maximum compression |
Network Performance
SSH Multiplexing
Enable SSH connection sharing to speed up remote operations:- Reuses SSH connections (no re-authentication overhead)
- Faster for repositories with many small operations
- Reduces network latency
Bandwidth Limiting
Limit backup bandwidth for slow or metered connections:Database Performance
SQLite Optimization
Borg UI uses SQLite for metadata storage. Current settings:- WAL mode: Enabled (concurrent reads during writes)
- Journal mode: WAL (Write-Ahead Logging)
- Synchronous: NORMAL (good balance of safety and speed)
Migration Performance
Database migrations run on startup (fromapp/database/migrations/__init__.py:12-55):
- 72 migrations execute sequentially
- Each migration checks for existing columns (idempotent)
- First startup: 5-10 seconds
- Subsequent startups: 1 second (migrations already applied)
Monitoring and Profiling
Performance Metrics
Cache hit rate:Log Analysis
Find slow operations:Performance Tuning Checklist
Large Repository Optimization (1M+ files)
Large Repository Optimization (1M+ files)
Cache:
- External Redis with 8-20GB memory
- Cache size: 8192-20480 MB
- Cache TTL: 1440 minutes (24 hours)
- Monitor hit rate 80%
-
info_timeout: 1800s (30 min) -
list_timeout: 1800s (30 min) -
mount_timeout: 300s (5 min) -
source_size_timeout: 7200s (2 hours)
- Compression:
zstd,3orlz4 - Encryption:
repokey-blake2(faster than SHA256) - Regular
borg compactto reclaim space
Remote Repository Optimization (SSH)
Remote Repository Optimization (SSH)
SSH:
- SSH multiplexing enabled (
ControlMaster auto) - Compression enabled in SSH config
- SSH key authentication (no password delays)
- Dedicated backup user (no shell overhead)
- Bandwidth limiting if needed (
--remote-ratelimit) - Consider using local mount for very large datasets
- Increase all timeouts by 2-3x for remote operations
- Monitor for timeout errors in logs
Container Resource Limits
Container Resource Limits
Memory:
- Borg UI: 2-4GB for large archive browsing
- Redis: Match cache size + 500MB overhead
- No limit for backup operations (compression benefits from all cores)
- Consider limiting for background jobs only
Related Documentation
Cache Configuration
Detailed Redis setup and troubleshooting
Troubleshooting
Performance issues and solutions
Maintenance
Database optimization and cleanup
Configuration
Environment variables and system settings