Model Deployment · Topic 1 of 2

Batch, Streaming and Real Time Inference

Databricks ML Associate: choose batch, streaming or real time inference, score a pandas DataFrame with MLflow, and apply a model in a pipeline.

  • 5 min
In a nutshell
  • Batch is cheapest and fits scheduled scoring; streaming fits continuous events; real time fits per request answers in milliseconds.
  • mlflow.pyfunc.load_model(uri).predict(pandas_df) scores a pandas DataFrame on one machine.
  • mlflow.pyfunc.spark_udf(spark, uri) turns the model into a UDF so Spark scores large tables in parallel.

What it is

Inference means using a trained model to score new data. On Databricks the same registered MLflow model can be used in three ways: batch (score a whole table on a schedule), streaming (score records as they arrive) and real time (answer one request at a time behind a REST endpoint).

The exam describes a workload and asks which approach fits, then asks how the batch or streaming version is written. Real time endpoints have their own page in this chapter.

Registered modelmodels:/catalog.schema.model@championBatchpandas or spark_udfDelta table of predictionsRegistered modelmodels:/catalog.schema.model@championStreamingpipeline UDFStreaming table of predictionsRegistered modelmodels:/catalog.schema.model@championReal timeserving endpointREST response

How it works

Comparing the three approaches

ApproachLatencyTypical useMain advantage
BatchMinutes to hoursNightly churn scores, weekly segmentsCheapest and simplest; compute runs only while the job runs
StreamingSecondsFraud or anomaly flags on event streamsScores data continuously as it lands, at high throughput
Real timeMilliseconds per requestA web app asks for a recommendationLowest latency for single requests, through a REST API

Batch is the default whenever nobody needs an answer before the next scheduled run. It scores millions of rows in one job, writes them to a Delta table, and downstream reports or apps read that table.

Streaming is driven by data arriving, not by a caller waiting for a reply. Real time needs an always available endpoint, so it costs the most per prediction.

Batch inference with pandas

For data that fits in driver memory, load the model as a generic pyfunc and call predict on a pandas DataFrame.

import mlflow
mlflow.set_registry_uri("databricks-uc")
model = mlflow.pyfunc.load_model("models:/main.ml.churn@champion")
pdf = spark.table("main.ml.customers").toPandas()
pdf["prediction"] = model.predict(pdf[["tenure", "plays", "skips"]])

The @champion alias means the job always scores with whichever version holds that alias, so promoting a new version needs no code change.

Batch inference at scale with spark_udf

When the table is too large for one machine, wrap the model as a Spark UDF so every worker scores its own partitions.

predict = mlflow.pyfunc.spark_udf(spark, "models:/main.ml.churn@champion")
df = spark.table("main.ml.customers")
scored = df.withColumn("prediction", predict("tenure", "plays", "skips"))
scored.write.mode("overwrite").saveAsTable("main.ml.churn_scores")

If the model was logged with a feature engineering training set, FeatureEngineeringClient().score_batch(model_uri=uri, df=df) looks up the features from the feature tables for you, so df only needs the lookup keys and any features not stored in feature tables.

Streaming inference with Delta Live Tables

Delta Live Tables is now called Lakeflow pipelines, built on Apache Spark Declarative Pipelines; existing dlt code still runs. For streaming inference, the model is loaded as a Spark UDF and applied to a streaming source inside a pipeline table definition.

import dlt
import mlflow
predict = mlflow.pyfunc.spark_udf(spark, "models:/main.ml.churn@champion")

@dlt.table
def scored_events():
    df = spark.readStream.table("main.ml.events")
    return df.withColumn("prediction", predict("tenure", "plays", "skips"))
Event sourcestreaming readPipeline tablespark_udf on each micro batchStreaming tablescored events

The pipeline processes new records incrementally, manages checkpoints and retries, and can autoscale its compute as event volume changes. The model runs on the pipeline's own cluster, with no network call per record.

Worked example

A retailer wants scores for 2 million customers ready by 06:00. A nightly batch job scores all 2 million rows, then the cluster shuts down.

A podcast app emits tens of thousands of events per second and wants low engagement flagged within seconds. A pipeline that applies the model as a Spark UDF over the event stream fits; calling a serving endpoint once per event would add network overhead for no benefit.

How the exam asks about this

  • "Scores are needed once a night for the whole customer table; no low latency requirement." Batch inference on a schedule, the most cost effective choice.
  • "A data scientist has a 50,000 row pandas DataFrame and a registered model." Call mlflow.pyfunc.load_model(uri).predict(pdf).
  • "Events arrive continuously at high volume and the pipeline compute must resize as volume changes." Apply the model as a Spark UDF in a Delta Live Tables pipeline, not through a serving endpoint.

What to remember for the exam

  • Batch is cheapest and fits scheduled scoring; streaming fits continuous events; real time fits per request answers in milliseconds.
  • mlflow.pyfunc.load_model(uri).predict(pandas_df) scores a pandas DataFrame on one machine.
  • mlflow.pyfunc.spark_udf(spark, uri) turns the model into a UDF so Spark scores large tables in parallel.
  • Streaming inference in Delta Live Tables applies the model as a Spark UDF over a streaming read inside a pipeline table.
  • Load by alias (models:/catalog.schema.model@champion) so jobs and pipelines pick up a promoted version without edits.
  • score_batch on the Feature Engineering client looks up features automatically for a model logged with a training set.
Watch out

Do not pick a real time endpoint just because it sounds modern. If the scenario has no caller waiting for a reply, batch or streaming is cheaper and is the expected answer.

Common mistakes

Calling an endpoint from a streaming job. Routing every event through a Model Serving endpoint adds a network hop and endpoint cost. Inside a pipeline, applying the model directly as a Spark UDF is simpler and scales with the cluster.

Using toPandas on a huge table. Collecting billions of rows to the driver can run out of memory. Use spark_udf so the work is spread across workers.

Hard coding a version number. Loading models:/main.ml.churn/3 means the job keeps using version 3 after a better model is promoted. Loading by alias follows the promotion.

Check yourself

  • Which approach fits scores needed once a day for every customer, with no latency requirement?

    Batch inference on a schedule, because it is the cheapest and nobody waits for an individual prediction.

  • How do you score a pandas DataFrame with a model registered in Unity Catalog?

    Load it with mlflow.pyfunc.load_model("models:/catalog.schema.model@alias") and call predict on the DataFrame.

  • How is a model applied for streaming inference in a Delta Live Tables pipeline?

    It is loaded with mlflow.pyfunc.spark_udf and applied with withColumn to a streaming read inside a pipeline table definition.

Topic 1 of 2 in Model Deployment

Test yourself on Model Deployment

The full Databricks Machine Learning Associate question bank has 600 questions, with timed practice exams and an explanation for every answer.

This study guide is independent and is not affiliated with, endorsed by, or sponsored by Databricks. Vendor names, certification names and exam codes are trademarks of their respective owners and are used for identification only.