Companion code for the W33D2 lesson — runnable examples of caching, bottleneck identification, and background tasks, designed to support the teaching block and give fellows patterns they can adapt for their capstone work.
The lesson's central frame: scaling is about not wasting work. Everything in this repo demonstrates one of three moves — cache the result, find the slowest step, or move work off the hot path.
w33d2-demo-repo/
├── README.md
├── requirements.txt
├── Dockerfile
├── docker-compose.yml
├── .dockerignore
├── app.py # Baseline FastAPI app — slow, no patterns applied
├── benchmark.py # Repeated query test tool — same query × 10
├── snippets/ # Standalone code examples for each pattern
│ ├── caching_dict.py
│ ├── caching_lru.py
│ ├── timing_bottleneck.py
│ └── background_tasks.py
└── solutions/ # The same app with each pattern applied
├── app_with_cache.py
├── app_with_timing.py
└── app_with_async.py
Each app variant is a separate profile. Only one runs at a time — they all bind to port 8000, which is the point: spin up one, benchmark it, then swap.
# Terminal 1 — start the baseline
docker compose --profile baseline up
# Terminal 2 — run the benchmark
python benchmark.pyYou should see ten consecutive calls of roughly the same length (~1.9 seconds each). The app repeats expensive work — retrieval, model call, logging — on every request, even when the query is identical. That's the experience the opening activity is designed to surface.
Stop the baseline with Ctrl+C, then run a variant the same way:
docker compose --profile cache up # with caching applied
docker compose --profile timing up # with timing logs
docker compose --profile async up # logging moved off the hot pathThe benchmark always runs against localhost:8000, so the command in Terminal 2 doesn't change.
If you don't have Docker, the same flow works directly:
pip install -r requirements.txt
# Terminal 1 — start the baseline
uvicorn app:app --reload
# Or a variant
uvicorn solutions.app_with_cache:app --reload
# Terminal 2 — run the benchmark
python benchmark.pyEach snippet in snippets/ is a self-contained Python file demonstrating one pattern.
With Docker (no Python required on host):
docker compose run --rm baseline python snippets/caching_dict.py
docker compose run --rm baseline python snippets/caching_lru.py
docker compose run --rm baseline python snippets/timing_bottleneck.py(--profile isn't needed for one-shot run commands.)
Native:
python snippets/caching_dict.py
python snippets/caching_lru.py
python snippets/timing_bottleneck.pysnippets/background_tasks.py is a FastAPI app on its own — run it with uvicorn or add it as another compose profile.
The solutions/ folder shows the same baseline app with each pattern applied. Useful for diff-based teaching:
diff app.py solutions/app_with_cache.py
diff app.py solutions/app_with_timing.py
diff app.py solutions/app_with_async.py- Show baseline.
docker compose --profile baseline up+python benchmark.py. The system repeats work on every call. Expected: ~1.9s per call, no improvement across calls. - Apply caching. Stop baseline, run
docker compose --profile cache up. Re-run the benchmark. Expected: first call ~1.9s, subsequent calls near-instant. - Show the timing log variant.
docker compose --profile timing up. Discuss why instrumenting suspects beats instrumenting everywhere. - Move logging async.
docker compose --profile async up. Note: for the W33D2 capstone deliverable, fellows only need to name an async candidate, not implement one. This profile is illustrative.
Fellows have heterogeneous stacks (Python, JavaScript, varying frameworks). The patterns transfer:
- Caching: every language has a hash map.
functools.lru_cachein Python; aMapor plain object in JS; equivalents elsewhere. - Timing:
time.time()deltas in Python;console.time/console.timeEndorperformance.now()in JS. - Background work:
BackgroundTasksin FastAPI;setImmediateor a worker queue in Node; the conceptual move is the same — return to the user before the side effect finishes.
Use freely for AISE 2026 instruction.