Initializing Techhub.cafe

How do you deploy a trained model to a real-time SageMaker endpoint?

Updated Aug 1, 2026

Short answer

Create a Model (artefact plus inference image), an EndpointConfig (instance type, count, variants), then an Endpoint. Clients call InvokeEndpoint over HTTPS and you pay per instance-hour until the endpoint is deleted.

Deep explanation

The three-object structure is not bureaucracy — it is what makes zero-downtime updates possible. Because the Model and the EndpointConfig are separate from the Endpoint, you can build a new configuration and swap traffic to it atomically.

Python
from sagemaker.model import Model
from sagemaker.serializers import JSONSerializer
from sagemaker.deserializers import JSONDeserializer
model = Model(
image_uri=inference_image, # container that serves the model
model_data="s3://my-bucket/models/fraud/model.tar.gz",
role=role,
name="fraud-model-v3",
)
predictor = model.deploy(
initial_instance_count=2, # 2+ for availability across AZs
instance_type="ml.m5.xlarge",
endpoint_name="fraud-scorer",
serializer=JSONSerializer(),
deserializer=JSONDeserializer(),
data_capture_config=DataCaptureConfig( # needed later by Model Monitor
enable_capture=True,
sampling_percentage=20,
destination_s3_uri="s3://my-bucket/capture/fraud",
),
)

For a custom container, the inference script implements four hooks. Understanding their order is the whole request lifecycle:

Python
# inference.py
import joblib, os, json
def model_fn(model_dir): # once, at container start
return joblib.load(os.path.join(model_dir, "model.joblib"))
def input_fn(request_body, content_type): # per request: parse
if content_type == "application/json":
return json.loads(request_body)["features"]
raise ValueError(f"Unsupported content type: {content_type}")
def predict_fn(data, model): # per request: infer
return model.predict_proba([data])[0][1]
def output_fn(prediction, accept): # per request: serialise
return json.dumps({"fraud_probability": float(prediction)}), accept

model_fn runs once per container, so load heavy objects there, never inside predict_fn. Calling it per request is the single most common cause of an endpoint that "works" but has terrible latency.

Invoking from an application:

Python
import boto3, json
runtime = boto3.client("sagemaker-runtime")
resp = runtime.invoke_endpoint(
EndpointName="fraud-scorer",
ContentType="application/json",
Body=json.dumps({"features": [240.0, 0.7, 3, 1]}),
)
print(json.loads(resp["Body"].read()))

Updating safely: create a new EndpointConfig and call update_endpoint. SageMaker provisions the new fleet, shifts traffic, then removes the old one — no downtime and automatic rollback if the new variant fails health checks.

Real-world example

A payments company serves a fraud model at p99 under 100 ms with two ml.c5.xlarge instances across availability zones, fronted by API Gateway and Lambda for authentication and request shaping. Deployments go through a new EndpointConfig with a canary variant at 10% traffic for fifteen minutes; a CloudWatch alarm on ModelLatency and Invocation5XXErrors triggers automatic rollback before customers notice.

Common mistakes

  • - Loading the model inside `predict_fn` instead of `model_fn`, adding seconds to every request.
  • - Deploying a single instance in production — no redundancy, and any AZ event takes the service down.
  • - Deleting and recreating an endpoint to update it, causing an outage where `update_endpoint` would have been seamless.
  • - Ignoring the 60-second `InvokeEndpoint` limit and the payload size limit
  • long or large inference belongs on asynchronous inference.
  • - Enabling data capture only after a drift incident, when the baseline you needed was never recorded.

Follow-up questions

  • How do you update a model with no downtime?
  • What do you do when inference takes longer than 60 seconds?
  • How would you serve hundreds of per-customer models cost-effectively?

More AWS Machine Learning interview questions

View all →