Created
March 14, 2026 15:12
-
-
Save mohashari/bee3005bde7d73e686109a8c04dc8397 to your computer and use it in GitHub Desktop.
Code snippets — Redis Caching Strategies
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func UpdateUser(ctx context.Context, user *User) error { | |
| // 1. Update database | |
| if err := db.UpdateUser(ctx, user); err != nil { | |
| return err | |
| } | |
| // 2. Update cache immediately | |
| cacheKey := fmt.Sprintf("user:%s", user.ID) | |
| data, _ := json.Marshal(user) | |
| redis.Set(ctx, cacheKey, data, 15*time.Minute) | |
| return nil | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Use colon-separated namespaces | |
| user:{id} | |
| user:{id}:posts | |
| product:{id}:variants | |
| session:{token} | |
| # Include version for schema changes | |
| v2:user:{id} | |
| # Include tenant for multi-tenant apps | |
| tenant:{tenant_id}:user:{user_id} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Cache with TTL | |
| redis.Set(ctx, "product:42", data, 5*time.Minute) | |
| // Use longer TTLs for stable data | |
| redis.Set(ctx, "config:features", data, 1*time.Hour) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| cache_hit_rate = hits / (hits + misses) # Target: >90% | |
| cache_memory_usage # Stay under 80% | |
| eviction_rate # High = cache too small |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func OnOrderStatusChanged(orderID string) { | |
| // Invalidate all related caches | |
| pipe := redis.Pipeline() | |
| pipe.Del(ctx, fmt.Sprintf("order:%s", orderID)) | |
| pipe.Del(ctx, fmt.Sprintf("user:orders:%s", order.UserID)) | |
| pipe.Del(ctx, "dashboard:summary") | |
| pipe.Exec(ctx) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Store user's cache keys in a set | |
| func CacheWithTag(ctx context.Context, key string, tag string, data interface{}, ttl time.Duration) { | |
| pipe := redis.Pipeline() | |
| serialized, _ := json.Marshal(data) | |
| pipe.Set(ctx, key, serialized, ttl) | |
| pipe.SAdd(ctx, fmt.Sprintf("tag:%s", tag), key) | |
| pipe.Exec(ctx) | |
| } | |
| // Invalidate all caches for a user | |
| func InvalidateTag(ctx context.Context, tag string) { | |
| tagKey := fmt.Sprintf("tag:%s", tag) | |
| keys, _ := redis.SMembers(ctx, tagKey).Result() | |
| if len(keys) > 0 { | |
| redis.Del(ctx, keys...) | |
| } | |
| redis.Del(ctx, tagKey) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func GetWithStampedeProtection(ctx context.Context, key string) ([]byte, error) { | |
| type cachedValue struct { | |
| Data []byte `json:"data"` | |
| Expiry time.Time `json:"expiry"` | |
| Delta float64 `json:"delta"` | |
| } | |
| raw, err := redis.Get(ctx, key).Bytes() | |
| if err != nil { | |
| return nil, err // Cache miss | |
| } | |
| var cv cachedValue | |
| json.Unmarshal(raw, &cv) | |
| // Probabilistically recompute before expiry | |
| ttl := time.Until(cv.Expiry).Seconds() | |
| if -cv.Delta*math.Log(rand.Float64()) >= ttl { | |
| return nil, nil // Trigger early recomputation | |
| } | |
| return cv.Data, nil | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func GetWithLock(ctx context.Context, key string, fetch func() ([]byte, error)) ([]byte, error) { | |
| // Try cache first | |
| if val, err := redis.Get(ctx, key).Bytes(); err == nil { | |
| return val, nil | |
| } | |
| // Acquire lock | |
| lockKey := key + ":lock" | |
| acquired, _ := redis.SetNX(ctx, lockKey, "1", 10*time.Second).Result() | |
| if !acquired { | |
| // Wait for lock holder to populate cache | |
| time.Sleep(50 * time.Millisecond) | |
| return GetWithLock(ctx, key, fetch) | |
| } | |
| defer redis.Del(ctx, lockKey) | |
| // Double-check after acquiring lock | |
| if val, err := redis.Get(ctx, key).Bytes(); err == nil { | |
| return val, nil | |
| } | |
| // Fetch and cache | |
| val, err := fetch() | |
| if err != nil { | |
| return nil, err | |
| } | |
| redis.Set(ctx, key, val, 5*time.Minute) | |
| return val, nil | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func GetUser(ctx context.Context, userID string) (*User, error) { | |
| // 1. Check cache | |
| cacheKey := fmt.Sprintf("user:%s", userID) | |
| cached, err := redis.Get(ctx, cacheKey).Result() | |
| if err == nil { | |
| var user User | |
| json.Unmarshal([]byte(cached), &user) | |
| return &user, nil | |
| } | |
| // 2. Cache miss — query database | |
| user, err := db.GetUser(ctx, userID) | |
| if err != nil { | |
| return nil, err | |
| } | |
| // 3. Populate cache | |
| data, _ := json.Marshal(user) | |
| redis.Set(ctx, cacheKey, data, 15*time.Minute) | |
| return user, nil | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Client → Redis (immediate) → Queue → Database (async) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment