Topic 10 of 12

Optimization and Performance

The techniques that come up most in practice to make a system fast: caching, asynchronous processing, concurrency, efficient SQL and CDNs.

What to study

  • Cache-Aside Pattern
  • Asynchronous jobs
  • Concurrency and parallelism
  • SQL optimization and performanceN+1 problem · Indexes
  • CDN

Visual examples

No cache vs. Cache-Aside

GET /api/v1/products/best-sellers

No cache

Clients
×1000 req
API
query
Database

Every request hits the database — the same heavy query runs thousands of times.

Cache-Aside

Clients
×1000 req
API
1. get
Redis
hit ✓
API
miss
2. query
Database
3. set
Redis

The API checks the cache first. Only on a miss does it query the database and write the result to the cache.

Synchronous vs. asynchronous processing

Without asynchronous processing

Client
POST
API
email + PDF + ...
~5 s
Response

The client waits for everything to finish — sending email, generating a PDF, calling external services — before getting a response.

With asynchronous processing

Client
POST
API
~50 ms
202 Accepted
API
publishes
Queue
RabbitMQ
consumes
Worker

The API just publishes a message to the queue and responds right away. Workers handle the heavy lifting in the background.

The N+1 problem

One query to fetch the list and then one extra query for each item. With 500 users, that's 501 trips to the database.

❌ N+1 — one query per user

import sqlite3

conn = sqlite3.connect('example.db')
cursor = conn.cursor()

cursor.execute("SELECT id, name FROM users")
users = cursor.fetchall()

for user_id, name in users:
    cursor.execute(
        "SELECT title FROM articles WHERE user_id = ?",
        (user_id,),
    )
    articles = cursor.fetchall()
    # 1 + N queries...

✅ A single query with a JOIN

cursor.execute("""
    SELECT u.id, u.name, a.title
    FROM users u
    LEFT JOIN articles a ON a.user_id = u.id
""")
rows = cursor.fetchall()

# SQL run by the N+1 code:
# SELECT id, name, email FROM users;
# SELECT title FROM articles WHERE user_id = 1;
# SELECT title FROM articles WHERE user_id = 2;
# ...
# SELECT title FROM articles WHERE user_id = 500;
Cache-aside flow: the application reads from the cache; on a miss, it queries the database and updates the cache
Cache-aside: the application checks the cache first and only goes to the database on a miss. Source: EnjoyAlgorithms.

Articles7

Videos1