My App
React

Caching Implementation — Redis, Invalidation, Job Queues, and Monitoring

Learn how to implement Redis caching, handle cache invalidation, use background job queues, and monitor performance in real-world web applications.

⚙️ Caching Implementation

Make your app faster and more reliable using Redis, background queues, and smart invalidation.


🧠 What is Caching Implementation?

After learning caching strategies, now we’ll learn how to implement them practically.

Caching implementation means:

  • Adding a caching system like Redis
  • Managing when to update or remove cached data
  • Running background tasks
  • And finally, monitoring performance to ensure everything runs smoothly.

Let’s see each part step-by-step with real-world examples and code.


🔴 1. Redis Integration

Redis is the most popular in-memory database used for caching.
It stores key-value data in memory for super-fast access.


🔸 Install and Connect Redis

Python Installation:

pip install redis

Start Redis Server (Linux/Mac):

redis-server

Connect in Python:

import redis

cache = redis.Redis(host="localhost", port=6379, db=0)
cache.set("welcome", "Hello, Safi!")
print(cache.get("welcome"))

💡 Real-World Example: Websites like YouTube and Instagram store trending video data or user feed data in Redis — so users see results instantly instead of waiting for database queries.


🔹 Use Redis in FastAPI

Example:

from fastapi import FastAPI
import redis

app = FastAPI()
cache = redis.Redis(host="localhost", port=6379, db=0)

@app.get("/user/{user_id}")
def get_user(user_id: int):
    cached_user = cache.get(f"user:{user_id}")
    if cached_user:
        return {"source": "cache", "user": cached_user.decode("utf-8")}
    
    # Simulate fetching from DB
    user = f"User {user_id}"
    cache.set(f"user:{user_id}", user, ex=60)  # expires in 60 seconds
    return {"source": "database", "user": user}

💡 How It Works:

  • First checks Redis for user data.
  • If not found, fetches from DB and stores it in Redis for 60 seconds.
  • Future requests are super fast.

🔁 2. Cache Invalidation Strategies

Caching is great — but what happens when data changes? Old or outdated data must be removed or updated in the cache. This process is called cache invalidation.


🔸 Common Invalidation Strategies

StrategyHow It WorksExample
Time-to-Live (TTL)Cache auto-expires after a set timeUser data expires after 60 seconds
Write-ThroughUpdate cache and DB at the same timeBanking balance updates
Write-Back (Lazy Write)Update cache immediately, DB laterHigh-speed analytics
Manual InvalidationDelete cache when data changesProduct info updated in admin panel

🔹 Example: TTL (Time to Live)

cache.set("user:1", "Safi", ex=120)  # expires after 2 minutes

After 2 minutes, Redis automatically removes the key.

💡 Real-World Example: Netflix caches user preferences and recommendations for a few hours using TTL, so updates don’t need manual clearing.


🔹 Example: Manual Invalidation

def update_user_profile(user_id, new_name):
    db.query(User).filter(User.id == user_id).update({"name": new_name})
    db.commit()
    cache.delete(f"user:{user_id}")  # invalidate cache

💡 Real-World Example: E-commerce sites clear product cache whenever price or stock is updated.


🔹 Example: Write-Through

def update_post(post_id, new_content):
    db.query(Post).filter(Post.id == post_id).update({"content": new_content})
    db.commit()
    cache.set(f"post:{post_id}", new_content)

💡 Real-World Example: Banking systems update both cache and DB together to always show correct balances.


⚙️ 3. Background Job Queues

Some tasks are slow and should run in the background, not while the user waits. This helps keep your app fast and responsive.


🔸 Why Background Jobs?

Because some tasks like:

  • Sending emails
  • Generating reports
  • Updating cache
  • Processing images

…take time but don’t need to block the user.


🔹 Example Using Celery + Redis

Install:

pip install celery redis

Create a Celery App (tasks.py):

from celery import Celery

app = Celery("tasks", broker="redis://localhost:6379/0")

@app.task
def clear_expired_cache():
    print("Clearing expired cache entries...")

Run Worker:

celery -A tasks worker --loglevel=info

Trigger Job:

from tasks import clear_expired_cache
clear_expired_cache.delay()

💡 Real-World Example:

  • Instagram uses background jobs to resize and cache images after upload.
  • E-commerce apps send email receipts using background queues.

📊 4. Performance Monitoring

Even with caching, we must monitor how well it’s performing. If cache hit rate is low, it means data is often missing — and performance can drop.


🔸 Key Metrics to Track

MetricMeaningIdeal Value
Cache Hit Ratio% of requests served from cache> 80%
Cache Miss Ratio% of requests that went to DB< 20%
Memory UsageHow full Redis memory isBelow 70%
LatencyTime to fetch dataAs low as possible

🔹 Example: Monitoring with Redis CLI

redis-cli info stats

Look for these:

keyspace_hits:1500
keyspace_misses:300

To calculate hit rate:

hit_rate = hits / (hits + misses)
= 1500 / (1500 + 300) = 83%

💡 Real-World Example: Netflix and Spotify track cache hit ratios and latency to auto-scale Redis clusters for peak hours.


🧾 Summary

ConceptWhat It DoesReal-World Example
Redis IntegrationAdds fast in-memory cachingInstagram feed data
Cache InvalidationKeeps data freshAmazon product price updates
Background JobsRuns heavy tasks asynchronouslyEmail sending, analytics
Performance MonitoringTracks cache efficiencyNetflix monitors cache hit ratios

💡 Final Thought

Caching isn’t just about speed — it’s about balance. A well-designed caching system saves cost, reduces load, and improves user experience.

Real-world systems like YouTube, Netflix, and Amazon rely heavily on Redis, queues, and monitoring to stay fast for millions of users.