Skip to main content

Conversion Prediction System Design: ML Pipeline for E-commerce Revenue Optimization

Comprehensive system design for real-time conversion prediction using ensemble learning, feature engineering, and scalable ML infrastructure.

Modern e-commerce platforms require sophisticated conversion prediction systems to optimize user experience and maximize revenue. This document outlines a complete ML system architecture that combines real-time feature processing, ensemble modeling, and scalable deployment strategies to predict user conversion probabilities at scale.

1. Problem Statement & ML Task Definition

Clarifying questions

  1. What is the specific business context for conversion prediction? Is this for e-commerce, ad serving, lead generation, or another domain?
  2. What is the expected QPS and latency budget for real-time predictions? Will this be used for real-time bidding, email campaigns, or web page personalization?
  3. What is the target conversion signal? Is it purchase, sign-up, click, or another specific action?
  4. What is the expected scale of users/items and volume of training data? How much historical data do we have available?
  5. What is the acceptable trade-off between model accuracy and inference latency? Will this be used for batch processing or real-time serving?
  6. What is the expected data freshness requirements? How frequently should models be retrained or updated?
  7. What are the key business success metrics that will drive model evaluation and optimization?

Business use case and success criteria

The system aims to predict the probability that a user will convert (e.g., make a purchase, sign up for a service, or complete an action) within a specified time window after being exposed to a recommendation or ad. The system will power real-time personalization, targeted campaigns, and resource allocation to maximize business KPIs such as revenue per user, conversion rate, or customer lifetime value.

Success criteria include:

  • 15% improvement in conversion rate over baseline
  • 20% reduction in cost per acquisition (CPA)
  • 30% improvement in revenue per user
  • 95th percentile prediction latency under 100ms for real-time serving

ML problem formulation

This is a binary classification task where the goal is to predict whether a user will convert (1) or not convert (0) within a specified time window. The task is framed as a probability estimation problem to enable decisioning based on confidence thresholds.

Justification:

  • Conversion is a binary event with clear positive/negative outcomes
  • Probability estimates enable flexible business decisioning (e.g., threshold tuning for different KPIs)
  • Binary classification is well-suited for this type of user behavior prediction

ML evaluation metrics

Offline Evaluation Metrics:

  • AUC-ROC: Primary metric for overall model discrimination
  • Precision@K: For top-K recommendation scenarios (e.g., top 100 users to target)
  • NDCG@K: For ranked recommendation scenarios (e.g., ranking users by conversion probability)
  • Log Loss: For calibrated probability estimation

Online Evaluation Metrics:

  • Click-Through Rate (CTR): For ad serving scenarios
  • Conversion Rate: Direct business impact metric
  • Revenue per User (RPU): Business value measurement
  • Cost Per Acquisition (CPA): Cost efficiency metric

Scale and constraints

Back-of-envelope estimates:

  • Training data size: 50M user-item interactions (100GB raw data)
  • Number of features: 5,000 total features (user + item + context + interaction)
  • Embedding matrix memory footprint: 5,000 features × 128 dimensions × 4 bytes = ~2.5MB per user
  • Serving QPS math: 100ms latency budget → 10 QPS per model instance; 1,000 QPS requires 100 instances

Scale constraints:

  • Target: 1,000 QPS for real-time serving
  • Latency budget: 100ms p99 (50ms p50)
  • Data volume: 50M training samples, 100M daily user interactions
  • Freshness requirements: Model retraining every 24 hours, feature updates every hour

Non-ML baseline strategy

Baseline rule-based system:

  1. Cold start handling: For new users, use default conversion probability (e.g., 0.02) based on historical population average
  2. Simple heuristics:
    • Users with > 50 page views in last hour → 0.15 probability
    • Users with > 100 page views in last hour → 0.25 probability
    • Users with recent purchase history → 0.30 probability
  3. Fallback logic: If model fails to serve, return baseline probability with error logging for retraining trigger
  4. Feature-based rules:
    • Users from high-converting segments (e.g., age 25-35, location US) → +0.05 probability boost
    • Users with low engagement (e.g., < 5 page views in past 24h) → -0.03 probability adjustment
# Baseline conversion probability calculation (simplified)
def calculate_baseline_conversion_probability(user_profile):
    base_prob = 0.02  # population average
    
    if user_profile.get('recent_purchases', 0) > 0:
        return min(0.30, base_prob + 0.15)
    elif user_profile.get('page_views_last_hour', 0) > 100:
        return min(0.25, base_prob + 0.10)
    elif user_profile.get('page_views_last_hour', 0) > 50:
        return min(0.20, base_prob + 0.08)
    else:
        return base_prob

2. Data Strategy

Training Data Sources

  • Explicit feedback: Purchase events, cart abandonment, wishlist additions, direct user ratings
  • Implicit signals: Page views, time on page, scroll depth, click-through rates, session duration
  • Third-party data: Demographic information from partner integrations, contextual signals (weather, events)
  • Historical behavioral sequences: User navigation patterns, item browsing history, search queries
  • Product catalog data: Item categories, pricing, availability, brand information

Labeling Pipeline Design

  • Human annotation: For high-value conversion events (e.g., purchase confirmation) with expert review for edge cases
  • Weak supervision: Using heuristics like "user viewed item X and added to cart but didn't purchase within 24h" as negative labels
  • Programmatic labeling:
    def label_conversion_event(user_session):
        if user_session['purchase'] == True:
            return 1
        elif user_session['cart_abandonment'] == True and user_session['time_to_purchase'] > 24*60*60:
            return 0
        else:
            return None  # Needs human review

Class Imbalance Handling Strategy

Conversion events represent ~2-5% of total user interactions, requiring:

  • Oversampling: Boost minority class samples in training batches
  • Class weights: Apply inverse frequency weighting during model training
  • Focal Loss: Reduce loss contribution from easy-to-classify examples to focus on hard ones
  • Stratified sampling: Ensure balanced representation in training batches

Negative Sampling Approach

  • Hard negative mining: Sample sessions that show high engagement but no conversion (e.g., long session duration, multiple item views)
  • Time-based sampling: Prefer recent non-conversion events to capture current user interest patterns
  • Stratified negative sampling: Maintain ratio of 1:3-5 positive to negative samples in training batches

Data Freshness and Update Frequency

  • Real-time signals: Updated every 5-10 minutes for user behavior tracking
  • Batch features: Updated daily for item and user embeddings, feature aggregates
  • Historical sequences: Updated weekly for long-term behavioral patterns
  • Freshness requirements: 24-hour window for user behavior, 7-day window for item popularity trends

Privacy Compliance

  • Data anonymization: Remove PII (names, email addresses) from training data
  • GDPR/CCPA compliance: Implement data retention policies (30 days for behavioral data, 6 months for purchase data)
  • Consent management: Track user consent for data collection and model training
  • Differential privacy: Apply noise to sensitive features during training to prevent re-identification

Data Quality Validation and Monitoring

  • Data validation checks:
    • Session consistency (time order, valid item IDs)
    • User ID uniqueness and format validation
    • Purchase timestamp alignment with session events
  • Monitoring dashboard: Track data drift, missing values, and distribution shifts in real-time
  • Automated alerts: Trigger when data quality drops below threshold (e.g., >5% missing values in key features)
  • Data lineage tracking: Maintain audit trail of data transformations and feature engineering steps

3. Feature Engineering

Feature Taxonomy

Features are organized into four main categories:

  • User Features: User demographics, behavioral history, engagement patterns, and segmentation data
  • Item Features: Product attributes, category information, pricing, inventory status, and popularity metrics
  • Context Features: Time-based signals (hour, day of week, seasonality), device type, geographic location, and campaign information
  • Interaction Features: User-item interaction history, recency of engagement, session behavior, and cross-feature combinations

Embedding Design

Entity Embeddings:

  • User ID embeddings (128-dim) trained via click-through rate prediction
  • Item ID embeddings (256-dim) using contrastive learning to capture semantic similarity
  • Category embeddings (64-dim) for hierarchical categorization

Text Embeddings:

  • Product title and description embeddings using BERT-base (768-dim) fine-tuned on product data
  • User review text embeddings using sentence-transformers (512-dim) for sentiment and content matching

Graph Embeddings:

  • User-item interaction graph embeddings using Node2Vec (128-dim) to capture latent user preferences and item relationships

Real-time vs Batch Feature Computation

Feature TypeComputation ModeReasoning
User session countReal-timeRequires low-latency response for conversion prediction
Item popularityBatchUpdated daily, can be pre-computed
User engagement scoreReal-timeDynamic metric that changes with each interaction
Historical conversion rateBatchStable over time, computed once per refresh cycle

Feature Store Design

Online Store:

  • Low-latency key-value store (e.g., Redis or DynamoDB) for real-time feature retrieval
  • TTL of 5 minutes for user session features, 1 hour for engagement scores

Offline Store:

  • Data warehouse (e.g., Snowflake or BigQuery) for training data and batch feature computation
  • Partitioned by date for efficient querying and historical analysis

Feature Freshness and TTL

FeatureSourceUpdate FrequencyStore Type
User session countReal-time logsEvery 5 minutesOnline
Item priceProduct catalogDailyOffline
User engagement scoreBehavioral logsEvery 15 minutesOnline
Item categoryProduct catalogDailyOffline
User purchase historyTransaction DBHourlyOffline
Time-based signalsSystem clockEvery minuteOnline

Cross Features and Feature Interaction Strategy

Cross features are engineered to capture complex user-item relationships:

  • User-item interaction frequency × item popularity (to detect high-value combinations)
  • User session duration × item category (to understand engagement patterns by content type)
  • Time since last interaction × user purchase frequency (to identify at-risk users)

Feature Importance and Selection Methodology

Methodology:

  • SHAP values for model interpretability and feature importance ranking
  • Permutation importance computed on holdout set to validate feature relevance
  • Recursive Feature Elimination (RFE) with cross-validation for automated selection

Threshold: Features with SHAP importance > 0.01 and permutation importance > 0.005 are retained for model training.

import numpy as np
from sklearn.feature_selection import RFE
from sklearn.ensemble import RandomForestClassifier

# Sample feature matrix (user_id, item_id, session_count, engagement_score, etc.)
X = np.random.rand(1000, 10)  # 1000 samples, 10 features
y = np.random.randint(0, 2, 1000)  # Binary conversion target

# Feature selection using RFE with Random Forest
rf_model = RandomForestClassifier(n_estimators=100, random_state=42)
selector = RFE(rf_model, n_features_to_select=5, step=1)

# Fit selector
selector.fit(X, y)

# Get selected features (indices)
selected_features = selector.support_
feature_importance_scores = selector.ranking_

# Output selected features
print("Selected features (indices):", np.where(selected_features)[0])
print("Feature importance ranking:", feature_importance_scores)

4. Model Architecture

Model Selection with Justification

For a conversion prediction system, I'll select a DNN-based two-tower architecture for the following reasons:

  1. Non-linear feature interactions: Conversion prediction requires capturing complex relationships between user and item features that linear models cannot adequately represent
  2. Scalability: DNNs can scale well with increasing feature dimensions and training data
  3. Flexibility: Easy to incorporate various embedding types (user, item, context) and real-time features
  4. Performance: DNNs typically outperform traditional ML methods like logistic regression or GBMs on complex recommendation tasks

Trade-offs compared to alternatives:

  • Logistic Regression: Simpler but lacks ability to capture complex feature interactions; poor performance on high-dimensional sparse data
  • GBM (XGBoost/LightGBM): Good performance but harder to scale and less flexible for real-time serving
  • Transformer: Powerful but overkill for conversion prediction; introduces unnecessary complexity and latency

Architecture Diagram

graph TD
    A[User Features] --> B[User Embedding Layer]
    C[Item Features] --> D[Item Embedding Layer]
    B --> E[User Representation]
    D --> F[Item Representation]
    E --> G[Interaction Layer]
    F --> G
    G --> H[MLP Layers]
    H --> I[Conversion Probability]
    
    subgraph "User Tower"
        B
        E
    end
    
    subgraph "Item Tower"
        D
        F
    end
    
    subgraph "Scoring Layer"
        G
        H
        I
    end

Two-Tower / Multi-Task / Ensemble Design

The system uses a two-tower architecture where:

  • User tower processes user features (demographics, behavior history, context)
  • Item tower processes item features (product attributes, category, price)
  • The towers interact through dot product or concatenation to compute conversion likelihood

Multi-task extension: Can extend to predict multiple related signals (click-through rate, purchase value, time-to-conversion) using a shared backbone with task-specific heads.

Pre-trained Model Selection and Fine-tuning Strategy

For foundation model integration:

  • Pre-trained text embeddings: Use BERT or similar for item descriptions and user reviews
  • Fine-tuning strategy:
    • Pre-train on large-scale text data (product descriptions, reviews)
    • Fine-tune on conversion prediction task with domain-specific data
    • Use transfer learning to reduce training time and improve generalization

Model Complexity vs Latency Trade-off Analysis

ModelParametersInference Latency (ms)Memory FootprintAccuracy (AUC)
Logistic Regression10K15MB0.72
XGBoost5M1550MB0.82
Two-Tower DNN (Small)10M35200MB0.86
Two-Tower DNN (Medium)50M65500MB0.89
Two-Tower DNN (Large)200M1202GB0.92

Offline Evaluation Baseline Framing

Baseline: Logistic regression with engineered features Expected improvement: 3-5% AUC improvement over baseline Target: Achieve AUC > 0.90 on holdout test set

Core Model Code Snippet

import torch
import torch.nn as nn
import torch.nn.functional as F

class ConversionPredictionModel(nn.Module):
    def __init__(self, user_feature_dim, item_feature_dim, 
                 user_embedding_dim=128, item_embedding_dim=128, 
                 hidden_dims=[256, 128, 64]):
        super().__init__()
        
        # User embedding layers
        self.user_embedding = nn.Linear(user_feature_dim, user_embedding_dim)
        
        # Item embedding layers  
        self.item_embedding = nn.Linear(item_feature_dim, item_embedding_dim)
        
        # MLP layers for interaction
        self.mlp_layers = nn.ModuleList([
            nn.Linear(user_embedding_dim + item_embedding_dim, hidden_dims[0])
        ])
        
        for i in range(len(hidden_dims) - 1):
            self.mlp_layers.append(
                nn.Linear(hidden_dims[i], hidden_dims[i+1])
            )
            
        self.output_layer = nn.Linear(hidden_dims[-1], 1)
        
    def forward(self, user_features, item_features):
        # Embedding layers
        user_emb = F.relu(self.user_embedding(user_features))
        item_emb = F.relu(self.item_embedding(item_features))
        
        # Concatenate embeddings
        combined = torch.cat([user_emb, item_emb], dim=1)
        
        # MLP processing
        for layer in self.mlp_layers:
            combined = F.relu(layer(combined))
            
        # Final prediction
        output = torch.sigmoid(self.output_layer(combined))
        return output
    
    def compute_loss(self, predictions, targets):
        # Binary cross entropy loss
        return F.binary_cross_entropy(predictions.squeeze(), targets.float())
    
    def predict_conversion_probability(self, user_features, item_features):
        """Returns conversion probability for given user-item pair"""
        self.eval()
        with torch.no_grad():
            prob = self(user_features, item_features)
            return prob.cpu().numpy()

# Example usage:
# model = ConversionPredictionModel(user_feature_dim=100, item_feature_dim=200)
# user_features = torch.randn(32, 100)  # batch_size=32
# item_features = torch.randn(32, 200)
# predictions = model(user_features, item_features)
# loss = model.compute_loss(predictions, torch.randint(0, 2, (32, 1)))

This implementation provides:

  • Modular embedding and MLP layers
  • Clear forward pass with proper activation functions
  • Binary cross-entropy loss computation
  • Prediction probability extraction
  • Batch processing capability for serving
  • Memory-efficient architecture suitable for production deployment

5. Serving & Inference Architecture

System Diagram

graph TD
    A[User Request] --> B[Load Balancer]
    B --> C[API Gateway]
    C --> D[Feature Store Lookup]
    D --> E[Model Serving Layer]
    E --> F[Scoring Service]
    F --> G[Response Formatter]
    G --> H[Return Result]
    
    subgraph "Real-time Serving Pipeline"
        C --> I[Request Router]
        I --> J[Embedding Cache]
        J --> K[Model Inference Engine]
        K --> L[Ranking/Scoring]
        L --> M[Response Builder]
    end

Online vs Batch Serving Decision

Online serving chosen for conversion prediction due to:

  • Real-time decision making required (user actions within seconds)
  • Low latency requirement (< 100ms p99 for user-facing experiences)
  • Personalization needs (user-specific predictions)
  • Immediate feedback loop for model performance

Batch serving would be appropriate for:

  • Weekly conversion rate forecasting
  • Historical trend analysis
  • Offline model retraining

Two-Stage Pipeline

Candidate Retrieval → Scoring → Re-ranking
  1. Candidate Retrieval:

    • Fast retrieval of top-K items using approximate nearest neighbor (ANN) search
    • Use Faiss or Annoy for efficient item embedding similarity lookup
  2. Scoring:

    • Full model inference on candidate set
    • Apply ranking weights and business rules
  3. Re-ranking:

    • Apply diversity constraints and business logic
    • Final ranking based on conversion probability + business factors

Serving Infrastructure

Primary choice: TorchServe with custom inference wrapper

Justification:

  • Supports PyTorch models natively
  • Built-in model versioning and A/B testing capabilities
  • Production-grade with built-in metrics and logging
  • Easy integration with Kubernetes for scaling

Alternative considerations:

  • Triton Inference Server: Better for multi-model serving, but more complex setup
  • vLLM: For LLM-based conversion prediction (if using prompt engineering), but overkill for typical conversion models

Latency Budget Breakdown

Stagep50 Latencyp99 LatencyBudget
Feature Lookup5ms15ms20ms
Model Inference10ms30ms40ms
Ranking/Scoring5ms15ms20ms
Response Build2ms8ms10ms
Total22ms68ms90ms

Model Compression Strategy

Primary approach: Quantization + Pruning

  1. INT8 Quantization:

    • 4x reduction in model size
    • <5% accuracy degradation for most models
    • Minimal impact on inference latency
  2. Structured Pruning:

    • Remove 30-50% of model parameters
    • Maintain model performance within 2-3% of full model
  3. Model Distillation:

    • Train smaller student model using teacher model logits
    • 5x-10x faster inference with <2% accuracy loss

Caching Strategy

Cache TypeSize EstimatePurpose
Prediction Cache50GBStore recent user predictions (LRU)
Embedding Cache20GBPre-computed item/user embeddings
KV Cache (LLM)10GBFor prompt-based conversion models

Implementation:

class PredictionCache:
    def __init__(self, max_size=100000):
        self.cache = {}
        self.access_order = []
        self.max_size = max_size
    
    def get(self, key):
        if key in self.cache:
            # Move to end (most recently used)
            self.access_order.remove(key)
            self.access_order.append(key)
            return self.cache[key]
        return None
    
    def set(self, key, value):
        if len(self.cache) >= self.max_size:
            # Remove least recently used
            oldest = self.access_order.pop(0)
            del self.cache[oldest]
        
        self.cache[key] = value
        self.access_order.append(key)

Auto-scaling and Capacity Planning

Horizontal scaling strategy:

  • Target QPS: 10,000 requests/sec (back-of-envelope: 50M daily users * 200 conversions/day = ~10,000 QPS)
  • Instance size: 4 vCPUs + 16GB RAM per model instance
  • Target p99 latency: < 100ms

Scaling factors:

  • Warm-up period: 2 hours for model loading and cache warming
  • Graceful degradation: Fallback to rule-based model during scaling events
  • Health checks: Liveness probe every 30 seconds, readiness probe every 15 seconds

Capacity calculation:

QPS = 10,000
Latency target = 100ms
Throughput per instance = 10,000 * 0.1 = 1,000 requests/sec
Model instances needed = 10,000 / 1,000 = 10 instances

Auto-scaling policy:

  • Scale up when QPS > 8,000 (80% threshold)
  • Scale down when QPS < 2,000 (20% threshold)
  • Minimum instances: 5 for cold start handling
  • Maximum instances: 50 for peak load handling

6. Evaluation Framework

Offline Evaluation Methodology

For offline evaluation, we employ a temporal split approach to ensure that our model is evaluated on data from the future relative to training, preventing data leakage. This is critical for conversion prediction systems where temporal dependencies are strong.

We split the dataset chronologically into:

  • Training: 6 months of historical data (2023-01-01 to 2023-06-30)
  • Validation: 1 month of data (2023-07-01 to 2023-07-31)
  • Test: 1 month of data (2023-08-01 to 2023-08-31)

This ensures that our model is evaluated on truly unseen future data, simulating real-world deployment conditions.

We also implement time-aware cross-validation with 3-fold splits, where each fold uses a different time window to ensure robustness across temporal trends.

Slice-Based Evaluation

To detect model performance degradation across user segments, we define critical slices:

Slice TypeDefinitionSample Size
User SegmentAge groups (18-25, 26-35, 36+)>10k users
Device TypeMobile, Desktop, Tablet>5k users
Geographic RegionUS, EU, APAC>10k users
Conversion StageAwareness, Consideration, Purchase>5k users
Traffic SourceOrganic, Paid, Referral>5k users

We monitor AUC-ROC and Precision@K for each slice, with thresholds set at 0.85 AUC and 0.70 Precision@K to trigger alerts for any slice below these thresholds.

A/B Test Design

We design a randomized controlled trial with the following specifications:

  • Randomization Unit: User ID (to prevent spillover effects)

  • Sample Size Calculation:

    • Target: 5% lift in conversion rate
    • Power: 80%
    • Significance Level: 5%
    • Estimated baseline conversion rate: 2.5%
    • Required sample size per group: ~18,000 users
  • Test Duration: 30 days to capture seasonal patterns

  • Primary Metric: Conversion Rate (CR) with 95% confidence interval

  • Secondary Metrics:

    • Revenue per User (RPU)
    • Click-Through Rate (CTR) on recommendations

We use multi-armed bandits for adaptive allocation to optimize for performance while maintaining statistical validity.

Guardrail Metrics and Blocking Conditions

To ensure safe deployment, we define guardrail metrics:

MetricThresholdAction
AUC-ROC Drop< 0.85Block deployment
Precision@K Drop< 0.65Block deployment
Model Confidence Variance> 0.3Alert and investigate
False Positive Rate> 0.15Block deployment

If any guardrail metric exceeds thresholds, the system automatically blocks model rollout and alerts ML engineers.

Shadow Mode Rollout Plan

Before full A/B testing, we implement a shadow mode rollout:

  1. Phase 1 (Week 1):

    • 5% of traffic routed to new model in shadow mode
    • All predictions logged but not served to users
    • Compare offline metrics with online logs
  2. Phase 2 (Week 2):

    • 15% traffic in shadow mode
    • Validate prediction consistency and latency
  3. Phase 3 (Week 3):

    • 50% traffic in shadow mode
    • Monitor for prediction drift and performance gaps
  4. Phase 4 (Week 4):

    • Full production rollout with A/B test

Long-Term Metric Measurement

We track long-term impact using:

  • Delayed Conversion Rate:

    • 7-day, 30-day, and 90-day conversion rates post-prediction
    • Expected to show improvement over baseline
  • Engagement Decay:

    • Monitor if users who received recommendations engage less over time
    • Target: <5% decay in engagement over 30 days
  • Revenue Impact:

    • Track revenue per user (RPU) and conversion rate over time
    • Expected to show 10-15% improvement in key KPIs

We implement delayed feedback loops where user behavior beyond the initial prediction window is monitored to ensure model does not encourage short-term gains at the cost of long-term user satisfaction.

# Example A/B test evaluation logic in Python

import numpy as np
from scipy import stats

class ABTestEvaluator:
    def __init__(self, baseline_cr=0.025, target_lift=0.05):
        self.baseline_cr = baseline_cr
        self.target_lift = target_lift
    
    def calculate_sample_size(self, power=0.8, alpha=0.05):
        """Calculate required sample size for A/B test"""
        z_alpha = stats.norm.ppf(1 - alpha/2)
        z_beta = stats.norm.ppf(power)
        
        # Conservative estimate for variance
        p1 = self.baseline_cr
        p2 = self.baseline_cr * (1 + self.target_lift)
        
        # Sample size calculation for proportions
        n = (z_alpha + z_beta)**2 * (p1*(1-p1) + p2*(1-p2)) / (p2 - p1)**2
        return int(np.ceil(n))
    
    def evaluate_ab_test(self, control_conversions, test_conversions, control_users, test_users):
        """Evaluate A/B test results"""
        cr_control = control_conversions / control_users
        cr_test = test_conversions / test_users
        
        # Calculate confidence interval for difference
        p1 = cr_control
        p2 = cr_test
        n1 = control_users
        n2 = test_users
        
        # Standard error for difference in proportions
        se_diff = np.sqrt((p1*(1-p1)/n1) + (p2*(1-p2)/n2))
        
        # Z-score for 95% confidence
        z_score = (p2 - p1) / se_diff
        
        # P-value calculation
        p_value = 2 * (1 - stats.norm.cdf(abs(z_score)))
        
        return {
            'conversion_rate_control': cr_control,
            'conversion_rate_test': cr_test,
            'lift': (cr_test - cr_control) / cr_control,
            'p_value': p_value,
            'is_significant': p_value < 0.05
        }

# Example usage:
evaluator = ABTestEvaluator(baseline_cr=0.025, target_lift=0.05)
sample_size = evaluator.calculate_sample_size()
print(f"Required sample size per group: {sample_size}")

# Simulate test results
control_conversions = 450  # 2.5% of 18,000
test_conversions = 500     # 2.78% of 18,000
control_users = 18000
test_users = 18000

results = evaluator.evaluate_ab_test(control_conversions, test_conversions, control_users, test_users)
print(f"Test results: {results}")

7. Training Pipeline

Training Data Pipeline

The training data pipeline follows a multi-stage ETL process:

  1. Data Extraction: Raw events from Kafka streams and batch files from S3
  2. Preprocessing:
    • Feature extraction from user sessions and item interactions
    • Label generation using conversion windows (7-day post-click)
    • Data cleaning and deduplication
  3. Shuffling: Distributed shuffling using Apache Spark to ensure data distribution across training workers
  4. Batching: Batches of 10,000 samples for efficient GPU utilization
import torch
from torch.utils.data import Dataset, DataLoader
from typing import Dict, List

class ConversionPredictionDataset(Dataset):
    def __init__(self, features: List[Dict], labels: List[int]):
        self.features = features
        self.labels = labels
    
    def __len__(self):
        return len(self.features)
    
    def __getitem__(self, idx):
        # Normalize features
        feature_dict = self.features[idx]
        normalized_features = {
            k: torch.tensor(v, dtype=torch.float32) 
            for k, v in feature_dict.items()
        }
        label = torch.tensor(self.labels[idx], dtype=torch.float32)
        return normalized_features, label

# Example usage in training loop
def train_step(model, dataloader, optimizer, criterion):
    model.train()
    total_loss = 0
    for batch_features, batch_labels in dataloader:
        optimizer.zero_grad()
        outputs = model(batch_features)
        loss = criterion(outputs, batch_labels)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
    return total_loss / len(dataloader)

Distributed Training Strategy

  • Data Parallelism: Using PyTorch Distributed Data Parallel (DDP) across 8 GPUs
  • Model Parallelism: For large embedding tables, model parallelism is applied to embeddings
  • Training Cluster: 2x nodes with 8x A100 GPUs each (16 total GPUs)
  • Estimated Training Time: ~2 hours for 10M samples with batch size 1024

Training Infrastructure

  • Compute: 16x A100 GPUs (8 nodes × 2 GPUs each)
  • Storage: NVMe SSDs for fast data loading (10TB total)
  • Framework: PyTorch Lightning with distributed training support
  • Resource Allocation: 8GB GPU memory per worker, 256GB RAM per node

Hyperparameter Tuning Approach

  • Search Strategy: Bayesian Optimization using Optuna
  • Key Hyperparameters:
    • Learning rate: [1e-5, 1e-2]
    • Batch size: [64, 256, 1024]
    • Embedding dimension: [64, 128, 256]
    • Dropout rate: [0.1, 0.3, 0.5]
  • Tuning Duration: 48 hours for 100 trials

Experiment Tracking and Reproducibility

  • Tool: MLflow for experiment tracking and model versioning
  • Logging: Metrics (AUC, precision@10), hyperparameters, model artifacts
  • Reproducibility:
    • Fixed random seeds (torch.manual_seed, numpy.random.seed)
    • Versioned model checkpoints with metadata
    • Docker containers for training environments

Model Versioning and Registry Strategy

  • Versioning: Semantic versioning (v1.0.0, v1.1.0) with git commit hash
  • Registry: MLflow Model Registry with staging and production environments
  • Rollback Capability: Automated rollback to last stable version on performance degradation

Continual / Online Learning Design

  • Trigger: Performance degradation > 2% in AUC or precision@10
  • Strategy:
    • Online fine-tuning with recent data (last 30 days)
    • Incremental model updates every 24 hours
    • Data drift detection using PSI for feature distribution changes
  • Implementation:
    def detect_drift(current_features, historical_features):
        psi_values = []
        for feature in current_features:
            psi = calculate_psi(current_features[feature], 
                              historical_features[feature])
            psi_values.append(psi)
        return any(psi > 0.1 for psi in psi_values)  # Threshold for drift

8. Monitoring & Observability

Data Drift Detection

Data drift detection is critical for maintaining model performance in production. We implement drift detection using:

  • PSI (Population Stability Index) for categorical features with thresholds at 0.1 (warning) and 0.25 (critical)
  • KL Divergence for continuous features with thresholds at 0.05 (warning) and 0.1 (critical)
  • Chi-square test for categorical feature drift with p-value threshold of 0.05
import numpy as np
from scipy import stats
from sklearn.metrics import mutual_info_score

class DriftDetector:
    def __init__(self, threshold_warning=0.1, threshold_critical=0.25):
        self.threshold_warning = threshold_warning
        self.threshold_critical = threshold_critical

    def psi_drift(self, old_data, new_data):
        # Calculate PSI for categorical features
        old_counts = np.histogram(old_data, bins=50)[0]
        new_counts = np.histogram(new_data, bins=50)[0]
        
        # Normalize counts
        old_probs = old_counts / len(old_data)
        new_probs = new_counts / len(new_data)
        
        # Calculate PSI
        psi = np.sum((new_probs - old_probs) * np.log(new_probs / old_probs + 1e-8))
        return psi

    def kl_divergence(self, old_dist, new_dist):
        # For continuous features
        return stats.entropy(old_dist, new_dist)

Prediction Drift and Label Drift Monitoring

Prediction drift is monitored by comparing model outputs over time windows:

  • Prediction shift detection: Track mean prediction difference using t-test with p-value < 0.01 as alert trigger
  • Label drift: Monitor label distribution shifts using chi-square test for categorical labels

Model Performance Degradation Alerting

We implement multi-layered alerting:

  • Offline AUC drop: Alert if AUC drops below baseline - 0.02
  • Online CTR drop: Alert if CTR drops below baseline - 0.05%
  • Latency increase: Alert if p99 latency increases by >20%
class PerformanceMonitor:
    def __init__(self, baseline_auc=0.85, baseline_ctr=0.02):
        self.baseline_auc = baseline_auc
        self.baseline_ctr = baseline_ctr

    def check_auc_degradation(self, current_auc):
        return current_auc < self.baseline_auc - 0.02

    def check_ctr_degradation(self, current_ctr):
        return current_ctr < self.baseline_ctr - 0.0005

    def check_latency_breach(self, current_p99, threshold=100):
        return current_p99 > threshold * 1.2

Retraining Trigger Strategy

Retraining is triggered by:

  • Scheduled: Monthly retraining for model refresh
  • Drift-triggered: When PSI > 0.25 or KL divergence > 0.1 for any feature
  • Performance-triggered: When AUC drops by 2% or CTR drops by 0.5%

Logging Design

Prediction logs include:

class PredictionLogger:
    def __init__(self):
        self.prediction_log = []
        
    def log_prediction(self, user_id, item_id, features, prediction, timestamp):
        log_entry = {
            "user_id": user_id,
            "item_id": item_id,
            "features": features,
            "prediction": prediction,
            "timestamp": timestamp,
            "model_version": "v1.2.3"
        }
        self.prediction_log.append(log_entry)
        
    def log_feature_update(self, feature_name, old_value, new_value, timestamp):
        feature_log = {
            "feature": feature_name,
            "old_value": old_value,
            "new_value": new_value,
            "timestamp": timestamp
        }
        # Store in feature store or logging system

Feedback Loop for Continuous Improvement

We implement a feedback loop with:

  • Label collection pipeline: Collect user conversion labels within 7-day window
  • Re-training trigger: Automatic retraining when new labels exceed threshold of 1000 samples
  • Model versioning: Track model versions with associated performance metrics

The monitoring system uses Prometheus and Grafana for real-time dashboards, with alerts configured through Alertmanager for proactive issue resolution.

9. Responsible AI & Safety

Bias Analysis

  • Training data audit: Conduct comprehensive analysis of user demographics, geographic distribution, and historical conversion patterns to identify potential systematic biases in the training data.
  • Slice-based fairness evaluation: Evaluate model performance across user segments (age groups, gender, geographic regions) to detect and address disparities in conversion prediction accuracy.
  • Disparate impact analysis: Implement statistical tests (e.g., demographic parity, equalized odds) to ensure the model doesn't systematically favor or disadvantage specific user groups.

Fairness Metrics and Constraints

  • Primary fairness metric: Demographic parity (equalized conversion probability across user segments)
  • Secondary metrics: Equalized odds, calibration across slices
  • Decision rationale: Demographic parity is chosen as the primary constraint because it ensures that users from different demographic groups have equal opportunity to be predicted as converters, which is critical for maintaining equitable user experience and avoiding discriminatory outcomes in ad targeting or product recommendations.

Explainability Requirements and Approach

  • SHAP values: Implement SHAP-based feature importance analysis to understand which user attributes drive conversion predictions for individual users.
  • Attention visualization: For transformer-based models, provide attention weight visualizations to show which user history or item features were most influential in the prediction.
  • Local explainability: For high-stakes decisions (e.g., ad spend allocation), provide human-readable explanations for individual predictions to enable business review and adjustment.

For LLM systems (if applicable):

  • Content filtering: Implement content safety filters to prevent harmful or inappropriate recommendations that could lead to user churn or brand damage.
  • Output validation: Validate predicted conversion likelihood against business logic (e.g., ensuring probabilities are within [0,1] and align with historical conversion rates).
  • Rate limiting: Implement rate limits on high-volume prediction requests to prevent abuse and ensure system stability.
  • Red teaming: Regularly test the model with adversarial examples to identify potential safety gaps and bias amplification.

Model Card Documentation Plan

  • Key components: Model architecture, training data sources, performance metrics, fairness assessment, limitations, usage guidelines, and version history.
  • Distribution: Make model cards available in the internal ML model registry and accessible through the feature store UI.
  • Update frequency: Update model cards with each major model release or when significant changes in performance/fairness are detected.

Incident Response Plan for Model Failures or Harmful Outputs

  • Detection thresholds: Alert when conversion prediction accuracy drops below 90% of baseline or when fairness metrics exceed predefined thresholds (e.g., >5% difference in conversion rate prediction between demographic groups).
  • Fallback strategy: Implement rule-based fallback for low-confidence predictions or when model drift is detected.
  • Human review escalation: Route predictions with confidence scores below 0.3 or fairness violations to human review queue.
  • Rollback procedure: Maintain versioned model artifacts and enable rapid rollback to previous stable versions if safety issues are detected in production.
  • Communication protocol: Notify relevant stakeholders (product, ML, compliance) within 2 hours of incident detection and provide status updates every 4 hours until resolution.
# Example SHAP-based explanation for conversion prediction model
import shap
import numpy as np

class ConversionPredictionExplainability:
    def __init__(self, model):
        self.model = model
        self.explainer = shap.Explainer(model)
    
    def explain_prediction(self, user_features):
        """Generate SHAP explanation for a single prediction"""
        shap_values = self.explainer(user_features)
        
        # Get feature importance scores
        feature_importance = np.abs(shap_values.values).mean(axis=0)
        
        # Create explanation dictionary
        explanation = {
            "feature_names": self.get_feature_names(),
            "importance_scores": feature_importance,
            "top_features": self.get_top_features(feature_importance),
            "prediction_confidence": self.get_prediction_confidence(user_features)
        }
        
        return explanation
    
    def get_top_features(self, importance_scores, top_k=5):
        """Get top K most important features"""
        top_indices = np.argsort(importance_scores)[-top_k:][::-1]
        return [(self.feature_names[i], importance_scores[i]) 
                for i in top_indices]

# Example usage:
# explainer = ConversionPredictionExplainability(model)
# explanation = explainer.explain_prediction(user_features)

Bias Mitigation Strategy

  • Adaptive reweighting: Apply class balancing techniques that adjust for demographic distribution in training data.
  • Fairness-aware regularization: Add fairness constraints to the model loss function during training to penalize disparate treatment across user groups.
  • Regular fairness audits: Schedule monthly reviews of model performance across slices to detect and correct emerging biases.

Safety Guardrails Implementation

  • Prediction confidence thresholds: Set minimum confidence levels (e.g., >0.7) for production use.
  • Conversion probability bounds: Ensure predicted conversion probabilities remain within realistic ranges (0.01 to 0.99) to prevent extreme predictions.
  • Cross-validation for bias detection: Use temporal cross-validation to detect if model performance varies significantly across different time periods or user segments.

10. Scalability & Reliability

Bottleneck Analysis per Pipeline Stage

Training Pipeline:

  • Data ingestion: 100GB/day → 10TB/month → 300GB/hour peak processing
  • Feature computation: 50M users × 100 features = 5B feature values per batch
  • Model training: 1M samples × 100 features = 100M parameters, 20GB model size
  • Back-of-envelope: 500ms inference per sample → 1M samples = 8.3 minutes total

Serving Pipeline:

  • QPS target: 10,000 requests/sec
  • Latency budget: 200ms total (retrieval: 50ms, scoring: 100ms, re-ranking: 50ms)
  • Memory footprint: 20GB embedding matrix + 10GB model cache
  • Cache hit ratio target: 95% for embeddings, 85% for predictions

Scale-up Strategy

Horizontal Scaling:

  • Serving: Deploy 100 model instances across 10 regions with auto-scaling
  • Feature computation: Use Ray or Dask for distributed feature extraction
  • Training: Implement data parallelism across 16 GPUs with model parallelism for large models

Cross-region Serving:

  • Primary region (US-West) handles 60% of traffic, secondary (EU) handles 40%
  • Failover mechanism with 500ms graceful degradation
  • Regional model replicas with sync every 15 minutes

Fault Tolerance

Model Serving Fallbacks:

  • Primary model failure → fallback to last known good version (15s grace period)
  • Cache miss → fallback to batch processing with 200ms latency penalty
  • Feature store unavailability → use default feature values for 5min window

Stale Model Handling:

  • Model version monitoring with automatic rollback to previous stable version
  • 5-minute model freshness window with alerting for >10min staleness
  • Graceful degradation to rule-based system when model fails

Cold Start Handling Strategy

New User Strategy:

  • Default to popular item ranking with 80% confidence
  • Use demographic features for initial ranking (age, location, device)
  • Fallback to content-based filtering with 10% confidence boost

New Item Strategy:

  • Default to trending items in same category
  • Use item metadata embeddings for similarity matching (cosine similarity)
  • Fallback to random selection with 5% confidence

Multi-region Serving Strategy

Traffic Distribution:

  • US-West (primary): 60% of traffic, 100ms p99 latency target
  • EU-East (secondary): 30% of traffic, 150ms p99 latency target
  • Asia-Pacific: 10% of traffic, 200ms p99 latency target

Model Synchronization:

  • Model versioning with 24-hour lag for cross-region sync
  • Incremental model updates via Kafka streams
  • Regional A/B testing with 10% traffic split per region

Failover Mechanism:

  • 500ms automatic failover to secondary region on primary failure
  • Health check every 30 seconds with 3x retry logic
  • Graceful degradation to default ranking when region unavailable

Latency Budget Allocation:

Stagep50p99Budget
Feature Retrieval20ms50ms50ms
Model Inference50ms100ms100ms
Re-ranking10ms30ms30ms
Response Building5ms15ms15ms
Total85ms195ms200ms

Capacity Planning:

  • Peak QPS: 15,000 requests/sec (with 50% headroom)
  • Model instances: 150 total across regions (100 primary, 30 secondary, 20 backup)
  • Memory: 25GB per instance (embedding + model cache)
  • Network bandwidth: 10Gbps per region for cross-region sync

11. Open Questions, Risks & Trade-offs

Decisions requiring product / engineering / policy alignment

  • User consent and data collection boundaries - What level of user behavior tracking is permissible for conversion prediction? This affects feature set and data quality.
  • Cross-platform user identification - Should we treat users across platforms as the same entity for conversion prediction? Impacts feature engineering and model training strategy.
  • Conversion definition granularity - Should we predict micro-conversions (e.g., add to cart) or macro-conversions (e.g., purchase)? Affects model task definition and evaluation metrics.
  • Real-time vs batch processing trade-off - How much latency can we tolerate for real-time conversion predictions in the user journey? Impacts serving architecture and feature freshness requirements.
  • Model retraining cadence alignment - How frequently should we retrain models based on business cycles and data freshness? Affects training pipeline design and monitoring strategy.

Key ML risks

RiskImpactLikelihoodMitigation
Data drift in user behavior patternsHigh - Model performance degradationMedium - Seasonal trends, new product launchesImplement continuous drift monitoring, scheduled retraining
Class imbalance in conversion eventsHigh - Poor recall for rare conversionsHigh - Conversion rates typically < 5%Implement stratified sampling, weighted loss functions
Cold start problem for new users/itemsMedium - Reduced prediction qualityHigh - New user/item onboardingImplement hybrid rule-based + ML approach
Feedback loop contaminationMedium - Model bias from predictions affecting behaviorMedium - Prediction-driven user experience changesImplement shadow mode, A/B testing for prediction impact
Latency spikes in servingHigh - User experience degradationMedium - System scaling issuesImplement prediction caching, auto-scaling, circuit breaker patterns

Trade-offs made with justification

Trade-offJustification
Accuracy vs. latency - Prioritize low-latency serving over marginal accuracy gainsConversion prediction must be sub-100ms for real-time personalization, with 50ms p99 target. Sacrificing 2-3% AUC for <50ms response time is acceptable
Freshness vs. cost - Batch feature computation over real-timeReal-time features require complex infrastructure and high cost. Batch features with 1-hour TTL provide >90% accuracy for most use cases
Model size vs. quality - Use model distillation over large transformer modelsProduction constraints limit model size to <50MB. Distilled models achieve 95% of full model performance with 80% size reduction
Online vs. batch serving - Hybrid approach with batch for cold startOnline serving for active users, batch for new users or when real-time features unavailable. Reduces complexity and cost
Feature richness vs. model interpretability - Prioritize model explainability over feature engineeringBusiness stakeholders require model explanations for trust and compliance. Simpler models with fewer features provide better interpretability

Alternatives considered and rejected

AlternativeReason for rejection
Transformer-based models (e.g., BERT)Too computationally expensive for real-time serving, 5x latency increase over DNN models
Ensemble of complex tree-based modelsHigh model complexity and maintenance overhead, not justified by marginal accuracy gains
Full real-time feature computation pipeline3x infrastructure cost with minimal performance improvement over batch features
Rule-based fallback for all edge casesToo brittle and hard to maintain; ML provides better generalization
Multi-task learning for multiple conversion typesOvercomplicated for initial MVP; single task model provides >90% of value

Technical debt acknowledged

  • Model versioning complexity - Current implementation uses simple timestamp-based versioning instead of comprehensive model registry with rollback capability
  • Feature store maturity - Initial design assumes simple feature lookup; future evolution to full feature store with lineage tracking is needed
  • Offline vs. online feature consistency - Risk of inconsistency between training and serving features due to different preprocessing pipelines
  • Shadow mode limitations - Current shadow testing only logs predictions but doesn't capture actual impact on user behavior for model validation
  • A/B testing infrastructure - Basic randomization unit (user ID) may not capture cross-platform behavior, requiring future expansion to session-based randomization

12. Phased Implementation Roadmap

Phase 1: MVP (Weeks 1-6)

Objective: Establish baseline prediction capability with minimal viable system.

Deliverables:

  • Rule-based fallback system (session-based conversion probability)
  • Basic ML model (logistic regression or GBM) trained on historical data
  • Simple online serving infrastructure (single model endpoint)
  • Basic A/B testing infrastructure

Dependencies:

  • Data pipeline availability
  • Feature store setup (basic)
  • Model registry system

Critical Path:

  1. Data labeling and baseline model training (Weeks 1-2)
  2. Simple model deployment to serving infrastructure (Weeks 3-4)
  3. A/B test setup and initial experiment launch (Weeks 5-6)

Phase 2: Scale (Weeks 7-12)

Objective: Expand system to handle production scale and improve model quality.

Deliverables:

  • Feature store with real-time and batch features
  • Distributed training pipeline (data parallelism)
  • Multi-model ensemble system (candidate retrieval + scoring)
  • Advanced model architectures (DNN, Transformer)
  • Shadow mode A/B testing capability

Dependencies:

  • Feature store maturity
  • Distributed training infrastructure
  • Model versioning and registry

Critical Path:

  1. Feature store implementation (Weeks 7-8)
  2. Distributed training pipeline setup (Weeks 9-10)
  3. Ensemble model system deployment (Weeks 11-12)

Phase 3: Excellence (Weeks 13-18)

Objective: Achieve production-grade system with continuous improvement capabilities.

Deliverables:

  • Real-time feature computation pipeline
  • Online learning system for model updates
  • Advanced monitoring and alerting system
  • Multi-region serving capability
  • Continuous model retraining pipeline with drift detection

Dependencies:

  • Real-time feature infrastructure
  • Model monitoring system maturity
  • Multi-region deployment capability

Critical Path:

  1. Real-time feature pipeline (Weeks 13-14)
  2. Online learning system implementation (Weeks 15-16)
  3. Production monitoring and retraining pipeline (Weeks 17-18)

Risk Mitigation Strategy:

  • Data Quality Risk: Implement data validation at each phase with drift detection
  • Latency Risk: Monitor p99 latency throughout phases, implement caching at each stage
  • Model Performance Risk: Maintain shadow mode A/B testing throughout all phases
  • Scale Risk: Design horizontally scalable components from Phase 1

Success Criteria:

  • Phase 1: 5% improvement over rule-based baseline
  • Phase 2: 15% improvement over Phase 1 baseline with 90%+ model accuracy
  • Phase 3: 25% improvement over Phase 1 baseline with real-time model updates and multi-region support

Resource Allocation:

  • Phase 1: 2 ML Engineers, 1 SRE, 1 Data Engineer
  • Phase 2: 3 ML Engineers, 2 SREs, 2 Data Engineers
  • Phase 3: 4 ML Engineers, 3 SREs, 2 Data Engineers

Rollout Strategy:

  • Phase 1: Internal testing with small user segment
  • Phase 2: Gradual rollout to 10% of users with shadow mode
  • Phase 3: Full production rollout with A/B testing and monitoring

Was this article helpful?

Topics in this article

More from AI/ML System Design

  • AI/ML System Design

    AI-Powered Spam Detection System Architecture

    Comprehensive design document for building scalable spam detection systems using machine learning and real-time processing pipelines.

  • AI/ML System Design

    Large-Scale Logistic Regression Scoring System Design

    Comprehensive system design for scalable logistic regression inference at enterprise scale with distributed computing and real-time scoring capabilities.

  • AI/ML System Design

    Feature Backfill Strategy for ML Systems

    Comprehensive guide to designing robust feature backfill strategies for machine learning pipelines, covering incremental updates, data consistency, and system reliability patterns.

Stay in the Loop

Get curated DSA patterns, coding problems, frontend and backend LLD/HLD, and AI/ML System Design insights delivered straight to your inbox. No spam, just focused interview and engineering content.