AI & integration

AWS SageMaker model monitoring: how to set up drift alerts

Even when the code stays unchanged, a model that performed well in the prior quarter may fail in the current quarter. Input data shifts as external conditions evolve. As a result, predictions grow less accurate over time, frequently before such changes appear on a dashboard.

AWS SageMaker model monitoring provides a service that executes scheduled jobs on live endpoint traffic to monitor data quality, model quality, and bias. It compares incoming data to a baseline and raises a violation when the data drifts beyond defined limits. These alerts are delivered via CloudWatch. To use this service effectively, you need an accurate baseline, suitable thresholds, and a plan for handling alerts.

We frequently see this scenario in our client engagements. A model may be deployed and perform well in a demonstration, yet the team fails to set up a monitoring system for production. Months later, a stakeholder could raise concerns about unusual approval rates. The team cannot explain the issue because they were not tracking the model's performance. AWS SageMaker Model Monitor is built to solve this problem. It monitors data quality, model quality, and bias within production environments. The tool notifies you when metrics deviate markedly from your established baseline.

Implementing this system demands more than simple activation. You need to create a baseline with clean data, devise a logical schedule, and set thresholds that prevent false alarms. You also require a procedure for responding to flags. Omitting these steps will lead to unreliable alerts or a model that degrades unnoticed. This guide covers data capture, baselines, scheduled monitoring, CloudWatch alerts, bias, explainability, and the process for triaging a violation after it occurs.

The technical process of SageMaker Model Monitor

SageMaker Model Monitor is an AWS service that carries out scheduled checks on traffic from your real-time endpoints. It offers a framework containing four built-in monitor types, each targeting a particular type of failure.

The underlying pipeline is the same for all four options. You should grasp this process before altering any configuration settings.

Four monitors, four questions

Each monitor tracks a particular aspect of your model's performance in production. You are not required to implement all four monitors at the outset.

  • Data Quality Monitor observes the statistical shape of your input features, distributions, missing values, and type mismatches, and triggers when they drift from your baseline.
  • Model Quality Monitor compares predictions to ground truth labels after they are received. It tracks metrics like accuracy, F1, AUC, or RMSE depending on the specific task.
  • Model Bias Monitor evaluates disparate impact and fairness metrics for the demographic groups you specify. It identifies cases where shifts in the user population significantly change model outcomes.
  • Model Explainability Monitor monitors SHAP feature attribution values over time. It detects when a new set of inputs starts influencing predictions.

Start by monitoring data quality and model quality. These checks are cheaper to implement and capture most real incidents. This approach lets your team become comfortable interpreting violation reports before adding the extra complexity of bias and explainability monitoring via Clarify.

How the system operates internally

Each monitor type follows the same basic process. SageMaker employs a data capture configuration to gather a sample of live traffic from your endpoint. This data is stored in an S3 bucket in JSON Lines format, with separate files for each inference batch arranged by date and hour. A scheduled processing job reads these files and compares them to a pre-computed baseline. The job then writes a violation report to a specific output path.

The baseline is the most critical input for the whole system. If the baseline is wrong, every constraint that SageMaker derives from it will also be wrong. This leads the monitoring system to flag normal traffic as violations.

The system schedules runs with a cron expression that you define. These runs typically occur hourly or daily, depending on your traffic volume. AWS runs these as fully managed Processing jobs, so you do not need to provision compute resources or manage clusters. A job starts, performs the comparison, records the output, and then ends.

Violations are not immediately obvious

SageMaker creates a constraint_violations.json file in your output path. This action does not generate alerts. To monitor violations, you must connect the monitoring schedule to Amazon CloudWatch. CloudWatch automatically gathers metrics such as feature_baseline_drift_distance and data_missing_values once you activate the schedule. You can then set up CloudWatch alarms with specific thresholds to send SNS notifications, launch a Lambda function, or integrate with your existing incident management tools.

Before you start: permissions and a monitoring plan

Before writing any code, complete two tasks. First, determine the permissions required by your monitoring jobs. Second, document precisely what you intend to monitor. If you skip these steps, you will likely build a pipeline that runs correctly but does not provide useful information.

Permissions required for your execution role

Your SageMaker execution role must be permitted to write to S3, publish metrics to CloudWatch, and create and run Processing jobs. If you use an existing role, confirm that it includes these permissions:

  • SageMaker access that covers monitoring actions. This can be the full managed policy or a custom policy with a limited scope.
  • S3 access scoped to your monitoring input and output buckets
  • CloudWatch access for publishing metrics
  • SNS access if alerts will route through an SNS topic

Create a dedicated S3 bucket for monitoring. Use separate prefixes for captured data, baseline artefacts, and job outputs. Separating these files from your training data and model artefacts prevents errors during debugging.

Write the plan down before configuring anything

A monitoring plan consists of a specific set of decisions rather than a formal document. You must decide which monitor types to run, which features are important, how frequently you require results, and which person receives a notification when a violation occurs. Answer these questions before you begin Step 1:

  • Which monitor types are you enabling: data quality, model quality, bias, explainability, or some combination
  • Identify the three to five input features that are most important and require the strictest thresholds.
  • What cadence fits your traffic: hourly, daily, or weekly
  • Will you use a strict method that flags every deviation, or a lenient method that flags deviations only after they exceed a specific percentage?
  • Where do alerts land: an SNS topic, a Slack channel via Lambda, PagerDuty, something else
  • Who triages a violation when it fires

The following configuration choices depend on these six answers, so it is best to record them before beginning Step 1.

Step 1: turn on data capture

Data capture is the primary requirement for all subsequent processes. Monitoring jobs require this data to perform comparisons. SageMaker records inference requests and responses from active endpoints and saves them to S3. The data uses the JSON Lines format and is organised by date and hour. You can activate this feature during deployment by using a DataCaptureConfig. You can also enable it on an existing endpoint without performing a full redeployment.

Configure the capture

DataCaptureConfig manages the capture status, the traffic sampling percentage, and the S3 storage location. Set EnableCapture to true and the sampling percentage to 100 during the initial setup. This provides the most representative sample for your baseline job. After you establish the baseline, reduce the sampling rate to decrease storage costs.

from sagemaker.model_monitor import DataCaptureConfig
from sagemaker import Session

sagemaker_session = Session()

data_capture_config = DataCaptureConfig(
    enable_capture=True,
    sampling_percentage=100,
    destination_s3_uri="s3://your-bucket/monitoring/captured-data/",
    capture_options=["REQUEST", "RESPONSE"]
)

predictor = model.deploy(
    initial_instance_count=1,
    instance_type="ml.m5.xlarge",
    endpoint_name="your-endpoint-name",
    data_capture_config=data_capture_config
)

Include both REQUEST and RESPONSE in capture_options. You require the inputs and the output for later monitoring of data quality and model quality. If you omit RESPONSE, you will have to redeploy the system to obtain prediction distributions that you expected to be available.

Verify that the data is being received

Send a handful of test inferences, then check the S3 destination prefix. SageMaker writes one JSON Lines file per inference batch under a path structured as year, month, day, hour.

aws s3 ls s3://your-bucket/monitoring/captured-data/ --recursive

Files should appear within two or three minutes. If the prefix remains empty after several calls, the cause is typically a missing write permission on the destination bucket rather than a problem with the endpoint.

Step 2: create your baseline

The baseline serves as the standard for all subsequent monitoring tasks. SageMaker performs a single processing job on a representative sample of your captured data to generate two files. The first file, statistics.json, describes the mean, median, standard deviation, and distribution shape of each feature. The second file, constraints.json, defines the specific ranges and limits allowed for these properties.

Run the baseline job

The SDK's DefaultModelMonitor class creates a baseline with one method call. You provide the captured S3 prefix and an output location for the process to run.

from sagemaker.model_monitor import DefaultModelMonitor
from sagemaker.model_monitor.dataset_format import DatasetFormat

monitor = DefaultModelMonitor(
    role="arn:aws:iam::your-account-id:role/your-sagemaker-role",
    instance_count=1,
    instance_type="ml.m5.xlarge",
    volume_size_in_gb=20,
    max_runtime_in_seconds=3600
)

monitor.suggest_baseline(
    baseline_dataset="s3://your-bucket/monitoring/captured-data/",
    dataset_format=DatasetFormat.csv(header=True),
    output_s3_uri="s3://your-bucket/monitoring/baseline-results/",
    wait=True,
    logs=False
)

This process usually takes five to fifteen minutes, depending on the size of the dataset. Both artefacts are saved to your baseline output prefix and can be attached to a schedule.

Read the constraints before you trust them

SageMaker's auto-generated constraints are conservative by default, but review them before use. Open constraints.json and check the inferred type for each feature, the completeness threshold, and any string constraints on categorical columns. Features with high cardinality or irregular distributions are the ones where the auto-generated constraints tend to come out too strict or too loose for what production looks like. Edit the JSON where needed, and keep both versions in version control for an audit trail.

Step 3: schedule monitoring and wire up CloudWatch

After you establish a baseline, schedule recurring jobs to monitor for drift. This schedule instructs SageMaker to run at specific intervals to collect captured data, compare that data to your baseline, and generate a violation report. These steps transition the setup from a single task into an active system.

Create the schedule

from sagemaker.model_monitor import CronExpressionGenerator

monitor.create_monitoring_schedule(
    monitor_schedule_name="data-quality-schedule",
    endpoint_input="your-endpoint-name",
    output_s3_uri="s3://your-bucket/monitoring/schedule-output/",
    statistics=monitor.baseline_statistics(),
    constraints=monitor.suggested_constraints(),
    schedule_cron_expression=CronExpressionGenerator.hourly(),
    enable_cloudwatch_metrics=True
)

You must set enable_cloudwatch_metrics=True for alerts to function. If you disable this setting, violation reports will save to S3, but data will not reach CloudWatch. This prevents any alarms you create from having information to evaluate. You should set your job frequency based on your traffic levels and how fast you need to detect issues. Run daily jobs for low-traffic endpoints. Running hourly jobs on small samples creates statistical noise caused by the sample size rather than actual data drift.

Reading a violation report

Each run generates a constraint_violations.json file in a folder named with a timestamp. Every entry in the file lists the feature name, the specific constraint that was broken, and the value that caused the violation. A standard entry follows this format:

  • Feature name: customer_age
  • Check type: baseline drift check
  • Description: observed distance 0.38 exceeds threshold 0.20

Monitor the distance in relation to the threshold. A distance that is slightly above the threshold during one run is frequently caused by noise instead of actual drift. You should track the distance over multiple consecutive runs before you decide to investigate the results.

Set up the alarm

Use the SDK to create alarms. This approach can be repeated and lets you keep the configuration in version control. The example below demonstrates an alarm for the drift distance of one feature, and it delivers notifications to an SNS topic:

import boto3

cloudwatch = boto3.client("cloudwatch", region_name="eu-west-1")

cloudwatch.put_metric_alarm(
    AlarmName="data-drift-customer-age",
    MetricName="feature_baseline_drift_distance",
    Namespace="/aws/sagemaker/Endpoints/data-metrics",
    Dimensions=[
        {"Name": "Endpoint", "Value": "your-endpoint-name"},
        {"Name": "MonitoringSchedule", "Value": "data-quality-schedule"},
        {"Name": "Feature", "Value": "customer_age"}
    ],
    Statistic="Maximum",
    Period=3600,
    EvaluationPeriods=2,
    Threshold=0.20,
    ComparisonOperator="GreaterThanThreshold",
    AlarmActions=["arn:aws:sns:eu-west-1:your-account-id:your-sns-topic"],
    TreatMissingData="notBreaching"
)

Set EvaluationPeriods to 2. With this setting, the alarm will fire only after two consecutive breaches, eliminating the single-period noise mentioned earlier. Define an individual alarm for each critical feature rather than a single generic alarm. A feature-specific alarm enables your team to pinpoint the issue more quickly than a generic alert that merely signals a change.

Best for teams that need reliable early warning without babysitting a dashboard. Watch for: alarms on too many features at once, which trains your team to ignore them. Start with three to five features that matter to the business, not every column your data happens to have.

An SNS topic can deliver messages to email, SMS, Lambda functions, or external services like PagerDuty. For Slack users, the most efficient setup we have seen employs a small Lambda function. That function formats the CloudWatch payload and posts it to a channel, providing the metric value and a link to the graph.

Step 4: add model quality, bias, and explainability

Data quality monitoring shows whether your input data has changed. It does not assess whether the model stays accurate. Model quality monitoring solves this by comparing predictions to ground truth labels once they are available. This monitoring offers the most direct indication of business impact.

Unique requirements for model quality

Model quality needs both your predictions and a matching set of ground truth labels supplied after the initial inference. This is different from data quality, which relies solely on captured inference data. The process includes a delay since real-world outcomes may take hours, days, or weeks to appear. You must make sure that your ground truth delivery schedule matches your monitoring schedule. If the schedules differ, the monitoring job will execute but will not yield useful results.

If ground truth never arrives for a prediction, for example fraud flags on transactions that are never investigated, model quality monitoring is not feasible, and you rely on data quality and bias monitoring instead.

Use the ModelQualityMonitor class to create a baseline. Evaluate it with a labelled holdout dataset that reflects production conditions. Verify that the file includes both predictions and ground truth labels.

from sagemaker.model_monitor import ModelQualityMonitor
from sagemaker.model_monitor.dataset_format import DatasetFormat

model_quality_monitor = ModelQualityMonitor(
    role="arn:aws:iam::your-account-id:role/your-sagemaker-role",
    instance_count=1,
    instance_type="ml.m5.xlarge"
)

model_quality_monitor.suggest_baseline(
    baseline_dataset="s3://your-bucket/monitoring/baseline-with-labels.csv",
    dataset_format=DatasetFormat.csv(header=True),
    output_s3_uri="s3://your-bucket/monitoring/model-quality-baseline/",
    problem_type="BinaryClassification",
    inference_attribute="prediction",
    ground_truth_attribute="label",
    wait=True
)

Set problem_type to the value that corresponds to your task. This option decides whether SageMaker computes F1, AUC, or RMSE metrics. Schedule this job using the same approach as a data quality monitor. Supply an S3 URI for your ground truth data. Arrange the files in date-based partitions so the system can associate predictions with labels via timestamps.

Bias and explainability

Data quality and model quality do not reveal whether a model is fair or interpretable. Bias drift happens when changes in the makeup of inference traffic cause unequal results for protected groups, even if the model weights stay unchanged. For instance, if a loan approval model gets more applications from a particular age group, the approval rate for that group might differ from the baseline because of external factors rather than the model itself. SageMaker's ModelBiasMonitor identifies these shifts by computing fairness metrics such as the Disparate Impact Ratio. It compares the current data to a baseline built from labelled production data using SageMaker Clarify.

Explainability monitoring follows SHAP feature attribution values over time and alerts when the features that drive predictions move away from the baseline. It is effective at detecting silent upstream changes, where a feature that previously had little impact suddenly dominates because the pipeline supplying it altered its shape. Both monitors operate through Clarify configurations, not DefaultModelMonitor, so allocate additional setup time. When all four monitors are active, you obtain real coverage for accuracy, drift, fairness, and interpretability, rather than a single metric that claims the model is fine without explaining why.

Triage: how to respond to an alarm

An alarm does not necessarily mean the model needs retraining. Retraining each time an alert fires wastes data-science resources on statistical noise, pipeline errors, and wrong thresholds. This is among the most common and expensive mistakes teams make after deploying monitoring systems.

Follow the diagnostic steps in the given order

Open the violation report for the run that triggered the alarm. Note the observed distance. Examine the metric history in CloudWatch for the last five to ten periods to see whether the data shows a consistent trend or a single spike. Ask these questions in order:

  • Check whether the sample size dropped during the period in question. Small samples do not yield reliable statistics.
  • Determine whether the violation appears in a single feature or across several features at the same time. When multiple features change together, the cause is usually a change in the upstream pipeline rather than genuine model decay.
  • Were there any other system changes during the same period? This includes updates to the data structure, modifications to the underlying infrastructure, or transfers of data from one source to another.
  • Does the model quality monitor display a matching drop in accuracy, or does the value stay within the baseline?

If a violation shows up in one run but not in the next, it is typically due to a small sample size rather than an actual change. Do not act on a single data point.

Retrain, adjust, or escalate elsewhere

If you verify that the input distribution has shifted and accuracy has dropped, create a retraining ticket. Give the data-science team the statistical comparison for the period in question along with the related accuracy data.

If your baseline no longer matches current production due to data changes, update the baseline instead of retraining the model. Rerun the baseline job with a new sample. Examine the resulting constraints and adjust your schedule to use the new files.

If the issue originates before your endpoint, for example a broken pipeline delivering incorrect values, forward the problem to the data engineering team rather than the model owners. Routing each error type to the appropriate team with evidence helps avoid recurring false alarms.

Deploying the system to production correctly

You have now established monitoring for data quality, model quality, bias, and explainability. CloudWatch alarms send notifications to the appropriate staff, and you have a triage process for managing these alerts. Before you move to production, perform a full test cycle in a staging environment. Verify that captured data flows properly, baselines generate without errors, and alarms trigger correctly. Record every threshold and baseline version in your team's runbooks.

Monitoring isn't something you set once. Revisit baselines every quarter, or sooner if your data shifts meaningfully, and treat each triage cycle as feedback that sharpens your thresholds rather than a one-off firefight. This is the production readiness work that separates a model running quietly for years from one that needs constant hand-holding, and it's the piece teams most often skip when racing to ship.

If you'd rather have someone design the monitoring architecture around your existing ML infrastructure than build it from scratch, talk to us and we'll walk through what your setup actually needs.

From concept to production in weeks, not quarters: our bespoke AI development puts articles like this to work on your data.

Frequently asked questions

What is AWS SageMaker?

AWS SageMaker is a managed platform for machine learning. SageMaker Model Monitor is the specific feature used to track data quality, model quality, and bias after a model has been deployed. It executes scheduled tasks to analyse traffic from a real-time endpoint, which removes the need for users to develop their own logging and comparison systems. To use SageMaker monitoring effectively, you must establish a baseline, set appropriate thresholds, and create a plan for responding to alerts.

What are the four types of monitors in SageMaker Model Monitor?

SageMaker Model Monitor provides four monitoring types to identify different failure modes. The Data Quality Monitor identifies drift in the statistical properties of input features. The Model Quality Monitor compares model predictions with ground truth labels as they become available. The Model Bias Monitor evaluates fairness metrics for specific demographic groups. The Model Explainability Monitor tracks changes in SHAP feature attribution values. Most teams implement data quality and model quality monitoring before using the other two types.

How do you build a baseline for SageMaker Model Monitor?

You create a baseline using SageMaker's DefaultModelMonitor class, directing it to a representative sample of captured S3 data. This process generates two files: statistics.json, which describes the distribution of each feature, and constraints.json, which defines the acceptable boundaries for those properties. Each subsequent monitoring job compares data against this baseline. Therefore, review the automatically generated constraints before accepting them, as features with many unique values or irregular patterns can result in constraints that are either too strict or too permissive. Store both files in version control to maintain a record of changes.

How do CloudWatch alerts work with SageMaker Model Monitor?

SageMaker saves violation reports to S3. You must connect the monitoring schedule to CloudWatch to receive alerts. When CloudWatch metrics are enabled, the system automatically collects data such as feature_baseline_drift_distance. You can then configure alarms with specific thresholds. These alarms can trigger SNS notifications, Lambda functions, or other incident management tools. Setting an alarm to fire only after two consecutive breaches helps prevent alerts caused by temporary fluctuations.

What should you do when a SageMaker Model Monitor alarm fires?

When an alarm occurs, open the violation report and review the metric's history in CloudWatch. Determine if the data shows a consistent trend or a single spike. A violation that appears once and then disappears is typically a result of a small sample size rather than actual model drift. Check if the sample size decreased, if multiple features changed simultaneously, and if other variables changed during that period. Create a retraining ticket only if the diagnosis confirms a genuine shift that corresponds to a decrease in accuracy. If the shift is not genuine, update the baseline or send the issue to the data engineering team.

Start at your core.

Tell us where your data is today and what you want AI to do. We'll come back with a straight answer on what your foundation needs and where the quickest real win is.

Talk to us