← Back to Index

8. Performance

Caching

Caching stores frequently accessed data in a fast, temporary storage layer to reduce latency and offload backend systems.

Cache Strategies

StrategyHow It WorksWhen to Use
Cache AsideApplication checks cache first; on miss, reads DB and updates cacheSimplest, most common; good for general-purpose
Read ThroughCache automatically loads from DB on missConsistent caching behavior
Write ThroughWrite to cache and DB simultaneouslyStrong consistency between cache and DB
Write BehindWrite to cache, asynchronously write to DBHigh write throughput, eventual consistency OK
Cache InvalidationEvict or update cache when data changesStale data tolerance varies
# Cache Aside (Pseudocode)
function getUser(userId):
    user = cache.get("user:" + userId)
    if user is None:
        user = db.query("SELECT * FROM users WHERE id = ?", userId)
        cache.set("user:" + userId, user, ttl=3600)
    return user

Cache Eviction Policies

Caching Tiers

Message Queues

Queues decouple producers and consumers, allowing asynchronous processing and buffering during traffic spikes.

# Producer
queue.send("order.created", {"order_id": 42, "user_id": 7})

# Consumer (scale horizontally)
def handle(message):
    if message.type == "order.created":
        process_payment(message.data)
        send_confirmation(message.data)

Popular queue systems: RabbitMQ, Amazon SQS, Google Pub/Sub, Apache Kafka (for high-throughput event streaming).

Concurrency & Parallelism

Database Optimization

Exercise: Your e-commerce site's product page loads in 4 seconds. The bottleneck is a complex SQL query joining 7 tables for each product. Propose three optimization strategies (one cache-based, one DB-index-based, one architectural) and estimate the improvement for each.