Enterprises today serve customers across continents, from New York to Singapore, London to São Paulo. For these organizations, delivering fast, reliable user experiences is a business requirement: latency can directly impact conversion rates, user satisfaction, and ultimately, revenue. Furthermore, mission-critical, user-facing applications need a multi-region / multi-cloud strategy to ensure reliability in the modern cloud computing environment
Consider a real-time fraud detection system or personalized recommendation engine serving users worldwide. A customer in Frankfurt requesting a prediction from a model endpoint hosted in US-East (Virginia) experiences a round-trip latency of approximately 80-120 milliseconds due to network transit alone. Compare this to an intra-region request within Europe (say, Frankfurt to Frankfurt), which typically completes in 1-5 milliseconds for network transit latency. When your ML model inference adds another 50-200ms on top of network latency, that European user could be waiting 300ms or more for a response, an eternity in modern web applications where latency can directly impact conversions.
The challenges of single-region serving extend beyond just latency:
Setting up a model serving in a single region on Databricks is well-covered ground. The platform docs walk through it end-to-end, and we recap it briefly in Part 1. The harder problem, and the focus of this guide, is what comes next: taking a model and its features that already live in one region and standing up low-latency serving in another. You'll see how to provision a serverless workspace in a second region with Terraform, distribute your feature table and model across regions using OpenSharing (without data copies), and configure a low-latency endpoint that reads directly from shared data. By the end, you'll have a repeatable playbook for delivering ML predictions close to users anywhere in the world.
This architecture also ensures cross-region resilience. Because each region runs a complete, independent serving stack with its own Lakebase online store and Model Serving endpoint, a regional outage is no longer an all-or-nothing event. If us-east-1 becomes unavailable, the endpoint in us-west-2 keeps serving predictions and features uninterrupted, because it reads from its own in-region online store rather than reaching back to the failed region. Point your traffic manager or DNS at the healthy region, and inference continues. What would have been a total outage for a single-region deployment turns into a routing change.
At a high level, one region acts as the provider and every additional region is a recipient. The provider region owns the source of truth: the offline feature table in Delta and the model registered in Unity Catalog. OpenSharing exposes both assets to recipient regions through secure, scoped credentials, making it easy to keep data in sync across regions. Each recipient region then builds a thin, in-region serving stack on top of the share: a Lakebase online store that syncs from the shared feature table and a Model Serving endpoint that serves the shared model. You train once and share, so each new region does not require retraining of the model or recomputation of the features.
Before going multi-region, you need a working single-region serving stack in your provider region. This is standard feature serving, so we keep it brief. For this guide we use a fraud detection use case: an account-level feature table scored at transaction time.
The single-region stack is five steps:
Part 2 depends on two outputs of this stack: the offline account_features table and the fraud_detection_model in UC. Everything that follows serves these in a second region without copying data or retraining.
We'll add a second region in three moves: provision a serverless workspace and metastore, share the feature table and model into it with OpenSharing, and stand up an in-region serving stack that reads from the share.
Throughout, the provider is the region from Part 1 (say us-east-1) and the recipient is the new region (say us-west-2).
A serverless workspace is the fastest way to add a region: no customer-managed networking, storage, or IAM. Databricks manages compute and networking, so there's no VPC, S3 root bucket, or cross-account role. In Terraform this is a single resource with compute_mode = "SERVERLESS". Each region also needs its own Unity Catalog metastore, so we create one and assign it to the new workspace.
Because creating workspaces and metastores are account-level operations, these run against the account-level Databricks provider (host = "https://accounts.cloud.databricks.com"), not a workspace host.
# Serverless recipient workspace: no networking/storage/credentials required.
resource "databricks_mws_workspaces" "recipient" {
provider = databricks.mws
account_id = var.databricks_account_id
workspace_name = var.workspace_name
aws_region = var.aws_region # e.g. us-west-2
compute_mode = "SERVERLESS"
}
# Recipient Unity Catalog metastore, assigned to the new workspace.
resource "databricks_metastore" "b" {
provider = databricks.mws
name = var.metastore_name
region = var.aws_region
force_destroy = true
}
resource "databricks_metastore_assignment" "b" {
provider = databricks.mws
workspace_id = databricks_mws_workspaces.recipient.workspace_id
metastore_id = databricks_metastore.b.id
}
Link to Terraform docs. After terraform apply, note the new metastore's global sharing identifier (SELECT current_metastore(); in the new workspace or the account console). The provider region needs it in the next step.
We bridge the two metastores with Databricks-to-Databricks OpenSharing. The provider creates a share containing the feature table and the model, then grants it to a recipient identified by the recipient metastore's sharing identifier, reading the provider's storage through scoped, time-limited credentials.
%SQL
-- Provider (Metastore A): create the share + recipient, then add the assets
CREATE SHARE IF NOT EXISTS fraud_serving_share;
CREATE RECIPIENT IF NOT EXISTS region_b_recipient
USING ID 'aws:us-west-2:metastore-b-sharing-identifier';
ALTER SHARE fraud_serving_share ADD TABLE sample_catalog.sample_schema.account_features;
ALTER SHARE fraud_serving_share ADD MODEL sample_catalog.sample_schema.fraud_detection_model;
-- Alternatively, if these assets reside in the same schema, you could just share the entire schema
GRANT SELECT ON SHARE fraud_serving_share TO RECIPIENT region_b_recipient;
Sharing the model with the table lets the recipient serve without retraining or copying artifacts.
On the recipient side, mount the share as a read-only catalog. The shared table and model then appear as ordinary Unity Catalog objects: queryable, governable, and ready to serve.
Run this in the recipient region:
%SQL
-- Recipient (Metastore B): mount the share as a catalog
CREATE CATALOG IF NOT EXISTS shared_from_provider
USING SHARE provider_name.fraud_serving_share;
GRANT USE CATALOG, SELECT ON CATALOG shared_from_provider TO `account users`;
provider_name is how Metastore B refers back to Metastore A. Discover it with SHOW PROVIDERS.
The final move rebuilds the serving stack in the recipient region but reads from the share rather than local objects. Lakebase is provisioned exactly as in Part 1 (same create_project call, in this region). The one line that changes is the sync source: the synced table points at the shared offline table, so the online store syncs continuously from the provider with no local copy.
# Recipient synced table: source is the Delta-Shared table, everything else is identical to Part 1.
w.postgres.create_synced_table(
synced_table_id=f"{catalog}.{schema}.account_features_online",
synced_table=SyncedTable(spec=SyncedTableSyncedTableSpec(
branch=BRANCH,
postgres_database=catalog,
source_table_full_name="shared_from_provider.sample_schema.account_features", # <-- the share
scheduling_policy=SchedulingPolicy.CONTINUOUS,
primary_key_columns=["user_id"],
create_database_objects_if_missing=True,
accelerated_sync=True,
new_pipeline_spec=NewPipelineSpec(storage_catalog=catalog, storage_schema=schema),
)),
)
Link to Databricks Python SDK documentation. Likewise, the serving endpoint is created exactly as in Part 1, but its served entity is the shared model, shared_from_provider.sample_schema.fraud_detection_model, instead of a local one.
Feature lookups resolve against the local Lakebase instance you just created, so inference stays entirely in-region. For a third or fourth region, repeat this section (provision, share, serve).
Serving ML models globally has meant a tradeoff: accept the latency, compliance, and availability costs of a single region, or build bespoke replication yourself. This architecture avoids both, because the platform pieces compose:
That independence makes this a high-availability setup, not only a latency optimization. Each region serves from its own store and endpoint, so losing us-east-1 does not take down us-west-2. You failover by shifting traffic instead of rebuilding infrastructure under pressure.
This answers the challenges we opened with: lower latency, respected data residency, higher availability, and controlled cost, without a replication service or custom glue code. Register an asset once and serve it everywhere, letting one team deliver fast, compliant, resilient predictions worldwide.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.