Skip to main content

Redis Caching Configuration

Borg UI includes an intelligent caching system that can provide 600x faster archive browsing using Redis. The cache system automatically compresses large archives and gracefully falls back to in-memory caching when Redis is unavailable.

Overview

Performance Impact

Redis caching transforms the browsing experience:Without cache: 5-10 seconds per archive (depending on size)With cache: ~10ms per archive (after first load)Speedup: Up to 600x faster for large archives

How It Works

  1. First Browse: Archive contents loaded via borg list (slow)
  2. Cached: Results compressed and stored in Redis with TTL
  3. Subsequent Browses: Served instantly from cache (fast)
  4. Automatic Refresh: Cache expires after TTL, rebuilds on next access

Cache Architecture

┌─────────────────┐
│   Borg UI App   │
└────────┬────────┘

         ├─────────────┐
         │             │
    ┌────▼───┐    ┌────▼─────┐
    │ Redis  │    │ In-Memory│
    │ Cache  │    │ Fallback │
    └────────┘    └──────────┘
    (Primary)      (Backup)
Dual Backend System:
  • Redis: Primary cache (persistent, shared across restarts)
  • In-Memory: Automatic fallback (when Redis unavailable)

Quick Setup

The default Docker Compose configuration includes Redis:
docker-compose.yml
services:
  app:
    environment:
      - REDIS_HOST=redis
      - REDIS_PORT=6379
      - CACHE_TTL_SECONDS=7200  # 2 hours
      - CACHE_MAX_SIZE_MB=2048  # 2GB
    depends_on:
      redis:
        condition: service_healthy

  redis:
    image: redis:7-alpine
    command: >
      redis-server
      --maxmemory 2gb
      --maxmemory-policy allkeys-lru
      --save ""
      --appendonly no
Redis starts automatically with Borg UI. No additional configuration needed for local setup.

Configuration Options

Environment Variables

REDIS_URL
string
default:"none"
External Redis connection URL. Takes precedence over REDIS_HOST/REDIS_PORT.Formats:
  • TCP: redis://hostname:port/db
  • TCP with password: redis://:password@hostname:port/db
  • TLS: rediss://hostname:port/db
  • Unix socket: unix:///run/redis.sock?db=0
Examples:
# Remote Redis
REDIS_URL=redis://192.168.1.100:6379/0

# With password
REDIS_URL=redis://:[email protected]:6379/0

# TLS connection
REDIS_URL=rediss://secure-redis.example.com:6380/0

# Unix socket
REDIS_URL=unix:///var/run/redis/redis.sock?db=0
REDIS_HOST
string
default:"redis"
Redis server hostname. Used if REDIS_URL is not set.Set to "disabled" to disable Redis and use only in-memory cache.
REDIS_HOST=redis
REDIS_PORT
integer
default:"6379"
Redis server port.
REDIS_PORT=6379
REDIS_DB
integer
default:"0"
Redis database number (0-15).
REDIS_DB=0
REDIS_PASSWORD
string
default:"none"
Redis server password (if authentication enabled).
REDIS_PASSWORD=your-redis-password
CACHE_TTL_SECONDS
integer
default:"7200"
Cache time-to-live in seconds. Archive data cached for this duration.Default: 2 hours (7200 seconds)Recommendations:
  • Static archives: 14400 (4 hours) or higher
  • Active backups: 3600 (1 hour) or lower
  • Development: 300 (5 minutes)
CACHE_TTL_SECONDS=7200
CACHE_MAX_SIZE_MB
integer
default:"2048"
Maximum in-memory cache size in megabytes (fallback backend only).Default: 2GB (2048 MB)
CACHE_MAX_SIZE_MB=2048

UI Configuration

Cache settings can also be configured via Settings → Cache in the web UI.UI settings override environment variables and persist to the database.
Configurable via UI:
  • Redis URL (external Redis)
  • Cache TTL
  • Cache size limit
  • Enable/disable caching

Redis Memory Configuration

Default Configuration

docker-compose.yml
redis:
  command: >
    redis-server
    --maxmemory 2gb
    --maxmemory-policy allkeys-lru
    --save ""
    --appendonly no
Flags explained:
FlagPurposeDefault
--maxmemoryMaximum memory limit2GB
--maxmemory-policyEviction policy when fullallkeys-lru
--save ""Disable RDB snapshotsDisabled
--appendonlyDisable AOF persistenceDisabled
Persistence is disabled because Redis is used purely as a cache. Data loss on restart is acceptable since the cache rebuilds automatically.

Eviction Policies

allkeys-lru (Recommended):
  • Evicts least recently used keys from all keys
  • Best for pure cache use case
  • Automatically removes old archives to make room
Alternatives:
  • allkeys-lfu: Evict least frequently used (better for hot data)
  • volatile-lru: Only evict keys with TTL set
  • volatile-ttl: Evict keys with shortest TTL first

Memory Sizing

Estimation formula:
Cache Size ≈ (Avg Archive Size × Number of Archives × Compression Ratio)
Compression:
  • Archives 100KB: Automatically compressed (zlib level 6)
  • Typical compression: 30-50% of original size
  • Archives 100KB: Stored uncompressed
Examples:
ArchivesAvg SizeCompressedRecommended Redis
1001MB~40MB512MB
5005MB~1GB2GB
100010MB~3GB4GB
50002MB~3GB4GB
Set maxmemory slightly higher than estimated to prevent constant evictions.

Adjusting Memory Limits

docker-compose.yml
redis:
  command: >
    redis-server
    --maxmemory 4gb
    --maxmemory-policy allkeys-lru
.env
CACHE_MAX_SIZE_MB=4096

External Redis Setup

Shared Redis Instance

docker-compose.yml
services:
  app:
    environment:
      - REDIS_URL=redis://shared-redis.internal.lan:6379/0
    # Remove local redis service

Redis with Authentication

.env
REDIS_URL=redis://:[email protected]:6379/0

TLS/SSL Connection

.env
REDIS_URL=rediss://secure-redis.example.com:6380/0

Multiple Borg UI Instances

Share one Redis instance across multiple Borg UI deployments:
docker-compose.yml
services:
  app1:
    environment:
      - REDIS_URL=redis://shared-redis:6379/0
  
  app2:
    environment:
      - REDIS_URL=redis://shared-redis:6379/1  # Different DB
  
  shared-redis:
    image: redis:7-alpine
    command: redis-server --maxmemory 8gb
Use different Redis databases (0-15) to isolate cache data between instances.

Cache Management

View Cache Statistics

UI: Settings → Cache → Statistics API:
GET /api/cache/stats
Response
{
  "backend": "redis",
  "available": true,
  "connection_type": "local",
  "connection_info": "redis:6379/0",
  "hits": 1523,
  "misses": 127,
  "hit_rate": 92.3,
  "size_bytes": 157286400,
  "entry_count": 245,
  "ttl_seconds": 7200,
  "max_size_mb": 2048
}

Clear Cache

POST /api/cache/clear
Use cases:
  • After pruning archives
  • After deleting archives
  • Testing/troubleshooting
  • Repository structure changed

Cache Keys

Format: archive:{repo_id}:{archive_name} Examples:
  • archive:1:backup-2026-02-28T10:00:00
  • archive:5:weekly-2026-W09
  • archive:12:daily-monday

Manual Redis Access

# Connect to Redis container
docker exec -it borg-redis redis-cli

# View all cache keys
KEYS archive:*

# Get cache entry count
DBSIZE

# View memory usage
INFO memory

# Clear entire database
FLUSHDB

# Test connection
PING

In-Memory Fallback

When It Activates

Automatic fallback to in-memory cache when:
  • Redis connection fails
  • Redis not configured (REDIS_HOST=disabled)
  • Redis unavailable during startup
  • Redis fails 3+ consecutive operations

Limitations

FeatureRedisIn-Memory
PersistenceSurvives restartLost on restart
SharedMulti-instanceSingle instance
Size limitSet via maxmemorySet via CACHE_MAX_SIZE_MB
EvictionConfigurableLRU only
PerformanceExcellentGood

Disabling Redis

.env
REDIS_HOST=disabled
docker-compose.yml
services:
  app:
    environment:
      - REDIS_HOST=disabled
      - CACHE_MAX_SIZE_MB=2048
    # Remove depends_on redis

# Remove redis service

Performance Tuning

Large Repositories (>1000 archives)

docker-compose.yml
redis:
  command: >
    redis-server
    --maxmemory 8gb
    --maxmemory-policy allkeys-lru
    --tcp-backlog 511
    --timeout 0
    --tcp-keepalive 300
.env
CACHE_TTL_SECONDS=14400  # 4 hours
CACHE_MAX_SIZE_MB=8192   # 8GB

Very Large Archives (>500MB each)

.env
CACHE_TTL_SECONDS=86400  # 24 hours (if archives rarely change)
redis:
  command: >
    redis-server
    --maxmemory 16gb
    --maxmemory-policy allkeys-lru

High-Traffic Deployments

redis:
  command: >
    redis-server
    --maxmemory 4gb
    --maxmemory-policy allkeys-lfu  # Least frequently used
    --maxclients 10000

Low-Memory Environments

redis:
  command: >
    redis-server
    --maxmemory 512mb
    --maxmemory-policy allkeys-lru
.env
CACHE_TTL_SECONDS=1800   # 30 minutes
CACHE_MAX_SIZE_MB=512

Monitoring

Health Checks

Redis health check:
healthcheck:
  test: ["CMD", "redis-cli", "ping"]
  interval: 10s
  timeout: 3s
  retries: 3
Check status:
docker-compose ps redis

Redis Logs

# View Redis logs
docker-compose logs -f redis

# Check for errors
docker-compose logs redis | grep -i error

Performance Metrics

# Connect to Redis
docker exec -it borg-redis redis-cli

# View info
INFO stats
INFO memory
INFO persistence

# Monitor commands in real-time
MONITOR

# Slow query log
SLOWLOG GET 10

Troubleshooting

Redis Connection Failed

Symptoms:
Redis health check failed: Connection refused
Fallback to in-memory cache
Solutions:
  1. Check Redis is running:
    docker-compose ps redis
    
  2. Check Redis logs:
    docker-compose logs redis
    
  3. Restart Redis:
    docker-compose restart redis
    
  4. Verify network:
    docker exec -it borg-web-ui ping redis
    

Out of Memory

Symptoms:
OOM command not allowed when used memory > 'maxmemory'
Solutions:
  1. Increase Redis memory:
    redis:
      command: redis-server --maxmemory 4gb
    
  2. Lower TTL to expire data faster:
    CACHE_TTL_SECONDS=3600
    
  3. Manually clear cache:
    docker exec -it borg-redis redis-cli FLUSHDB
    

Slow Performance

Symptoms: Cache hit rate 80%, slow archive browsing Solutions:
  1. Check hit rate:
    docker exec -it borg-redis redis-cli INFO stats | grep hit_rate
    
  2. Increase TTL:
    CACHE_TTL_SECONDS=14400  # 4 hours
    
  3. Increase memory:
    redis:
      command: redis-server --maxmemory 4gb
    
  4. Check Redis is actually being used:
    docker exec -it borg-redis redis-cli DBSIZE
    

Cache Not Updating

Symptoms: New archives not showing, stale data displayed Solutions:
  1. Clear repository cache:
    POST /api/cache/clear-repository
    {"repo_id": 1}
    
  2. Check TTL expiration:
    docker exec -it borg-redis redis-cli TTL archive:1:archive-name
    
  3. Verify archive name matches cache key

Best Practices

Always use Redis in production. The in-memory fallback is for emergency/testing only.
Balance freshness vs performance:
  • Static archives: Longer TTL (4-24 hours)
  • Active backups: Shorter TTL (1-2 hours)
  • Development: Very short TTL (5-30 minutes)
Allocate 2-4x the average total archive size (compressed) for optimal hit rates.
Target 90%+ hit rate. If lower, increase memory or TTL.
Redis is a cache - disable RDB/AOF to improve performance and reduce disk I/O.
Manually clear cache after pruning, deleting archives, or restructuring repositories.
Share one Redis instance across multiple Borg UI deployments for better resource utilization.

Next Steps

Environment Variables

Complete cache environment variable reference

Docker Compose

Advanced Docker Compose configurations

Performance Optimization

Advanced performance tuning guide

API Reference

Cache management API documentation

Build docs developers (and LLMs) love