Machine learning system design is the architectural discipline of building end-to-end ML systems that operate reliably at scale in production. Unlike traditional software systems, ML systems must handle probabilistic outputs, continuous data evolution, and the unique challenge of serving predictions while simultaneously learning from new data. Modern ML system design integrates data pipelines, training infrastructure, model serving, experimentation frameworks, and monitoring systems into a cohesive architecture. The most critical distinction: ML systems degrade silently — without proper monitoring and retraining triggers, model performance erodes invisibly as the world changes beneath them.
What This Cheat Sheet Covers
This topic spans 15 focused tables and 149 indexed concepts, 122 flashcards. Below is a complete table-by-table outline of this topic, spanning foundational concepts through advanced details.
A jump-to index of every table row in this cheat sheet.
An interactive map of every table and concept in this topic.
Table 1: Core ML System Design Patterns
Production ML systems follow repeatable architectural patterns that balance prediction accuracy, latency, cost, and maintainability. These patterns represent proven approaches for deploying models at scale.
| Pattern | Example | Description | |
|---|---|---|---|
predictions = model.predict(daily_data)store_to_cache(predictions) | • Precomputes predictions for all inputs on a schedule (hourly/daily) • serves results from cache for low-latency lookups at the cost of staleness | ||
return model.predict(request.features) | • Computes predictions on-demand per request • sub-100ms latency requirement drives optimization choices like model size and caching | ||
model.partial_fit(new_batch)if drift_detected: retrain() | • Updates model continuously with streaming data • trades training stability for adaptiveness to distribution shifts in real-time | ||
features = store.get_online(user_id)offline = store.get_historical(timestamp) | • Centralized feature computation and serving layer • ensures training-serving consistency by using identical feature logic in both paths | ||
registry.log_model(model, metrics)prod_model = registry.load("v2.3") | • Version control for trained models with lineage tracking • enables rollbacks, A/B testing, and audit trails of what ran when | ||
old_pred = model_v1.predict(x)new_pred = model_v2.predict(x)log_both(); serve(old_pred) | • Runs new model in parallel with production model without affecting users • validates performance on live traffic before cutover | ||
if user_id % 100 < 5: return new_model.predict(x) | • Gradually shifts traffic to new model (5% → 25% → 100%) • limits blast radius of model regressions while collecting real-world metrics | ||
model = assign_variant(user_id)log_prediction_and_outcome() | • Compares models by randomly assigning users to variants • measures causal impact on business metrics rather than just accuracy | ||
probs = thompson_sampling(rewards)model = np.random.choice(models, p=probs) | • Dynamically allocates traffic based on performance • optimizes while learning unlike fixed A/B tests that wait for significance | ||
cached = redis.get(key)if cached: return cachedreturn model.predict(input) | • Precomputes 90% of predictions in batch • falls back to real-time inference on cache miss for cost-effective low latency |