# Redis-Backed Handle Resolver The QuickDID service now supports Redis-backed caching for handle resolution, providing persistent caching with 90-day expiration times. ## Features - **90-Day Cache TTL**: Resolved handles are cached in Redis for 90 days, significantly reducing resolution latency - **Error Caching**: Failed resolutions are also cached (as empty strings) to prevent repeated failed lookups - **Automatic Fallback**: If Redis is unavailable, the service falls back to in-memory caching - **Configurable Key Prefix**: Supports custom Redis key prefixes for multi-tenant deployments ## Configuration Set the `REDIS_URL` environment variable to enable Redis caching: ```bash export REDIS_URL="redis://localhost:6379" # or with authentication export REDIS_URL="redis://username:password@localhost:6379/0" ``` When Redis is configured: - Handle resolutions are cached with 90-day expiration - Cache keys use the format: `handle:{handle_name}` - Failed resolutions are cached as empty strings When Redis is not configured: - Falls back to in-memory caching with 10-minute TTL - Cache is not persisted between service restarts ## Architecture ``` ┌─────────────────┐ │ HTTP Request │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Handle Resolver │ │ Endpoint │ └────────┬────────┘ │ ▼ ┌─────────────────────┐ Cache Miss ┌───────────────────┐ │ RedisHandleResolver │ ─────────────────► │ BaseHandleResolver│ │ │ │ │ │ - Check Redis │ │ - DNS TXT lookup │ │ - 90-day TTL │ ◄───────────────── │ - Well-known │ │ - Cache result │ Resolution │ endpoint │ └─────────┬───────────┘ └───────────────────┘ │ │ Cache Hit ▼ ┌─────────────────┐ │ Redis Cache │ │ │ │ handle:alice -> │ │ did:plc:xyz... │ └─────────────────┘ ``` ## Implementation Details ### RedisHandleResolver The `RedisHandleResolver` struct wraps a base handle resolver and adds Redis caching: ```rust pub struct RedisHandleResolver { inner: Arc, pool: RedisPool, key_prefix: String, } ``` ### Cache Behavior 1. **Cache Hit**: Returns DID immediately from Redis 2. **Cache Miss**: Resolves through inner resolver, caches result 3. **Resolution Error**: Caches empty string to prevent repeated failures 4. **Redis Error**: Falls back to inner resolver without caching ### Key Format Redis keys follow this pattern: - Success: `handle:alice.bsky.social` → `did:plc:xyz123...` - Error: `handle:invalid.handle` → `""` (empty string) ## Testing Tests can be run with a local Redis instance: ```bash # Start Redis locally docker run -d -p 6379:6379 redis:latest # Run tests with Redis export TEST_REDIS_URL="redis://localhost:6379" cargo test # Tests will skip if TEST_REDIS_URL is not set cargo test ``` ## Performance Considerations - **Cache Hits**: Near-instantaneous (<1ms typical) - **Cache Misses**: Same as base resolver (DNS/HTTP lookups) - **Memory Usage**: Minimal, only stores handle → DID mappings - **Network Overhead**: Single Redis round-trip per resolution ## Monitoring The service logs cache operations at various levels: - `DEBUG`: Cache hits/misses - `INFO`: Redis pool creation and resolver selection - `WARN`: Redis connection failures and fallbacks Example logs: ``` INFO Using Redis-backed handle resolver with 90-day cache TTL DEBUG Cache miss for handle alice.bsky.social, resolving... DEBUG Caching successful resolution for handle alice.bsky.social: did:plc:xyz123 DEBUG Cache hit for handle alice.bsky.social: did:plc:xyz123 ``` ## Migration To migrate from in-memory to Redis caching: 1. Deploy Redis instance 2. Set `REDIS_URL` environment variable 3. Restart QuickDID service 4. Service will automatically use Redis for new resolutions No data migration needed - cache will populate on first resolution.