Welcome back! In our last lesson, we built the essential data infrastructure for production ML: the feature store. We learned how to create a single source of truth for features that serves both high-throughput training pipelines (from the offline store) and low-latency prediction services (from the online store). You now know how to manage the data. Today, we'll design the systems that use that data to make predictions at scale.
This lesson directly addresses the learning outcome: Design scalable architectures for both online (real-time) and batch (offline) model inference. Once a model is trained, deploying it so it can deliver value is a complex system design challenge. Mastering these patterns is fundamental for any senior engineer working on AI/ML platforms at companies like Google or Meta.
We'll break down this crucial topic into our five-concept structure:
- The Core Dichotomy: Online vs. Batch Inference
- Architecture of Online (Real-Time) Inference
- Optimizing Online Inference: The Power of Dynamic Batching
- Architecture of Batch (Offline) Inference
- The Hybrid Model: Asynchronous Inference for Resilience and Scale
1. The Core Dichotomy: Online vs. Batch Inference (Easy)
-
Technical Explanation:
Model inference—the process of using a trained model to make a prediction—is not a one-size-fits-all problem. The way you deploy your model depends entirely on the product requirements. This leads to two primary architectural patterns:- Online (Real-Time) Inference: Used when predictions are needed immediately in response to a user action or event. The system is optimized for low latency (how fast you get one prediction). A canonical example is credit card fraud detection; the prediction must happen before the transaction is approved.
- Batch (Offline) Inference: Used when you need to generate predictions for a large volume of data at once, and it's acceptable for the results to be available later. The system is optimized for high throughput (how many predictions you can make over a period) and cost-effectiveness. A good example is generating personalized product recommendations for all users nightly.
The fundamental trade-off is Latency vs. Throughput. Optimizing for one often comes at the expense of the other.
-
Metaphor for a 5-Year-Old:
Imagine a restaurant.- Online Inference is the à la carte kitchen. A customer orders a burger, and a cook makes that one burger as fast as possible. The goal is speed for a single order (low latency).
- Batch Inference is the catering service. The kitchen has an order to prepare 1,000 chicken dinners for a wedding banquet tomorrow. They don't need to be fast for one dinner; they need to be efficient at making all 1,000 (high throughput).
-
Anchor Reading:
To build a solid foundation, let's explore these concepts and their underlying requirements in more detail.
ML serving 101: Core architectures
The article 'ML serving 101: Core architectures' by Paul Iusztin provides an excellent breakdown of the fundamental requirements that dictate your deployment choice.
Read the first two sections: 'Criteria for choosing ML deployment types' and 'Understanding inference deployment types'. Focus on the definitions of throughput and latency and how they create a trade-off. This will frame our entire discussion.
-
Conceptual Python Snippet (Illustrating the Two Modes):
# 1. Online Inference: A web service endpoint # This function would be part of a web server (like Flask or FastAPI). # It's called for one user at a time and must return quickly. def predict_online(user_request_data): # 1. Get features from the ONLINE feature store (low latency) feature_vector = feature_store.get_online_features(user_id=user_request_data['user_id']) # 2. Make a single prediction prediction = model.predict(feature_vector) # 3. Return immediately return {"prediction": prediction} # 2. Batch Inference: A distributed data processing job # This function would be part of a Spark or Ray job. # It runs on a schedule over a huge dataset. def predict_batch(all_users_dataframe): # 1. Get features from the OFFLINE feature store (high throughput) # This is a large-scale join operation. features_df = feature_store.get_historical_features(entity_df=all_users_dataframe) # 2. Apply model to all rows in parallel predictions_df = features_df.withColumn("prediction", model_udf(features_df.features)) # 3. Save all predictions to a database for later use predictions_df.write.save_to("results_database/daily_recommendations")
2. Architecture of Online (Real-Time) Inference (Medium)
-
Technical Explanation:
A scalable online inference system is a classic example of a distributed, stateless microservice architecture. The request flows like this:- API Gateway: The single entry point for all clients. It handles authentication, rate limiting, and request validation before forwarding the request internally.
- Load Balancer: Distributes incoming prediction requests evenly across a pool of model serving workers. This prevents any single worker from being overwhelmed and is key to high availability.
- Model Serving Workers: A group of identical, stateless services. Each worker loads a copy of the model into memory and is ready to serve predictions. "Stateless" means a worker retains no memory of past requests. Any request can be sent to any worker, which is what makes horizontal scaling (adding more workers) so effective.
- Model Registry: A central repository where trained and versioned model artifacts are stored. When a worker starts up, it pulls the specified model version from this registry.
This entire setup is typically containerized using Docker and managed by an orchestrator like Kubernetes, which can automatically handle scaling, health checks, and replacing failed workers.
-
Metaphor for a 5-Year-Old:
Let's expand our à la carte kitchen.- API Gateway: The cashier who takes your order, checks if you have money, and makes sure you're not ordering 1,000 burgers at once.
- Load Balancer: The shift manager who sees three cooks are available. Cook 1 is busy, Cook 2 is finishing up, but Cook 3 is free. The manager gives your order to Cook 3.
- Model Serving Workers: The identical cooks. Each has the same training and the same recipe book (the model). They don't need to know what you ordered yesterday; they just cook the burger on the ticket they receive. If it gets busy, the manager can call in more identical cooks to handle the load.
- Model Registry: The central office where the master recipe books are stored. When a new cook starts their shift, they get the latest, approved recipe book.
-
Anchor Reading:
This article provides a superb, interview-ready breakdown of a full model deployment system, with a clear focus on the online serving components.
Meta MLE Interview: Machine Learning Model Deployment ...
The article 'Meta MLE Interview: Machine Learning Model Deployment' provides a blueprint for a robust serving system.
Read the sections 'High-Level Architecture', 'Model Serving Layer', and 'Inference Path Internals'. Pay close attention to the role of each component (API Gateway, Load Balancer, Serving Layer) and the stateless design principle that enables horizontal scaling. This is the canonical architecture for online inference.
3. Optimizing Online Inference: The Power of Dynamic Batching (Hard)
-
Technical Explanation:
While online inference handles requests one by one conceptually, a major inefficiency arises when using hardware accelerators like GPUs. A GPU achieves its speed through massive parallelism, but feeding it single data points leaves most of its cores idle.Dynamic Batching (or micro-batching) is a critical optimization technique to improve throughput. An inference server doesn't immediately send a request to the model. Instead, it holds the request in a short-lived queue for a very brief period (e.g., 5-10 milliseconds). If other requests arrive during this window, they are grouped together into a single "batch." This batch is then fed to the GPU in one pass, dramatically improving hardware utilization and overall throughput.
This introduces a small amount of extra latency for each request but can increase the system's Queries Per Second (QPS) by an order of magnitude. It's a trade-off that is almost always worthwhile for deep learning models.

-
Metaphor for a 5-Year-Old:
Imagine an elevator in a busy building. It would be very inefficient if the elevator went up and down for every single person who arrived. Instead, the elevator waits for a few seconds to let a small group of people get in (dynamic batching) and then takes them all up at once. Each person waits a few extra seconds, but the elevator transports far more people per hour (higher throughput). -
Conceptual Python Snippet (The Logic of a Batching Server):
This pseudo-code illustrates the core idea inside a model server like NVIDIA's Triton.import queue import threading import time # A thread-safe queue to hold incoming requests request_queue = queue.Queue() # The worker thread that performs batched inference def inference_worker(): while True: batch = [] # Wait for the first request batch.append(request_queue.get()) # Try to collect more requests for a short time (e.g., 5ms) start_time = time.time() while (time.time() - start_time) < 0.005 and len(batch) < MAX_BATCH_SIZE: try: # Non-blocking get batch.append(request_queue.get_nowait()) except queue.Empty: break # No more requests in the queue # We have a batch! Process it. inputs = [req['data'] for req in batch] results = model.predict(inputs) # GPU processes this efficiently # Send results back to individual clients (details omitted) for i, req in enumerate(batch): req['response_queue'].put(results[i]) # In the main web server thread... def handle_http_request(data): response_q = queue.Queue() request_queue.put({'data': data, 'response_queue': response_q}) # Wait for the result from the worker result = response_q.get() return result
4. Architecture of Batch (Offline) Inference (Medium)
-
Technical Explanation:
Batch inference architecture is designed for throughput and cost, not latency. It is closely tied to data engineering and distributed computing frameworks.- Workflow Orchestrator: A tool like Apache Airflow or Argo Workflows manages the entire process. It triggers the job on a schedule (e.g., every night at 1 AM) and handles dependencies and failure recovery.
- Distributed Compute Engine: The workhorse is a framework like Apache Spark or Ray. The orchestrator submits a job to the compute engine.
- Data Ingestion: The Spark/Ray job reads a massive dataset from a distributed file system (like HDFS or S3) or a data warehouse (like BigQuery/Snowflake). This is the equivalent of reading from our offline feature store.
- Parallel Inference: The model is broadcast to hundreds or thousands of worker nodes. The input data is partitioned, and each worker applies the model to its partition in parallel. This is often done using a User-Defined Function (UDF).
- Results Storage: The predictions from all workers are collected and written back to a destination, such as a database table or another location in the data lake, where downstream applications can consume them.

-
Metaphor for a 5-Year-Old:
Back to our catering company.- Orchestrator: The head chef who has the master plan for the wedding banquet. The plan says: "At 9 AM, start preparing the 1,000 chicken dinners."
- Compute Engine: The entire kitchen staff.
- Data Ingestion: A giant truck delivers 1,000 raw chickens (the input data) from the warehouse.
- Parallel Inference: The head chef divides the chickens among 20 cooks (the workers). Each cook takes 50 chickens and prepares them according to the same recipe (the model UDF). They all work at the same time.
- Results Storage: As the dinners are finished, they are loaded into a large refrigerated truck (the results database), ready for delivery to the wedding.
-
Anchor Reading:
The samedecodingaiarticle we started with has a concise and accurate description of this pattern.
ML serving 101: Core architectures
Let's revisit 'ML serving 101' to see its description of the batch architecture.
Read the section 'Offline batch transform'. Notice how it emphasizes processing large volumes, scheduling, and storing results for later use. This perfectly contrasts with the online architecture.
5. The Hybrid Model: Asynchronous Inference for Resilience and Scale (Harder)
-
Technical Explanation:
What if a prediction takes too long for a synchronous online request (e.g., >1 second), but you can't wait hours for a batch job? This is where asynchronous inference comes in. It's a hybrid pattern that offers a balance between online and batch.The architecture uses a message queue (like Kafka, RabbitMQ, or SQS) as a buffer:
- A client sends a request to an API endpoint.
- The API does minimal validation and immediately publishes the request as a message to a queue, then returns a
202 Acceptedstatus with a job ID to the client. The client is now free and not blocked. - A separate pool of inference workers subscribes to this queue. They pull messages one by one (or in small batches), perform the potentially long-running inference, and write the result to a results store (e.g., a database or object storage), indexed by the job ID.
- The client can then either poll an endpoint with the job ID to check for the result or receive a webhook/push notification when the job is complete.
This architecture is highly resilient and cost-effective. It decouples the request intake from the processing, allowing it to absorb huge traffic spikes without failing. The number of workers can be scaled independently based on the queue length.
-
Metaphor for a 5-Year-Old:
You go to a busy deli and order a complex, custom sandwich.- You place your order with the cashier.
- The cashier doesn't make you wait at the counter. They give you a ticket with a number (job ID) and put your order slip on a spike (the message queue). You are free to sit down.
- The sandwich makers (inference workers) take slips from the spike one by one, make the sandwiches, and put them on the pickup shelf (results store).
- They call your number over the loudspeaker (notification), and you go pick up your sandwich.
-
Anchor Video:
This video on designing a recommendation engine shows a practical application of using queues to manage the inference workflow.
Design an ML Recommendation Engine | System Design
The video 'Design an ML Recommendation Engine' by Interview Pen showcases an architecture that uses queues to manage different parts of the ML system, including inference.
Watch from 05:32 to 07:19. Pay close attention to the introduction of the 'inference server' that reads from a queue and pre-computes recommendations into a cache. This is a form of asynchronous processing designed to reduce user-facing latency.
Test your understanding! (System Design Question)
You are designing the ML inference system for a video platform like YouTube. You need to support two features:
- Content Moderation: As soon as a video is uploaded, it must be scanned for inappropriate content. This process can take a few minutes per video.
- "Up Next" Recommendations: When a user is watching a video, a list of recommended next videos must be displayed on the side of the page instantly.
For each feature, which inference architecture would you choose (Online, Batch, or Asynchronous)? Justify your choice by describing the high-level architecture and explaining why it's the best fit based on latency, throughput, and user experience requirements.
Show answer
Here's a breakdown of the design choices:
1. Feature: Content Moderation
- Chosen Architecture: Asynchronous Inference.
- Justification:
- Latency: The inference process (scanning a full video) is long-running (minutes), making a synchronous online approach impossible. The user would see a timeout.
- User Experience: The user doesn't need an instant result. They can upload the video and leave. The system can process it in the background and notify them (or take action) later if a problem is found.
- Scalability: Video uploads can be very spiky. An asynchronous architecture with a message queue (like SQS or Kafka) is perfect for this. The upload service can simply drop a message onto the queue for each new video and return immediately. A separate fleet of inference workers can scale up or down based on the queue length, processing videos at a steady pace without being overwhelmed by spikes. This is far more cost-effective and resilient than trying to provision enough servers for peak load.
- High-Level Architecture:
- User uploads video via web server.
- Web server saves the video to object storage (e.g., S3) and publishes a message to a
video-processing-queuecontaining the video's ID. - A pool of auto-scaling containerized workers pulls messages from this queue.
- Each worker downloads the video, runs the content moderation model, and stores the result (e.g.,
PASS/FAILwith timestamps) in a database. - If the result is
FAIL, a separate process flags the video or notifies an operations team.
2. Feature: "Up Next" Recommendations
- Chosen Architecture: Online (Real-Time) Inference.
- Justification:
- Latency: This is the primary constraint. The recommendations must appear almost instantly (< 200ms) when the page loads. Any noticeable delay harms user engagement.
- User Experience: The user is actively waiting for the content. A synchronous request-response pattern is required.
- Input: The recommendations are highly contextual, depending on the current video being watched, the user's history, and the time of day. The prediction must be generated "on-the-fly."
- High-Level Architecture:
- User's browser requests the video watch page.
- The backend service makes a request to a load-balanced, online recommendation service. The request includes the
user_idandcurrent_video_id. - The recommendation service might execute a two-stage process (as seen in the mock interview resource):
- Candidate Generation: Quickly retrieve a few hundred candidate videos from a pre-computed index or the online feature store.
- Ranking: Use a lightweight ML model to rank these candidates based on features fetched in real-time from the online feature store (e.g., user's recent activity).
- This ranking is done with dynamic batching on GPUs to maintain high throughput.
- The ranked list of video IDs is returned to the backend, which then renders the "Up Next" panel.
Conclusion
Today, we've designed the three core architectures for putting machine learning models into production. You now have a clear framework for deciding how to serve a model based on business needs, whether the priority is instant responses, massive throughput, or a resilient balance between the two.
Key Takeaways:
- Online Inference is for low-latency, synchronous predictions, built on stateless, horizontally scalable services.
- Batch Inference is for high-throughput, offline jobs, built on scheduled workflows and distributed compute engines like Spark.
- Asynchronous Inference is a hybrid model using message queues to decouple long-running jobs from clients, providing resilience and handling spiky traffic.
- The choice of architecture is a critical system design decision driven by a trade-off between latency, throughput, cost, and complexity.
- Optimizations like dynamic batching are essential for achieving high performance with modern hardware in online systems.
Next Lesson Preview
We've now trained a model, built a feature store, and designed the serving architecture. But how do we deploy a new model without breaking everything? How do we prove the new model is actually better in the real world? Our next lesson will focus on deployment strategies: Implement A/B testing and canary deployment strategies for comparing ML models in production.