4.5 Deploying, Querying, and Splitting Traffic Across Real-Time Endpoints
Key Takeaways
A serving endpoint hosts one or more served entities behind a single URL;
traffic_configroutes a percentage of requests to each.Traffic percentages across an endpoint's routes must total 100, which is how canary rollouts and A/B tests are expressed without redeploying anything.
Query an endpoint with an HTTPS POST to
/serving-endpoints/{name}/invocationsusingdataframe_split,dataframe_records,instances, orinputs.Inference tables capture request and response payloads asynchronously into Unity Catalog Delta tables for drift monitoring and audit.
CAN_QUERYpermits invoking the endpoint,CAN_MANAGEpermits changing its configuration, and the endpoint needsEXECUTEon the underlying registered model.
4.5 Deploying, Querying, and Splitting Traffic Across Real-Time Endpoints
Serverless Real-Time Endpoint Architecture
When a model from the Unity Catalog Model Registry is deployed to a serving endpoint, Databricks packages the model artifacts, its logged code environment, and its Python dependencies into managed serverless containers sitting behind an authenticated inference gateway.
+---------------------------------------------------------------------------------------------------+
| DATABRICKS REAL-TIME MODEL SERVING ARCHITECTURE |
| |
| EXTERNAL CLIENTS |
| (Web Apps, Mobile Backends, Microservices) |
| | |
| | HTTPS POST /serving-endpoints/{endpoint-name}/invocations |
| | Headers: Authorization: Bearer <token>, Content-Type: application/json |
| v |
| +-------------------------------------------------------------------------------------------+ |
| | MANAGED INFERENCE GATEWAY & ROUTER (Load Balancer & Auth Verification) | |
| +-------------------------------------------------------------------------------------------+ |
| | | |
| | Traffic Split: 90% (Champion) | Traffic Split: 10% (Challenger) |
| v v |
| +---------------------------------------+ +---------------------------------------+ |
| | SERVED ENTITY 1: @champion | | SERVED ENTITY 2: @challenger | |
| | - Container Replicas (Auto-scaled) | | - Container Replicas (Auto-scaled) | |
| | - Workload Size: Medium (CPU/GPU) | | - Workload Size: Small (CPU/GPU) | |
| | - Scale-to-Zero when idle | | - Scale-to-Zero when idle | |
| +---------------------------------------+ +---------------------------------------+ |
| | | |
| +--------------------------+--------------------------+ |
| | Asynchronous Payload Streaming |
| v |
| +-------------------------------------------------------------------------------------------+ |
| | UNITY CATALOG INFERENCE TABLE (Delta Lake Managed Table) |
| | - request_payload | response_payload | latency_ms | model_name | model_version | timestamp | |
| +-------------------------------------------------------------------------------------------+ |
+---------------------------------------------------------------------------------------------------+
Autoscaling & Scale-to-Zero
Databricks Model Serving dynamically monitors incoming request concurrency and latency metrics:
- Scale-Up: When request concurrency surges, the serving control plane provisions additional container replicas across available data plane capacity within seconds to maintain sub-50ms latency SLOs.
- Scale-to-Zero: When an endpoint experiences zero incoming traffic for a configurable cooldown window, the serving engine terminates active compute container instances, reducing compute cost to $0.00 while keeping the endpoint URL active. When a new request arrives, the endpoint automatically cold-starts.
Workload Sizing & Compute Configuration
When deploying a model, practitioners configure the workload size per served entity: Workload size sets the endpoint's provisioned concurrency — the number of requests it can process at once, since one unit of concurrency serves one request at a time:
| Workload size | Provisioned concurrency |
|---|---|
| Small | 4 |
| Medium | 8 – 16 |
| Large | 16 – 64 |
When scale_to_zero_enabled is set, the lower bound of each range drops to 0 during
idle periods. GPU-backed workload types are configured separately for deep learning
frameworks such as PyTorch, TensorFlow, and Hugging Face Transformers.
Multi-Model Traffic Splitting & Rollout Strategies
Production deployments require rigorous risk mitigation when introducing new model versions. Databricks Model Serving enables multi-entity routing behind a single endpoint URL.
+---------------------------------------------------------------------------------------------------+
| PROGRESSIVE TRAFFIC ROLLOUT PATTERNS |
| |
| PHASE 1: CANARY VALIDATION PHASE 2: A/B EXPERIMENTATION PHASE 3: FULL CUTOVER |
| +---------------------------+ +---------------------------+ +-------------------+ |
| | Champion (@prod): 90% | | Champion (@prod): 50% | | New Model (@prod):100%| |
| | Challenger (@canary): 10% | ----> | Challenger (@exp): 50% | ----> | Old Model: 0%| |
| | Assess error rates/latency| | Measure business KPIs | | (Decommissioned) | |
| +---------------------------+ +---------------------------+ +-------------------+ |
+---------------------------------------------------------------------------------------------------+
Deployment Strategies
- Canary Deployment: Route 5%–10% of live traffic to a newly registered candidate model while routing 90%–95% to the existing production baseline. Engineers monitor latency, memory consumption, and error rates before expanding traffic.
- A/B Testing: Route 50% of traffic to Model A and 50% to Model B. Downstream business metrics (e.g., click-through rate, conversion rate) are tracked via Inference Tables to evaluate statistical superiority.
- Champion / Challenger Rollout: Models are tagged in Unity Catalog using model aliases (
@championand@challenger). The endpoint configuration references these aliases directly, enabling zero-downtime weight adjustments.
Endpoint Configuration Example via Python SDK
from databricks.sdk import WorkspaceClient
from databricks.sdk.service.serving import EndpointCoreConfigInput, ServedEntityInput
w = WorkspaceClient()
# Create or update a serving endpoint with 90/10 traffic splitting
w.serving_endpoints.create_and_wait(
name="customer-churn-serving-endpoint",
config=EndpointCoreConfigInput(
served_entities=[
ServedEntityInput(
name="churn-champion",
entity_name="prod_ml.customer_churn.churn_model",
entity_version="4", # Or Unity Catalog alias
workload_size="Small",
scale_to_zero_enabled=True
),
ServedEntityInput(
name="churn-challenger",
entity_name="prod_ml.customer_churn.churn_model",
entity_version="5",
workload_size="Small",
scale_to_zero_enabled=True
)
],
traffic_config={
"routes": [
{"served_model_name": "churn-champion", "traffic_percentage": 90},
{"served_model_name": "churn-challenger", "traffic_percentage": 10}
]
},
auto_capture_config={
"catalog_name": "prod_ml",
"schema_name": "monitoring",
"table_name_prefix": "churn_endpoint"
}
)
)
How Traffic Splitting Actually Works
A single endpoint can host multiple served entities — usually two versions of the
same registered model. The endpoint's traffic_config assigns each route a percentage
of incoming requests, and the gateway distributes calls accordingly.
traffic_config={
"routes": [
{"served_model_name": "churn-champion", "traffic_percentage": 90},
{"served_model_name": "churn-challenger", "traffic_percentage": 10},
]
}
Rules the exam tests:
- Percentages must sum to 100. A configuration totalling 90 or 110 is rejected.
- Splitting happens within one endpoint, behind one URL. Clients are unaware of it and need no change to participate in a canary.
- Shifting traffic is a configuration update, not a redeployment. Moving from 90/10 to 50/50 to 0/100 updates the endpoint config; the model containers are not rebuilt.
- Rollback is the same operation in reverse. Returning the champion to 100% is immediate, which is precisely why canary rollout is safer than an in-place swap.
- Attribution requires logging. To compare the two entities you must know which
served the request; inference tables record that in
request_metadata.
Canary vs. A/B vs. blue-green
| Pattern | Split | Purpose |
|---|---|---|
| Canary | 95/5 or 90/10 | Detect errors, latency regressions, and crashes on a small blast radius |
| A/B test | 50/50 | Measure a business metric difference with statistical power |
| Blue-green | 100/0 then 0/100 | Instant cutover with instant rollback, no mixed-traffic period |
A canary answers "is the new version broken?"; an A/B test answers "is the new version better?". The traffic percentage follows from which question is being asked.
REST API Invocation Formats & Client Integration
Databricks Model Serving endpoints accept standard JSON structures via HTTP POST requests.
Supported Request Formats
dataframe_split(Recommended for tabular data with column names):
{
"dataframe_split": {
"columns": ["age", "tenure", "monthly_charges", "support_tickets"],
"data": [
[34, 12, 65.50, 1],
[52, 48, 110.00, 4]
]
}
}
dataframe_records(Array of key-value objects):
{
"dataframe_records": [
{"age": 34, "tenure": 12, "monthly_charges": 65.50, "support_tickets": 1},
{"age": 52, "tenure": 48, "monthly_charges": 110.00, "support_tickets": 4}
]
}
instances(List of feature vectors):
{
"instances": [
[34, 12, 65.50, 1],
[52, 48, 110.00, 4]
]
}
inputs(Columnar dictionary of arrays or tensor dictionaries):
{
"inputs": {
"age": [34, 52],
"tenure": [12, 48],
"monthly_charges": [65.50, 110.00],
"support_tickets": [1, 4]
}
}
cURL Invocation Example
curl -X POST https://<databricks-instance>/serving-endpoints/customer-churn-serving-endpoint/invocations \
-H "Authorization: Bearer dapi1234567890abcdef" \
-H "Content-Type: application/json" \
-d '{
"dataframe_split": {
"columns": ["age", "tenure", "monthly_charges", "support_tickets"],
"data": [[45, 24, 89.99, 2]]
}
}'
Python Requests Client with Error Handling
import requests
import json
import time
DATABRICKS_HOST = "https://adb-123456789.databricks.com"
TOKEN = "dapi_your_auth_token_here"
ENDPOINT_NAME = "customer-churn-serving-endpoint"
url = f"{DATABRICKS_HOST}/serving-endpoints/{ENDPOINT_NAME}/invocations"
headers = {
"Authorization": f"Bearer {TOKEN}",
"Content-Type": "application/json"
}
payload = {
"dataframe_split": {
"columns": ["age", "tenure", "monthly_charges", "support_tickets"],
"data": [[45, 24, 89.99, 2], [28, 6, 45.00, 0]]
}
}
start_time = time.time()
response = requests.post(url, headers=headers, json=payload, timeout=5.0)
latency_ms = (time.time() - start_time) * 1000
if response.status_code == 200:
predictions = response.json()["predictions"]
print(f"Predictions: {predictions} (Latency: {latency_ms:.2f}ms)")
else:
print(f"Invocation Failed [{response.status_code}]: {response.text}")
Unity Catalog Inference Tables (Request-Response Logging)
Inference Tables provide automated, asynchronous payload logging for all incoming requests and outgoing model responses.
Inference Table Architecture
When auto_capture_config is enabled on an endpoint, Databricks automatically provisions managed Delta Lake tables in the specified Unity Catalog schema:
<catalog>.<schema>.<prefix>_payload: one row per request, with these columns:
| Column | Type | Contents |
|---|---|---|
databricks_request_id | STRING | Databricks-generated request identifier |
client_request_id | STRING | Caller-supplied identifier, when provided |
date | DATE | Partitioning date |
timestamp_ms | LONG | Request timestamp in epoch milliseconds |
status_code | INT | HTTP status returned to the client |
sampling_fraction | DOUBLE | Fraction of traffic sampled into the table |
execution_time_ms | LONG | Endpoint execution latency |
request | STRING | Raw JSON request payload |
response | STRING | Raw JSON response payload |
request_metadata | MAP<STRING,STRING> | Endpoint and served-entity details, including model name and version |
- A batch of inputs sent in one call is logged as a single row, so unpacking the
requestJSON is required before per-record analysis. - Logging is asynchronous and runs outside the inference path, so it does not add to client-visible latency.
Key Use Cases for Inference Tables
- Data & Concept Drift Monitoring: Databricks Lakehouse Monitoring can be attached directly to the Inference Table to track statistical distribution drift between training and serving features over time.
- Auditability & Compliance: Maintains an immutable historical record of exact inputs and model outputs for financial, healthcare, and legal audits.
- Ground Truth Joining for Model Evaluation: Downstream ETL pipelines join inference table payloads with delayed ground-truth labels (e.g., actual customer churn 30 days later) to calculate live precision, recall, and ROC-AUC.
Querying Inference Tables with PySpark SQL
# Read and unpack JSON payloads from Unity Catalog Inference Table
raw_inference_df = spark.table("prod_ml.monitoring.churn_endpoint_payload")
# Unpack request and response fields
unpacked_df = raw_inference_df.selectExpr(
"timestamp_ms",
"date",
"status_code",
"execution_time_ms",
"request_metadata",
"from_json(request, 'struct<dataframe_split:struct<columns:array<string>,data:array<array<double>>>>') as req",
"from_json(response, 'struct<predictions:array<double>>') as resp"
)
display(unpacked_df)
Security & Access Governance
Access to Databricks Model Serving endpoints is strictly governed through Unity Catalog and Workspace Access Control Lists (ACLs):
CAN_QUERYPermission: Grants the ability to execute HTTPS POST inference requests against the endpoint URL. Given to client application service principals and BI tools.CAN_MANAGEPermission: Grants full administrative control to update endpoint configurations, modify served models, adjust traffic split percentages, resize compute, and delete the endpoint. Reserved for ML engineers and CI/CD service principals.CAN_VIEWPermission: Grants read-only visibility to inspect endpoint configuration, health status, and latency metrics in the Databricks UI.
An MLOps team has deployed a production credit risk model. They have trained a new model version and want to route 10% of live production traffic to the new version to monitor latency and error rates before a full rollout. How should this be configured in Databricks Model Serving?
Configure a single serving endpoint containing both served entities and set the traffic route percentages to 90% for the champion and 10% for the challenger.
Create two separate workspace clusters and randomly direct client cURL requests from client-side JavaScript code.
Deploy two separate serving endpoints and configure a Delta Live Tables expectation to filter 10% of requests.
Merge both models into a single Spark ML Pipeline and retrain on the full dataset.
Which of the following JSON structures is a valid format accepted by Databricks Model Serving endpoints for tabular scoring requests?
{"sql_query": "SELECT * FROM features WHERE id = 123"}
{"spark_dataframe": "dbfs:/data/features.parquet"}
{"dataframe_split": {"columns": ["age", "income"], "data": [[30, 75000], [45, 92000]]}}
{"binary_blob": "0x4F3A2B1C"}
What is the primary operational and cost advantage of the 'scale-to-zero' feature in Databricks Real-Time Model Serving endpoints?
It permanently converts real-time models into distributed Spark batch jobs.
It forces all model inference computations to execute exclusively in CPU L1 cache.
It compresses model weights on disk to reduce cloud storage footprint.
It automatically terminates compute container replicas when no incoming traffic is received, reducing compute infrastructure costs to zero while keeping the endpoint URL active.
What is the primary function of Unity Catalog Inference Tables when enabled on a Databricks Real-Time Model Serving endpoint?
They precompute all possible model predictions in batch and cache them in driver RAM.
They automatically log incoming request payloads, model outputs, timestamps, and execution latencies into a managed Delta Lake table asynchronously without adding latency to the response.
They act as an encryption key store for securing OAuth tokens.
They replace the need for Unity Catalog Feature Store tables.
Sections you finish are checked off in the contents.
You've completed this section
Continue exploring other exams