Skip to main content

Anomaly Detection System Design: ML Frameworks and Implementation Patterns

Comprehensive guide to designing robust anomaly detection systems with real-time processing, scalable architectures, and production-ready ML pipelines for FAANG-scale applications.

Anomaly detection systems form the backbone of modern ML infrastructure at scale, requiring careful architectural decisions around data pipelines, model selection, and real-time processing capabilities to handle massive volumes of streaming data effectively.

1. Problem Statement & ML Task Definition

Clarifying questions

  1. What types of anomalies are we trying to detect? (e.g., network intrusions, fraud, system failures, data drift)
  2. What is the expected ratio of normal vs anomalous samples in training data? (e.g., 99.9% normal, 0.1% anomalies)
  3. What is the acceptable latency for anomaly detection? (e.g., <100ms for real-time alerts, 5s for batch processing)
  4. Is this primarily an online (real-time) or offline (batch) use case? (e.g., real-time monitoring vs nightly anomaly reports)
  5. What is the desired false positive rate? (e.g., <1% to avoid alert fatigue)
  6. What is the expected scale of data volume and QPS? (e.g., 10M events/day, 100K QPS)
  7. Are there specific user or business success criteria? (e.g., reduce false positives by 50%, increase detection rate by 30%)

Business use case and success criteria

The system detects anomalous network traffic patterns to identify potential security threats or system failures. The primary business goal is to reduce time-to-detection of security incidents by 70% and decrease false positive alerts by 50% compared to current rule-based systems. Success is measured by:

  • Detection Accuracy: Precision and Recall of detected anomalies
  • Alert Response Time: Average time from anomaly detection to incident response
  • False Positive Rate: <1% of legitimate traffic flagged as anomalous
  • Business Impact: Reduction in security incidents and system downtime

ML problem formulation

This is an unsupervised anomaly detection task. The system learns normal behavior patterns from historical data and flags deviations as anomalies. We use a semi-supervised approach where labeled anomaly examples are used to fine-tune unsupervised models, but the majority of training data is unlabeled normal samples.

ML evaluation metrics

Offline Metrics:

  • Precision@K: Top-K ranked anomalies that are actually anomalous
  • Recall@K: Proportion of actual anomalies captured in top-K predictions
  • F1-Score: Harmonic mean of precision and recall
  • AUC-ROC: Overall model discrimination capability

Online Metrics:

  • False Positive Rate: % of legitimate events flagged as anomalies
  • Detection Latency: Time from event arrival to anomaly alert
  • Incident Response Time: Time from alert to incident handling completion

Scale and constraints

Back-of-envelope estimates:

  • Training data size: 100M network flow records (50GB raw, 20GB processed)
  • Number of features: ~500 features (network metadata, flow statistics, protocol headers)
  • Embedding matrix memory: ~50GB for 1M unique entities at 64-dim embeddings
  • Serving QPS math: 10M events/day ÷ 86400 seconds = ~115 QPS (peak), with burst capacity for 10x

Constraints:

  • Latency Budget: <50ms for real-time anomaly detection
  • QPS: 100K QPS peak with 5x burst capacity
  • Freshness: 5-minute window for real-time updates, 1-hour batch retraining
  • Accuracy Target: >95% recall for known anomalies, <1% false positive rate

Non-ML baseline strategy

Rule-based fallback:

  • IP address blacklisting (existing system)
  • Protocol anomaly detection (e.g., unexpected port usage)
  • Traffic volume thresholds (e.g., >10x baseline traffic)

Cold start handling:

  • Default to "normal" classification for new network entities
  • Use historical behavior patterns from similar entities as proxy
  • Implement a "confidence threshold" that requires model certainty before flagging anomalies

2. Data Strategy

Training Data Sources

  • Historical system logs: CPU, memory, network usage, disk I/O patterns from infrastructure monitoring systems (e.g., Prometheus, Datadog)
  • Application telemetry: Error rates, response times, throughput metrics from application performance monitoring (APM) tools like New Relic or AppDynamics
  • Business metrics: User behavior signals (session duration, feature adoption rates) and business KPIs (revenue, conversion rates)
  • Third-party threat intelligence feeds: Known attack signatures, IP reputation data, and threat actor patterns from security vendors (e.g., VirusTotal, ThreatConnect)
  • Synthetic data generation: Simulated anomalous behavior patterns to augment real-world examples and test edge cases

Labeling Pipeline Design

  • Human annotation: For labeled anomalies in high-value system components (critical services, security-sensitive systems) with domain expert review
  • Weak supervision: Using heuristics and rules-based labeling (e.g., "CPU usage > 95% for more than 10 minutes" or "Error rate > 5% in last hour")
  • Programmatic labeling: Automated labeling using statistical thresholds (e.g., Z-score > 3) or ML-based pseudo-labeling from a pre-trained anomaly detector

Class Imbalance Handling Strategy

  • Justification: Anomalies are inherently rare events, making the dataset highly imbalanced (e.g., 1:1000 normal vs. anomalous samples)
  • Approach:
    • Use undersampling of majority class (normal samples) to balance the ratio during training
    • Apply weighted loss functions (e.g., focal loss) to penalize misclassifications of minority class more heavily
    • Implement anomaly-aware sampling where training batches are constructed to contain a balanced mix of normal and anomalous samples

Negative Sampling Approach

  • Strategy:
    • Random negative sampling from normal data points to create balanced training batches
    • Hard negative mining: Select most similar normal samples to anomalous ones for harder training examples
    • Time-aware negative sampling: Sample from recent normal behavior to capture temporal patterns in anomalies

Data Freshness and Update Frequency Requirements

  • Freshness requirement:
    • Real-time monitoring requires data to be updated every 5–10 minutes for system logs and metrics
    • For batch training, daily or hourly updates are acceptable with historical windowed features
  • Update frequency:
    • System logs: every 5 minutes (streaming)
    • Business metrics: hourly
    • Third-party threat feeds: every hour or as updated by vendor

Privacy Compliance (GDPR, CCPA)

  • Anonymization:
    • Remove or hash PII from logs (e.g., user IDs, IP addresses, session tokens)
    • Apply differential privacy techniques to sensitive feature values (e.g., memory usage, CPU time)
  • Data retention:
    • Retain logs for a maximum of 90 days (compliant with GDPR/CCPA)
    • Implement automated log rotation and deletion policies
  • Access control:
    • Role-based access to sensitive logs and training data
    • Audit trail for any data access or modification

Data Quality Validation and Monitoring

  • Validation checks:
    • Missing value detection (e.g., null or zero values in key metrics)
    • Data format validation (ensure numeric fields are indeed numbers, timestamps are valid)
  • Monitoring:
    • Anomaly in feature distributions (e.g., sudden shift in CPU usage distribution)
    • Drift detection using statistical tests (Kolmogorov-Smirnov, Chi-square)
    • Data integrity checks (e.g., monotonicity in timestamps, consistency in log levels)
import numpy as np
from scipy import stats

def detect_drift(data_old, data_new):
    """Detect drift between historical and new data distributions."""
    # Kolmogorov-Smirnov test for distribution shift
    ks_stat, p_value = stats.ks_2samp(data_old, data_new)
    return ks_stat > 0.1 and p_value < 0.05  # Threshold for drift detection

# Example usage:
historical_cpu_usage = np.random.normal(50, 10, 1000)
current_cpu_usage = np.random.normal(60, 15, 1000)
is_drifted = detect_drift(historical_cpu_usage, current_cpu_usage)

3. Feature Engineering

Feature Taxonomy

Features are categorized into four main types:

  1. User Features: User demographics, behavioral patterns, session statistics, historical anomaly counts
  2. Item Features: Item metadata, performance metrics, category characteristics, temporal properties
  3. Context Features: Time-based signals (hour, day of week, seasonality), geographic location, device type, network conditions
  4. Interaction Features: User-item engagement signals, temporal gaps between interactions, sequence patterns, feature co-occurrence

Embedding Design

Entity Embeddings:

  • User ID embeddings (128-dim) trained via collaborative filtering
  • Item ID embeddings (256-dim) using item popularity and engagement patterns
  • Context feature embeddings (64-dim) for categorical variables like device type, region

Text Embeddings:

  • For textual item descriptions or user comments using pre-trained BERT (768-dim)
  • Dimensionality reduced via PCA to 256-dim for efficiency

Graph Embeddings:

  • User-item interaction graph embeddings using Node2Vec (128-dim)
  • Captures user preferences and item similarity patterns

Real-time vs Batch Feature Computation

Feature TypeComputation ModeJustification
User session statsReal-timeRequired for immediate anomaly detection
Historical countsBatchUpdated hourly, can be pre-computed
Temporal patternsReal-timeTime-sensitive features need low latency
Item popularityBatchUpdated daily, can be cached

Feature Store Design

Online Store:

  • Low-latency key-value store (e.g., Redis or DynamoDB)
  • Designed for sub-100ms response times
  • Supports feature lookups during real-time scoring

Offline Store:

  • Data warehouse (e.g., Snowflake or BigQuery)
  • Used for model training and batch feature generation
  • Supports complex aggregations and historical analysis

Feature Freshness and TTL

FeatureSourceUpdate FrequencyStore TypeTTL
User session countReal-time streamEvery 5 minutesOnline1 hour
Item engagement rateBatch ETLDailyOffline30 days
Time-based signalsSystem clockEvery hourOnline1 day
User-item interaction countReal-time streamEvery minuteOnline6 hours

Cross Features and Feature Interactions

Cross features are engineered to capture complex patterns:

  • User-item interaction frequency × time since last interaction
  • Item popularity × user session duration
  • Context-aware engagement ratios (e.g., mobile vs desktop engagement ratio)

Feature Importance and Selection

Methodology:

  • SHAP values for global feature importance analysis
  • Permutation importance during training for online validation
  • Recursive Feature Elimination (RFE) with cross-validation

Selection Strategy:

  • Top 200 features retained for model training
  • Features with SHAP importance < 0.01 removed to reduce noise
  • Online A/B testing validates feature impact on anomaly detection performance
# Feature engineering pipeline example for anomaly detection
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler

class AnomalyFeatureEngineer:
    def __init__(self):
        self.scaler = StandardScaler()
        
    def compute_user_session_features(self, user_data):
        """Compute real-time session-based features"""
        # Session duration in minutes
        session_duration = user_data['session_end_time'] - user_data['session_start_time']
        user_data['session_duration_minutes'] = session_duration.dt.total_seconds() / 60
        
        # Number of actions per session
        user_data['actions_per_session'] = user_data.groupby('user_id')['action_id'].transform('count')
        
        # Time since last session (in hours)
        user_data['time_since_last_session_hours'] = (
            pd.Timestamp.now() - user_data.groupby('user_id')['session_start_time'].transform('max')
        ).dt.total_seconds() / 3600
        
        return user_data
    
    def compute_item_features(self, item_data):
        """Compute item-level features"""
        # Item popularity score (based on historical engagement)
        item_data['popularity_score'] = (
            item_data.groupby('item_id')['user_id'].transform('count') / 
            item_data['total_users']
        )
        
        # Engagement rate (actions per user)
        item_data['engagement_rate'] = (
            item_data.groupby('item_id')['action_id'].transform('count') / 
            item_data['unique_users']
        )
        
        return item_data
    
    def compute_context_features(self, context_data):
        """Compute time-based and contextual features"""
        # Time-based features
        context_data['hour_of_day'] = pd.to_datetime(context_data['timestamp']).dt.hour
        context_data['day_of_week'] = pd.to_datetime(context_data['timestamp']).dt.dayofweek
        context_data['is_weekend'] = context_data['day_of_week'].isin([5, 6]).astype(int)
        
        # Geographic features (if available)
        context_data['region_engagement'] = (
            context_data.groupby('region')['user_id'].transform('count') / 
            context_data['total_users']
        )
        
        return context_data
    
    def compute_cross_features(self, df):
        """Compute interaction and cross features"""
        # User-item engagement ratio
        df['user_item_engagement_ratio'] = (
            df.groupby(['user_id', 'item_id'])['action_id'].transform('count') / 
            df.groupby('user_id')['action_id'].transform('count')
        )
        
        # Time-based engagement patterns
        df['engagement_window_1h'] = (
            df.groupby('user_id')['timestamp'].diff().dt.total_seconds() / 3600
        )
        
        return df
    
    def engineer_features(self, raw_data):
        """Main feature engineering pipeline"""
        # Apply transformations
        engineered_data = self.compute_user_session_features(raw_data.copy())
        engineered_data = self.compute_item_features(engineered_data)
        engineered_data = self.compute_context_features(engineered_data)
        engineered_data = self.compute_cross_features(engineered_data)
        
        # Normalize numerical features
        numeric_features = ['session_duration_minutes', 'actions_per_session', 
                           'popularity_score', 'engagement_rate']
        engineered_data[numeric_features] = self.scaler.fit_transform(
            engineered_data[numeric_features]
        )
        
        return engineered_data

4. Model Architecture

Model Selection with Justification

For anomaly detection in a large-scale system, I'll select a Variational Autoencoder (VAE) as the primary model architecture. This choice balances several critical requirements:

  1. Unsupervised learning: Anomaly detection typically lacks labeled data, making unsupervised methods ideal
  2. Reconstruction-based detection: VAEs naturally detect anomalies through reconstruction error - anomalous samples will have higher reconstruction loss
  3. Probabilistic foundation: Provides uncertainty quantification for anomaly confidence scores
  4. Scalable training: VAEs can be efficiently trained with distributed computing frameworks

Alternative architectures considered:

  • Isolation Forest: Good for high-dimensional sparse data but struggles with complex feature interactions
  • One-Class SVM: Effective but computationally expensive for large-scale systems
  • Autoencoders: Simpler than VAEs but lack probabilistic guarantees

Architecture Diagram

graph TD
    A[Input Features] --> B[Encoder Network]
    B --> C[Latent Space (z)]
    C --> D[Decoder Network]
    D --> E[Reconstructed Features]
    A --> F[Reconstruction Loss]
    E --> F
    F --> G[Anomaly Score]

Two-Tower / Multi-Task / Ensemble Design

For production systems, I recommend a two-tower ensemble approach:

  • Tower 1: VAE for reconstruction-based anomaly detection
  • Tower 2: Isolation Forest for statistical anomaly detection
  • Ensemble: Weighted combination with dynamic weights based on recent performance

Pre-trained Model Selection and Fine-tuning Strategy

For systems with limited historical data, I'd consider:

  1. Pre-trained VAE: Use a pre-trained model on similar domains (e.g., network traffic patterns)
  2. Fine-tuning: Adapt to target domain with few labeled anomalies
  3. Transfer learning: Leverage pre-trained embeddings for feature representation

Model Complexity vs Latency Trade-off Analysis

ModelMetricLatency (ms)Size (MB)
VAE (small)Reconstruction Loss5-1025
VAE (medium)Reconstruction Loss10-20150
Isolation ForestStatistical Score1-550
Ensemble (2-tower)Combined Score15-30200

Offline Evaluation Baseline Framing

Baseline expectations:

  • Random classifier: ~50% AUC for binary anomaly classification
  • Isolation Forest: ~85-90% AUC on standard benchmarks (KDD Cup, NSL-KDD)
  • VAE: ~90-95% AUC on similar datasets with proper tuning

Core Model Code Snippet

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

class VariationalAutoencoder(nn.Module):
    def __init__(self, input_dim=1000, hidden_dim=512, latent_dim=64):
        super(VariationalAutoencoder, self).__init__()
        
        # Encoder
        self.encoder = nn.Sequential(
            nn.Linear(input_dim, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, hidden_dim // 2),
            nn.ReLU()
        )
        
        # Latent space parameters
        self.fc_mu = nn.Linear(hidden_dim // 2, latent_dim)
        self.fc_var = nn.Linear(hidden_dim // 2, latent_dim)
        
        # Decoder
        self.decoder = nn.Sequential(
            nn.Linear(latent_dim, hidden_dim // 2),
            nn.ReLU(),
            nn.Linear(hidden_dim // 2, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, input_dim),
            nn.Sigmoid()
        )
    
    def encode(self, x):
        h = self.encoder(x)
        mu = self.fc_mu(h)
        log_var = self.fc_var(h)
        return mu, log_var
    
    def reparameterize(self, mu, log_var):
        std = torch.exp(0.5 * log_var)
        eps = torch.randn_like(std)
        return mu + eps * std
    
    def decode(self, z):
        return self.decoder(z)
    
    def forward(self, x):
        mu, log_var = self.encode(x)
        z = self.reparameterize(mu, log_var)
        reconstructed = self.decode(z)
        
        # KL divergence loss
        kl_loss = -0.5 * torch.sum(1 + log_var - mu.pow(2) - log_var.exp())
        
        # Reconstruction loss
        recon_loss = F.mse_loss(reconstructed, x, reduction='none').sum(1)
        
        return reconstructed, kl_loss, recon_loss
    
    def anomaly_score(self, x):
        """Calculate anomaly score based on reconstruction error"""
        reconstructed, kl_loss, recon_loss = self.forward(x)
        # Normalize reconstruction loss by input dimensionality
        anomaly_score = recon_loss / x.shape[1]
        return anomaly_score

# Example usage for inference
def calculate_anomaly_score(model, input_features):
    model.eval()
    with torch.no_grad():
        reconstructed, kl_loss, recon_loss = model(input_features)
        anomaly_score = recon_loss / input_features.shape[1]
    return anomaly_score

# Example training step
def train_step(model, data_loader, optimizer, device):
    model.train()
    total_loss = 0
    for batch in data_loader:
        batch = batch.to(device)
        reconstructed, kl_loss, recon_loss = model(batch)
        
        # Combined loss
        loss = recon_loss.mean() + 0.01 * kl_loss.mean()
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        total_loss += loss.item()
    
    return total_loss / len(data_loader)

This implementation provides a production-ready VAE architecture with:

  • Complete forward pass including reconstruction and KL loss
  • Anomaly scoring logic based on normalized reconstruction error
  • Training step with proper loss combination
  • Memory-efficient batch processing
  • GPU-ready tensor operations
  • Scalable architecture with configurable dimensions

5. Serving & Inference Architecture

System Diagram

graph TD
    A[User Request] --> B[Load Balancer]
    B --> C[Anomaly Detection Service]
    C --> D{Online/Offline}
    D -->|Online| E[Feature Store]
    D -->|Offline| F[Batch Feature Store]
    E --> G[Embedding Cache]
    G --> H[Model Serving]
    F --> I[Model Training]
    H --> J[Anomaly Score]
    J --> K[Alert/Action]
    
    subgraph "Real-time Inference"
        C
        E
        G
        H
        J
        K
    end
    
    subgraph "Batch Processing"
        I
    end

Online vs Batch Serving Decision

For anomaly detection systems, we prioritize online serving due to:

  • Real-time alerting requirements (latency < 100ms for critical systems)
  • Immediate response to suspicious behavior patterns
  • User experience impact (e.g., fraud detection in payment systems)
  • Business SLA compliance (e.g., 99.9% availability for fraud detection)

Two-Stage Pipeline

1. Candidate Filtering → 2. Anomaly Scoring → 3. Alert Generation

Stage 1: Candidate Filtering

  • Filter based on feature thresholds or pre-defined rules
  • Reduce inference load by eliminating clearly normal cases

Stage 2: Anomaly Scoring

  • Apply trained model to filtered candidates
  • Compute anomaly probability/score

Stage 3: Alert Generation

  • Threshold-based alerting (e.g., score > 0.9)
  • Integration with alerting systems (Slack, email, SMS)

Serving Infrastructure

We use TorchServe for model serving with the following configuration:

  • Model format: ONNX or TorchScript
  • GPU acceleration for faster inference (if available)
  • Containerized deployment with Kubernetes orchestration
  • Auto-scaling based on QPS and latency metrics

Latency Budget Breakdown

Stagep50 Latencyp99 LatencyBudget
Feature Retrieval5ms15ms20ms
Model Inference10ms30ms40ms
Alert Generation2ms5ms10ms
Total17ms55ms70ms

Model Compression Strategy

For latency-sensitive deployments:

  1. Quantization: INT8 quantization reduces model size by 4x with <5% accuracy loss
  2. Pruning: Remove 30-50% of weights with minimal impact on AUC
  3. Knowledge Distillation: Train smaller student model from larger teacher model

Caching Strategy

Prediction Cache:

  • Cache recent anomaly scores for same inputs (TTL: 5 minutes)
  • Reduce redundant model calls for repeated patterns

Embedding Cache:

  • Store user/item embeddings in Redis or Memcached
  • Reduce feature computation overhead for frequent queries

Auto-scaling and Capacity Planning

Horizontal Scaling:

  • Scale inference instances based on QPS (target: 1000 QPS per instance)
  • Use Kubernetes HPA with CPU/memory utilization and latency metrics

Capacity Planning:

Back-of-envelope estimate:
- Target QPS: 50,000 requests/sec
- Model inference time: 20ms (p50)
- Required instances: 50,000 * 0.02 = 1,000 instances
- With 20% overhead for safety: ~1,200 instances

Cold Start Handling

  • New User/Item Detection:
    • Use default anomaly score (e.g., 0.1) for new entities
    • Flag as "unseen" in monitoring system
  • Fallback Strategy:
    • Default to rule-based anomaly detection for unknown entities
    • Gradually transition to ML model once sufficient training data is collected

Multi-region Serving Strategy

  • Deploy in multiple regions for low-latency global access
  • Use consistent model versions across regions
  • Implement region-specific anomaly thresholds based on regional behavior patterns

6. Evaluation Framework

Offline Evaluation Methodology

For anomaly detection, we use a holdout-based approach with temporal splits to ensure that the model is evaluated on unseen future data. This prevents data leakage and simulates real-world deployment conditions where anomalies are detected in real-time as they occur. We split the data chronologically into 70% training, 15% validation, and 15% test sets. For temporal consistency, we use a time-based window approach where training data is from the earliest period and test data from the most recent period.

Cross-validation is not suitable for anomaly detection due to temporal dependencies and the rare nature of anomalies. Instead, we use stratified sampling on normal vs anomalous instances within each temporal split to maintain balanced representation.

Slice-Based Evaluation

We define critical slices for comprehensive evaluation:

SliceDefinitionJustification
Time-basedHourly, daily, weekly patternsDetect temporal drift in anomaly patterns
User segmentsNew vs returning users, high-activity vs low-activityEvaluate model robustness across user behaviors
Device typesMobile, desktop, tabletEnsure consistent performance across platforms
Geographic regionsCountry/region clustersDetect regional anomaly pattern variations
Feature groupsHigh cardinality vs low cardinality featuresAssess model sensitivity to feature complexity

A/B Test Design

Randomization Unit: Individual user sessions or transactions (not users to avoid session bias)

Sample Size Calculation:

  • Target: 5% increase in anomaly detection accuracy
  • Power: 80%
  • Significance level: 5%
  • Estimated baseline detection rate: 2% (100 anomalies out of 5000 samples)
  • Required sample size: ~25,000 sessions per variant

Test Duration: 30 days to capture seasonal patterns and ensure statistical significance

Primary Metric:

  • F1-Score (precision + recall harmonic mean) for anomaly detection
  • False Positive Rate (FPR) reduction as secondary metric

Guardrail Metrics:

  • Precision drop below 0.85
  • Recall drop below 0.60
  • False positive rate increase >15%
  • Model latency >200ms p99

Shadow Mode Rollout Plan

  1. Phase 1 (Week 1): Run both baseline and new model in shadow mode with identical data
  2. Phase 2 (Week 2): Compare predictions and calculate shadow performance metrics
  3. Phase 3 (Week 3): Validate that shadow model's predictions align with actual anomaly rates
  4. Phase 4 (Week 4): Gradually increase shadow model's prediction weight to 50%
  5. Phase 5 (Week 5): Full production rollout with model monitoring in place

Long-term Metric Measurement

We track delayed conversion and engagement decay metrics to ensure the model's impact extends beyond immediate anomaly detection:

MetricDefinitionTarget
Delayed Conversion Rate% of anomalous events that trigger delayed conversions (e.g., fraud recovery)>85%
Engagement Decay% of users who continue engaging after anomaly detection<5% drop
False Positive Impact% of false positives that cause user churn or friction<1%
Anomaly Recovery Rate% of detected anomalies that are successfully mitigated>90%
Model Confidence DistributionDistribution of prediction confidence scores over timeStable distribution

Offline Evaluation Baseline

We establish a baseline using:

  1. Statistical methods: Isolation Forest, One-Class SVM, Autoencoders
  2. Rule-based systems: Threshold-based anomaly detection using domain knowledge
  3. Simple ML models: Logistic regression with engineered features

Expected baseline performance:

  • F1-Score: ~0.65
  • Precision: ~0.70
  • Recall: ~0.60

Proposed model should achieve:

  • F1-Score: >0.80
  • Precision: >0.85
  • Recall: >0.75

Model Performance Metrics Table

MetricBaseline TargetProposed TargetAcceptance Criteria
F1-Score0.65>0.80≥0.75 to pass
Precision0.70>0.85≥0.80 to pass
Recall0.60>0.75≥0.70 to pass
AUC-ROC0.85>0.92≥0.90 to pass
FPR0.15<0.05≤0.08 to pass
Detection Latency200ms<100ms≤150ms to pass

Risk Mitigation for Evaluation

We implement a multi-layered approach:

  1. Cross-validation on normal data only to prevent overfitting to anomalies
  2. Temporal holdout validation to ensure model generalizes to future data
  3. Human-in-the-loop review of top 100 anomalies per week for quality assessment
  4. Adversarial testing with synthetic anomaly data to stress-test model robustness

The evaluation framework balances statistical rigor with practical deployment considerations, ensuring that the model not only performs well in offline metrics but also delivers meaningful improvements in real-world anomaly detection scenarios.

7. Training Pipeline

Training Data Pipeline

The training pipeline follows a multi-stage ETL process:

  1. Data Ingestion: Raw telemetry data from monitoring systems (e.g., Prometheus, Grafana) flows through Kafka streams with 5-minute batch intervals
  2. Preprocessing:
    • Feature normalization using min-max scaling with global statistics computed from historical data
    • Missing value imputation using median values per feature
    • Outlier detection and capping using IQR method (1.5 × IQR)
  3. Shuffling: Data is shuffled using reservoir sampling to ensure temporal distribution uniformity
  4. Batching: Training batches are created with 1024 samples per batch, with 8 GPUs for distributed training
import torch
from torch.utils.data import Dataset, DataLoader
import pandas as pd
import numpy as np

class AnomalyDetectionDataset(Dataset):
    def __init__(self, features_df, labels=None, normalize=True):
        self.features = features_df.values.astype(np.float32)
        self.labels = labels if labels is not None else np.zeros(len(features_df))
        
        # Normalize features using global statistics
        if normalize:
            self.feature_means = np.mean(self.features, axis=0)
            self.feature_stds = np.std(self.features, axis=0) + 1e-8
            self.features = (self.features - self.feature_means) / self.feature_stds
    
    def __len__(self):
        return len(self.features)
    
    def __getitem__(self, idx):
        return torch.tensor(self.features[idx]), torch.tensor(self.labels[idx], dtype=torch.float32)

# Data loading with shuffling and batching
def create_training_dataloader(features_df, labels, batch_size=1024, shuffle=True):
    dataset = AnomalyDetectionDataset(features_df, labels)
    return DataLoader(dataset, batch_size=batch_size, shuffle=shuffle, num_workers=4)

Distributed Training Strategy

  • Data Parallelism: Using PyTorch's DistributedDataParallel (DDP) across 8 GPUs for efficient training
  • Model Parallelism: Not applicable for this use case as models are relatively small (10M parameters max)
  • Gradient Accumulation: 4 steps of accumulation to simulate larger batch sizes (effective batch size = 4096)
  • Training Duration: Expected training time of 2 hours for 1M samples with 8 GPUs

Training Infrastructure

  • Compute Cluster: 2x8-GPU A100 nodes (16 GPUs total) with 128GB RAM each
  • Storage: NVMe SSD storage for fast data access (500GB total)
  • Training Time Estimate:
    • 1M samples with 100 features → ~2 hours training
    • Batch size: 1024 samples per GPU
    • Effective batch size: 8,192 samples

Hyperparameter Tuning Approach

  • Search Strategy: Bayesian Optimization using Optuna with 50 trials
  • Key Hyperparameters:
    • Learning rate: [1e-4, 1e-2] (log scale)
    • Batch size: [512, 2048]
    • Dropout rate: [0.1, 0.5]
    • Reconstruction loss weight: [0.1, 1.0]

Experiment Tracking and Reproducibility

  • Tool: MLflow for experiment tracking, version control, and model registry
  • Logging: Metrics (AUC, F1-score, precision) logged per epoch
  • Versioning: Model checkpoints saved with timestamp and hyperparameters
  • Reproducibility: Fixed random seeds (42) for all components

Model Versioning and Registry Strategy

  • Registry: MLflow model registry with version control
  • Tagging: Models tagged by performance metrics (AUC > 0.95, F1 > 0.85)
  • Rollback: Automatic rollback to previous version if performance drops by >5%

Continual / Online Learning Design

  • Online Update Frequency: Every 24 hours or when drift detected (PSI > 0.1)
  • Incremental Learning: Implementing online learning with Adam optimizer using small batches (256 samples)
  • Model Refresh: Full model retraining every 30 days or when drift exceeds thresholds
  • Feedback Loop: Anomaly labels from human review are used to retrain model with 10% new data
import optuna
from sklearn.metrics import roc_auc_score, f1_score

def objective(trial):
    # Hyperparameter search space
    lr = trial.suggest_float('lr', 1e-4, 1e-2, log=True)
    batch_size = trial.suggest_categorical('batch_size', [512, 1024, 2048])
    dropout_rate = trial.suggest_float('dropout_rate', 0.1, 0.5)
    
    # Model training logic here
    model = AutoEncoder(input_dim=100, hidden_dim=64, dropout_rate=dropout_rate)
    optimizer = torch.optim.Adam(model.parameters(), lr=lr)
    
    # Training loop
    for epoch in range(10):
        for batch_features, _ in train_loader:
            optimizer.zero_grad()
            recon_batch, _ = model(batch_features)
            loss = reconstruction_loss(recon_batch, batch_features)
            loss.backward()
            optimizer.step()
    
    # Evaluate and return metric for optimization
    y_pred = model.predict(test_features)
    auc_score = roc_auc_score(test_labels, y_pred)
    
    return auc_score

8. Monitoring & Observability

Data Drift Detection

Data drift detection is critical for anomaly detection systems to maintain performance over time. We implement drift detection using Population Stability Index (PSI) for categorical features and Kolmogorov-Smirnov (KS) test for continuous features.

import numpy as np
from scipy import stats
from sklearn.metrics import roc_auc_score

def calculate_psi(expected, actual, bins=10):
    """Calculate PSI between expected and actual distributions"""
    # Ensure both arrays have same binning
    _, bin_edges = np.histogram(expected, bins=bins)
    
    # Count occurrences in each bin
    expected_counts, _ = np.histogram(expected, bins=bin_edges)
    actual_counts, _ = np.histogram(actual, bins=bin_edges)
    
    # Avoid zero division
    expected_counts = np.where(expected_counts == 0, 1e-6, expected_counts)
    actual_counts = np.where(actual_counts == 0, 1e-6, actual_counts)
    
    psi = np.sum((actual_counts - expected_counts) * 
                 np.log(actual_counts / expected_counts))
    return psi

def detect_drift_continuous(feature_values, reference_values, threshold=0.1):
    """Detect drift in continuous features using KS test"""
    ks_stat, p_value = stats.ks_2samp(reference_values, feature_values)
    return ks_stat > threshold

def detect_drift_categorical(feature_values, reference_values, threshold=0.1):
    """Detect drift in categorical features using PSI"""
    psi = calculate_psi(reference_values, feature_values)
    return psi > threshold

Prediction Drift and Label Drift Monitoring

Prediction drift monitors shifts in model predictions, while label drift tracks changes in actual labels that may indicate data distribution shifts.

class DriftMonitor:
    def __init__(self, drift_threshold=0.1):
        self.drift_threshold = drift_threshold
        self.reference_predictions = []
        self.reference_labels = []
        
    def update_reference_data(self, predictions, labels):
        """Update reference distribution for drift monitoring"""
        self.reference_predictions = predictions
        self.reference_labels = labels
        
    def detect_prediction_drift(self, current_predictions):
        """Detect drift in model predictions"""
        if len(self.reference_predictions) == 0:
            return False
            
        # Compare prediction distributions using KS test
        ks_stat, _ = stats.ks_2samp(
            self.reference_predictions, 
            current_predictions
        )
        return ks_stat > self.drift_threshold
        
    def detect_label_drift(self, current_labels):
        """Detect drift in actual labels"""
        if len(self.reference_labels) == 0:
            return False
            
        # For binary classification, check class distribution drift
        ref_pos = np.mean(self.reference_labels)
        current_pos = np.mean(current_labels)
        
        # Use chi-square test for distribution change
        expected_counts = [len(self.reference_labels) * ref_pos,
                          len(self.reference_labels) * (1 - ref_pos)]
        actual_counts = [len(current_labels) * current_pos,
                         len(current_labels) * (1 - current_pos)]
        
        chi2_stat, _, _, _ = stats.chi2_contingency(
            [expected_counts, actual_counts]
        )
        
        return chi2_stat > 3.84  # 95% confidence threshold for df=1

Model Performance Degradation Alerting

Performance degradation is monitored using AUC-ROC, F1-score, and precision-recall curves with configurable thresholds.

class PerformanceMonitor:
    def __init__(self, alert_thresholds):
        self.alert_thresholds = alert_thresholds
        self.performance_history = []
        
    def evaluate_performance(self, y_true, y_pred_proba, y_pred=None):
        """Evaluate model performance metrics"""
        if y_pred is None:
            y_pred = (y_pred_proba > 0.5).astype(int)
            
        auc_roc = roc_auc_score(y_true, y_pred_proba)
        
        # Calculate F1 score for anomaly detection
        f1_score = 2 * (np.sum(y_true * y_pred) / 
                       (np.sum(y_true) + np.sum(y_pred)))
        
        return {
            'auc_roc': auc_roc,
            'f1_score': f1_score,
            'precision': np.sum(y_true * y_pred) / (np.sum(y_pred) + 1e-8),
            'recall': np.sum(y_true * y_pred) / (np.sum(y_true) + 1e-8)
        }
        
    def check_performance_degradation(self, current_metrics):
        """Check if performance has degraded below thresholds"""
        degradation_alerts = []
        
        for metric_name, threshold in self.alert_thresholds.items():
            if current_metrics[metric_name] < threshold:
                degradation_alerts.append({
                    'metric': metric_name,
                    'current_value': current_metrics[metric_name],
                    'threshold': threshold
                })
                
        return degradation_alerts

Retraining Trigger Strategy

Retraining is triggered based on drift detection, performance degradation, and scheduled intervals to ensure model freshness.

class RetrainingTrigger:
    def __init__(self, drift_threshold=0.1, performance_threshold=0.85,
                 retrain_interval_days=30):
        self.drift_threshold = drift_threshold
        self.performance_threshold = performance_threshold
        self.retrain_interval_days = retrain_interval_days
        self.last_retrain_date = None
        
    def should_retrain(self, drift_detected=False, performance_degraded=False,
                       days_since_last_retrain=0):
        """Determine if model should be retrained"""
        
        # Trigger retraining if drift is detected
        if drift_detected:
            return True
            
        # Trigger retraining if performance degrades significantly
        if performance_degraded:
            return True
            
        # Trigger retraining on scheduled intervals
        if days_since_last_retrain >= self.retrain_interval_days:
            return True
            
        return False

Logging Design

Comprehensive logging includes prediction logs, feature logs, and label collection pipeline for model improvement.

import json
import logging
from datetime import datetime

class PredictionLogger:
    def __init__(self, log_file_path):
        self.logger = logging.getLogger('anomaly_detection')
        self.logger.setLevel(logging.INFO)
        
        # Setup file handler
        file_handler = logging.FileHandler(log_file_path)
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
        )
        file_handler.setFormatter(formatter)
        self.logger.addHandler(file_handler)
        
    def log_prediction(self, prediction_data):
        """Log prediction data for monitoring"""
        log_entry = {
            'timestamp': datetime.now().isoformat(),
            'prediction_id': prediction_data.get('id'),
            'user_id': prediction_data.get('user_id'),
            'features': prediction_data.get('features'),
            'prediction': prediction_data.get('prediction'),
            'anomaly_score': prediction_data.get('anomaly_score'),
            'confidence': prediction_data.get('confidence'),
            'model_version': prediction_data.get('model_version')
        }
        
        self.logger.info(json.dumps(log_entry))
        
    def log_feature_drift(self, drift_info):
        """Log feature drift detection"""
        drift_entry = {
            'timestamp': datetime.now().isoformat(),
            'drift_detected': drift_info.get('drift_detected'),
            'feature_name': drift_info.get('feature_name'),
            'drift_score': drift_info.get('drift_score'),
            'threshold': drift_info.get('threshold')
        }
        
        self.logger.info(json.dumps(drift_entry))

Feedback Loop for Continuous Improvement

The feedback loop collects human labels for flagged anomalies to improve model performance and reduce false positives.

class FeedbackLoop:
    def __init__(self, feedback_collection_endpoint):
        self.feedback_collection_endpoint = feedback_collection_endpoint
        
    def collect_feedback(self, flagged_anomalies):
        """Collect human feedback for flagged anomalies"""
        feedback_data = []
        
        for anomaly in flagged_anomalies:
            feedback_entry = {
                'anomaly_id': anomaly['id'],
                'user_feedback': None,  # To be filled by human review
                'correctness': None,    # True/False for correct classification
                'timestamp': datetime.now().isoformat()
            }
            feedback_data.append(feedback_entry)
            
        # Send to feedback collection system
        # This would typically be an HTTP POST to a feedback service
        return self.send_feedback_to_system(feedback_data)
        
    def send_feedback_to_system(self, feedback_data):
        """Send feedback to feedback collection system"""
        # Implementation would depend on specific feedback storage system
        # This is a placeholder for actual integration
        return True
        
    def update_model_with_feedback(self, feedback_data):
        """Update model with human feedback for continuous learning"""
        # Implementation would involve retraining or online learning
        # This is a placeholder for actual model update logic
        pass

Key Monitoring Metrics

MetricDescriptionAlert ThresholdFrequency
AUC-ROCModel discrimination ability< 0.85Daily
F1-ScoreBalance between precision and recall< 0.75Daily
PSI DriftPopulation stability index for features> 0.1Hourly
KS DriftKolmogorov-Smirnov test for continuous features> 0.1Hourly
False Positive RateProportion of normal instances classified as anomalies> 0.15Daily
Model AgeDays since last model retraining> 30 daysWeekly

Alerting Configuration

The system implements multi-tiered alerting:

  1. Critical Alerts: Immediate retraining required (drift > 0.2, AUC < 0.7)
  2. Warning Alerts: Performance degradation (AUC < 0.85, F1 < 0.75)
  3. Info Alerts: Feature drift (PSI > 0.1, KS > 0.1)

Observability Dashboard Components

  • Real-time prediction distribution charts
  • Drift detection heatmaps by feature type
  • Performance degradation trend lines
  • Anomaly classification accuracy by user segment
  • Retraining schedule and success rate tracking

This monitoring framework ensures the anomaly detection system maintains high performance, detects data drift early, and enables continuous model improvement through feedback loops.

9. Responsible AI & Safety

Bias Analysis

  • Training data audit: Conduct comprehensive audit of historical anomaly detection data to identify potential biases in normal vs. anomalous patterns. Key areas: temporal bias (e.g., seasonal anomalies not captured), geographic bias (e.g., regional anomaly patterns), and user segment bias (e.g., under-representation of certain user types).
  • Slice-based fairness evaluation: Evaluate model performance across user demographics (age, location, device type), business segments (enterprise vs. consumer), and temporal slices (seasonal variations). Monitor for disparate error rates across these slices.

Fairness Metrics and Constraints

  • Primary fairness metric: Equalized odds across user segments, ensuring that true positive rates and false positive rates are similar across different slices.
  • Decision: Prioritize equalized odds over demographic parity to avoid overly restrictive constraints that could reduce overall model effectiveness while maintaining fairness across user groups.
  • Constraint implementation: Implement fairness-aware loss functions that penalize performance disparities between slices during training.

Explainability Requirements and Approach

  • SHAP values: Implement SHAP-based explainability to provide feature importance scores for detected anomalies, enabling domain experts to understand why specific patterns were flagged.
  • Attention mechanisms: For transformer-based models, utilize attention weights to highlight which time windows or features were most influential in anomaly detection decisions.
  • Stakeholder requirements:
    • Business stakeholders: High-level anomaly explanations for operational decision-making
    • Security team: Detailed feature-level explanations for root cause analysis
    • Compliance team: Audit-ready explanations with confidence scores

Safety Guardrails for Anomaly Detection Systems

  • Content filtering: Implement thresholds to prevent false positives from being flagged as critical anomalies, particularly for low-confidence detections.
  • Output validation: Validate anomaly scores against business logic and historical patterns to prevent over-detection of normal events.
  • Rate limiting: Implement rate limits on anomaly alerts to prevent alert fatigue and ensure critical anomalies are not drowned out by noise.
  • Red teaming: Regularly test model behavior with adversarial examples and edge cases to identify blind spots in anomaly detection logic.

Model Card Documentation Plan

  • Documentation components:
    • Model architecture and training methodology
    • Performance metrics across different user segments and time periods
    • Known limitations and edge cases
    • Data characteristics and potential biases
    • Fairness assessment results
    • Safety thresholds and operational constraints

Incident Response Plan for Model Failures or Harmful Outputs

  • Failure detection triggers:
    • Sudden spike in false positive rate (>20% increase over 7-day window)
    • Drop in true positive rate below threshold (e.g., <80% of historical baseline)
    • Unusual pattern in anomaly alert distribution (e.g., all alerts from single user segment)
  • Response protocol:
    1. Immediate alert to ML and security teams
    2. Rollback to previous model version if drift detected
    3. Manual investigation of flagged anomalies using explainability tools
    4. Temporary disablement of alerts for affected user segments if necessary
    5. Post-mortem analysis and model retraining within 48 hours
class AnomalyDetectionSafetyGuardrails:
    def __init__(self, model, threshold_config):
        self.model = model
        self.confidence_threshold = threshold_config['confidence']
        self.false_positive_rate_limit = threshold_config['fpr_limit']
        
    def validate_anomaly_output(self, anomaly_score, confidence, user_segment):
        """Validate anomaly output for safety compliance"""
        # Safety checks
        if confidence < self.confidence_threshold:
            return {"valid": False, "reason": "low_confidence"}
        
        # Rate limiting for user segments
        if self._is_user_segment_over_alerted(user_segment):
            return {"valid": False, "reason": "rate_limit_exceeded"}
            
        # Validate against business logic
        if not self._validate_business_logic(anomaly_score):
            return {"valid": False, "reason": "business_logic_violation"}
            
        return {"valid": True, "score": anomaly_score}
    
    def _is_user_segment_over_alerted(self, user_segment):
        # Implement rate limiting logic
        pass
        
    def _validate_business_logic(self, score):
        # Validate that anomaly score aligns with business expectations
        return score > 0.5  # Example threshold

10. Scalability & Reliability

Bottleneck Analysis Per Pipeline Stage

Data Ingestion & Preprocessing:

  • Bottleneck: High-volume log parsing and feature extraction
  • Back-of-envelope: 10M events/sec → 50GB/s raw data → 200GB/s after feature extraction
  • Mitigation: Distributed Kafka + Spark streaming with parallel preprocessing

Model Training:

  • Bottleneck: Large-scale distributed training on 100K+ features
  • Back-of-envelope: 50M samples × 100K features = 5TB training data → 24h training on 100 GPU cluster
  • Mitigation: Data parallelism with gradient compression, model checkpointing

Online Serving:

  • Bottleneck: Real-time scoring of 10M+ concurrent users
  • Back-of-envelope: 100K QPS × 10ms latency = 1M concurrent requests → 1000x increase in serving capacity needed
  • Mitigation: Two-stage pipeline with candidate filtering, model compression

Scale-up Strategy

Horizontal Scaling of Serving:

  • User-level: Auto-scaling groups with Kubernetes HPA based on QPS
  • Model-level: Model sharding across multiple instances (e.g., 100 models for 100 user segments)
  • Feature-level: Distributed feature store with read replicas

Distributed Feature Computation:

  • Batch processing: Spark jobs for feature aggregation (daily)
  • Real-time processing: Flink/Kafka streams for user session features
  • Cache layer: Redis/Memcached for hot feature lookups (90% of features accessed <10ms)

Fault Tolerance

Model Serving Fallbacks:

  • Primary: ML model serving with 99.9% availability SLA
  • Fallback: Rule-based anomaly detection (threshold-based) when model fails
  • Graceful degradation: Reduced feature set serving during partial outages

Stale Model Serving:

  • Grace period: 24-hour window for model staleness
  • Fallback logic: Use last known good model version if new model fails to load
  • Health checks: 5-minute heartbeat monitoring for all model instances

Cold Start Handling Strategy

New User Detection:

  • Threshold: Less than 50 interactions in first 24 hours
  • Fallback: Use population-level anomaly thresholds with confidence bands
  • Recovery: Switch to personalized model once sufficient data collected

New Item Detection:

  • Threshold: Less than 1000 events in first week
  • Fallback: Use item category-level anomaly patterns with 85% confidence threshold
  • Recovery: Gradually personalize as more data becomes available

Multi-region Serving Strategy

Primary Region (e.g., us-west-2):

  • Capacity: 100K QPS with 50ms p99 latency
  • Redundancy: 3x replication for all model instances

Secondary Region (e.g., us-east-1):

  • Capacity: 50K QPS with 75ms p99 latency (accepts some degradation)
  • Failover: Automatic traffic routing on primary region failure
  • Data sync: 15-minute sync window for feature store consistency

Cross-region Load Balancing:

  • Strategy: Route traffic to nearest region with capacity
  • Fallback: 10% of traffic routed to secondary region for redundancy
  • Monitoring: Real-time QPS distribution across regions

Latency Budget Allocation:

Stagep50p99Budget
Feature Lookup5ms10ms15ms
Model Inference10ms25ms35ms
Response Assembly2ms5ms7ms
Total17ms40ms50ms

Reliability Metrics & Monitoring

SLA Targets:

  • Availability: 99.9% (100ms downtime/month)
  • Latency: 50ms p99, 20ms p50
  • Throughput: 100K QPS (with 2x headroom for scaling)

Failure Detection:

  • Timeout: 100ms for model inference (fail fast)
  • Error Rate: >5% error rate triggers alert
  • Latency Spike: >2x baseline latency triggers investigation

Recovery Procedures:

  1. Immediate: Auto-failover to fallback model
  2. Medium: Rollback to previous stable model version
  3. Long-term: Full system rollback with feature store recovery

Capacity Planning

QPS Growth Projection:

  • Year 1: 10K QPS → 50K QPS (5x growth)
  • Year 2: 50K QPS → 200K QPS (4x growth)
  • Year 3: 200K QPS → 500K QPS (2.5x growth)

Infrastructure Scaling:

  • GPU Cluster: 100 GPUs → 500 GPUs (5x increase)
  • Feature Store: 10TB → 50TB (5x increase)
  • Serving Nodes: 200 nodes → 1000 nodes (5x increase)

Cost Optimization:

  • Spot Instances: 30% of training capacity for cost savings
  • Model Compression: 40% reduction in model size with <5% accuracy loss
  • Caching Strategy: 60% reduction in feature lookup latency through caching

11. Open Questions, Risks & Trade-offs

Decisions requiring product / engineering / policy alignment

  • Threshold tuning strategy — Should thresholds be set statically or dynamically adjusted based on business impact? What's the escalation process when false positives exceed acceptable limits?
  • Alerting policy — Should all anomalies trigger alerts or only those above a confidence threshold? How do we handle alert fatigue for high-volume systems?
  • Human-in-the-loop integration — Should anomaly detection be fully automated or require human review for critical systems? What's the workflow for manual validation?
  • Cross-system correlation — Should anomalies in one system be treated as signals for correlated systems? How do we handle cascading failures?

Key ML risks

RiskImpactLikelihoodMitigation
High false positive rateBusiness disruption, alert fatigue, engineer burnoutMedium-HighImplement confidence thresholds, enable human review, A/B test alerting policies
Data drift in anomaly patternsModel becomes obsolete, missed real anomaliesMediumImplement drift detection, scheduled retraining, shadow mode monitoring
Class imbalance in anomaly dataModel biased toward normal samplesMediumUse anomaly-aware sampling, cost-sensitive learning, threshold tuning
Cold start for new entitiesMissed anomalies in new users/itemsMediumImplement ensemble approach with rule-based fallback, adaptive thresholds
High computational costIncreased latency, reduced scalabilityLow-MediumModel compression, feature selection, batch processing

Trade-offs made with justification

  • Accuracy vs. latency: Prioritizing sub-100ms response time over marginal accuracy gains by using lightweight models (e.g., Isolation Forest) with pre-computed thresholds rather than real-time model retraining
  • Freshness vs. cost: Accepting 5-minute feature freshness window to reduce computational overhead and storage costs, balancing with the need for timely anomaly detection
  • Model size vs. quality: Choosing smaller ensemble models over large transformers to maintain low latency and reduce infrastructure costs, despite potential accuracy loss
  • False positive rate vs. coverage: Accepting higher false positives to ensure no critical anomalies are missed, particularly in financial or security contexts where missing an anomaly is more costly than alert fatigue

Alternatives considered and rejected

  • Deep learning approaches (VAE, LSTM) were evaluated but rejected due to high computational requirements and longer training times that don't align with our sub-100ms latency requirement
  • Supervised learning was considered but rejected due to lack of labeled anomaly data in our system, making it infeasible for reliable training
  • Ensemble of multiple models was considered but rejected due to increased complexity and latency overhead, preferring simpler yet effective single-model approaches
  • Real-time retraining was considered but rejected due to the high cost of maintaining model freshness and the risk of training-serving skew in our batch-heavy environment

Technical debt acknowledged

  • Limited feature engineering — Current implementation relies heavily on basic statistical features rather than sophisticated engineered features, which may limit model performance in complex anomaly detection scenarios
  • Static thresholding — Using fixed thresholds rather than adaptive confidence-based approaches, which may not scale well with changing data distributions over time
  • Limited cross-system correlation — Not currently modeling inter-system anomalies, which could be valuable for detecting coordinated attacks or cascading failures
  • No active learning — Not implementing feedback loops to continuously improve model performance through human validation of detected anomalies

12. Phased Implementation Roadmap

Phase 1: MVP (Weeks 1-6)

Objective: Establish baseline anomaly detection capability with rule-based fallback

Deliverables:

  • Rule-based anomaly detection system (threshold-based, statistical)
  • Basic feature extraction pipeline
  • Simple ML model (Isolation Forest or One-Class SVM)
  • Online serving infrastructure with 100 QPS capacity
  • Basic A/B testing framework

Dependencies:

  • Data pipeline ready (1-2 weeks)
  • Feature store MVP (2 weeks)
  • Basic model training infrastructure (1 week)

Critical Path:

  1. Data ingestion pipeline (Week 1-2)
  2. Feature engineering pipeline (Week 2-3)
  3. Simple anomaly detection model training (Week 3-4)
  4. Online serving setup (Week 4-5)
  5. A/B testing infrastructure (Week 5-6)

Phase 2: Scale (Weeks 7-14)

Objective: Scale to production-grade anomaly detection with advanced features

Deliverables:

  • Distributed training pipeline (data parallelism)
  • Feature store with real-time capabilities
  • Multi-model ensemble approach (Isolation Forest + Autoencoder)
  • Advanced feature engineering (temporal features, cross-features)
  • Real-time feature computation pipeline
  • Model versioning and registry

Dependencies:

  • Feature store with real-time updates (2 weeks)
  • Distributed training infrastructure (3 weeks)
  • Model registry and versioning (1 week)

Critical Path:

  1. Feature store enhancement (Week 7-8)
  2. Distributed training pipeline (Week 8-10)
  3. Ensemble model implementation (Week 10-12)
  4. Real-time feature pipeline (Week 12-13)
  5. Production deployment (Week 13-14)

Phase 3: Excellence (Weeks 15-20)

Objective: Advanced anomaly detection with continuous learning and monitoring

Deliverables:

  • Online learning capability (incremental model updates)
  • Advanced drift detection and retraining triggers
  • Comprehensive monitoring and alerting system
  • Multi-slice evaluation framework (user segments, regions)
  • Continuous model improvement pipeline
  • LLM-based anomaly explanation generation (optional)

Dependencies:

  • Drift detection system (2 weeks)
  • Continuous learning infrastructure (3 weeks)
  • Advanced monitoring system (2 weeks)

Critical Path:

  1. Drift detection implementation (Week 15-16)
  2. Continuous learning pipeline (Week 16-18)
  3. Advanced monitoring system (Week 18-19)
  4. Model improvement pipeline (Week 19-20)

Risk Mitigation Strategy:

  • Data Quality Risk: Implement data validation at each stage
  • Model Performance Risk: Maintain rule-based fallback for all phases
  • Scale Risk: Start with smaller dataset and scale gradually
  • Latency Risk: Monitor QPS and latency at each phase

Success Metrics:

  • Phase 1: 80% rule-based coverage, <50ms latency
  • Phase 2: 90% model accuracy improvement, 10x QPS capacity
  • Phase 3: <2% false positive rate, <100ms latency, 95% drift detection coverage

Resource Allocation:

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

Rollout Strategy:

  • Phase 1: Internal testing with 5% traffic
  • Phase 2: Gradual rollout to 20% of production traffic
  • Phase 3: Full production deployment with monitoring dashboard

Technical Debt Considerations:

  • Modular architecture to support future model evolution
  • Comprehensive logging for all phases
  • Automated testing suite for each phase's deliverables

Was this article helpful?

Topics in this article

More from AI/ML System Design

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.