Apache Spark in Azure: Synapse and Databricks
Apache Spark runs on Azure in two main places: inside Azure Synapse Analytics as Synapse Spark pools, and on Azure Databricks as a fully managed Spark platform. Both give you the same open-source Spark engine, the same PySpark and Scala APIs, and the same ability to process petabytes of data. But they are optimised for different teams, different workflows, and different architectural patterns.
What Apache Spark is and why it matters
Apache Spark is a distributed computing framework that processes data across a cluster of machines in parallel. It keeps data in memory between operations, making it 10–100x faster than Hadoop MapReduce for iterative algorithms like machine learning. Spark has four main components:
- Spark SQL — query structured data using SQL or the DataFrame API
- Spark Streaming / Structured Streaming — process real-time data streams as mini-batches
- MLlib — a library of distributed machine learning algorithms
- GraphX — graph processing (less commonly used)
Both Synapse Spark and Databricks support all four components. The differences are in cluster management, ecosystem integrations, and developer experience rather than in the underlying Spark capabilities.
Synapse Spark pools: integrated but limited
Synapse Spark pools are Spark clusters managed within a Synapse workspace. They are defined at the pool level (node size, min/max nodes, Spark version) and allocated to sessions on demand. A session starts when you open a notebook and attach it to a pool; the session ends when you close the notebook or the auto-pause timeout fires.
Synapse Spark’s key advantages:
- Native Synapse integration — Spark can read from and write to dedicated SQL pools using the
spark.read.synapsesql()connector without any additional configuration. Credentials flow automatically from the workspace identity. - Shared development environment — SQL analysts and Spark engineers work in the same Synapse Studio with shared access to the same datasets and linked services.
- Lower operational overhead — pool-level configuration is simpler than Databricks cluster configuration. Good for teams that are primarily SQL-oriented and need occasional Spark for heavy ETL.
- Auto-pause — clusters auto-pause after idle minutes with no manual intervention, keeping costs low for intermittent workloads.
# Reading from a Synapse dedicated SQL pool in a Synapse Spark notebook
# The workspace identity handles authentication automatically
df = spark.read.synapsesql("myDedicatedPool.dbo.FactOrders")
# Writing a Spark DataFrame back to a dedicated SQL pool
df_aggregated.write.synapsesql(
"myDedicatedPool.dbo.AggregatedOrders",
options={
"dbTable": "dbo.AggregatedOrders"
}
)Azure Databricks: purpose-built for Spark at scale
Azure Databricks is a managed Spark platform built specifically around Spark as the primary compute engine. It has deeper Spark expertise baked in than Synapse, including the Photon engine, optimised Delta Lake management, and a much richer MLOps ecosystem with MLflow.
Databricks architecture:
┌──────────────────────────────────────────────────────────────┐
│ Azure Databricks Workspace │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ All-Purpose │ │ Job │ │ SQL Warehouse │ │
│ │ Cluster │ │ Cluster │ │ (Photon SQL) │ │
│ │(interactive) │ │ (scheduled) │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Delta Lake (versioned, ACID, ADLS Gen2) │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ MLflow (experiment tracking, model registry) │ │
│ └──────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘Databricks’s key advantages:
- Photon engine — native C++ vectorised execution for SQL and DataFrames, 2–8x faster than standard Spark JVM execution on analytical queries
- Delta Lake — Databricks’s ACID-compliant, versioned table format with Z-order clustering, liquid clustering, and predictive I/O optimisation
- MLflow — built-in experiment tracking, model registry, and deployment. The de facto standard for ML experiment management across the industry
- Job clusters — clusters that spin up for a job, run it, and terminate automatically. More cost-efficient than keeping all-purpose clusters running for scheduled jobs
- Unity Catalog — a centralised data governance and metastore that spans multiple Databricks workspaces
Side-by-side comparison
| Feature | Synapse Spark | Azure Databricks |
|---|---|---|
| Spark engine | Open-source Spark (JVM) | Open-source Spark + Photon (C++ accelerator) |
| Delta Lake | Supported (OSS Delta) | Native, highly optimised (liquid clustering, Z-order) |
| ML/MLOps | Basic (can integrate with AML externally) | Built-in MLflow, model registry, feature store |
| SQL analytics | Spark SQL only | Spark SQL + Databricks SQL (Photon-powered warehousing) |
| Integration with Synapse SQL pools | Native, zero-config | Via JDBC connector (needs manual credential config) |
| Auto-pause idle clusters | Yes (pool-level setting) | Yes (cluster-level auto-terminate) |
| Governance | Microsoft Purview integration | Unity Catalog (cross-workspace governance) |
| Pricing model | vCore-hours (+ Azure VM cost) | DBUs (Databricks Units) + Azure VM cost |
| Cluster config complexity | Low (pool-level node size and count) | Higher (cluster type, runtime, init scripts, policies) |
PySpark example: running on both platforms
This code runs identically on Synapse Spark and Databricks. It reads Delta tables, joins them, aggregates, and writes the result:
from pyspark.sql import SparkSession
from pyspark.sql.functions import (
col, sum as spark_sum, count, avg,
date_trunc, when, percentile_approx
)
spark = SparkSession.builder.getOrCreate()
# On Synapse: path would be abfss://silver@storage.dfs.core.windows.net/...
# On Databricks: path would be /mnt/silver/... or a Unity Catalog table name
orders = spark.read.format("delta").load(
"abfss://silver@mydatalake.dfs.core.windows.net/orders/"
)
customers = spark.read.format("delta").load(
"abfss://silver@mydatalake.dfs.core.windows.net/customers/"
)
# Compute customer lifetime value and segment
clv = (
orders
.join(customers, on="customer_id", how="inner")
.groupBy("customer_id", "customer_name", "country")
.agg(
count("order_id").alias("order_count"),
spark_sum("order_total").alias("lifetime_value"),
avg("order_total").alias("avg_order_value"),
percentile_approx("order_total", 0.5).alias("median_order_value")
)
.withColumn(
"segment",
when(col("lifetime_value") >= 10000, "Platinum")
.when(col("lifetime_value") >= 5000, "Gold")
.when(col("lifetime_value") >= 1000, "Silver")
.otherwise("Bronze")
)
)
# Write back to gold layer
clv.write.format("delta").mode("overwrite").save(
"abfss://gold@mydatalake.dfs.core.windows.net/customer_lifetime_value/"
)
print(f"CLV computed for {clv.count()} customers")
clv.groupBy("segment").count().orderBy("segment").show()The only changes needed to run this on Databricks are the storage paths (or using Unity Catalog table names like spark.read.table(“catalog.silver.orders”)).
When to choose each platform
Choose Synapse Spark when:
- Your team is primarily SQL-oriented and uses Spark occasionally for heavy ETL
- You need tight integration with Synapse dedicated SQL pools
- You want a single tool with both SQL warehousing and Spark in one workspace
- Your team is smaller and you want lower operational complexity
Choose Azure Databricks when:
- Your team is data science-heavy and needs MLflow, feature stores, and model registry
- You process very large datasets (10 TB+) where Photon’s performance advantage matters
- You need multi-workspace governance with Unity Catalog
- You are building Delta Lake as the foundation of your entire data platform
- Your team is Spark-first and will not use dedicated SQL pools at all
Common mistakes
- Using all-purpose (interactive) Databricks clusters for scheduled production jobs. All-purpose clusters are designed for interactive notebooks. Job clusters start fresh for each job run and terminate when done, costing roughly 30–50% less for the same work. Always use job clusters for scheduled ETL.
- Not caching DataFrames that are used multiple times in a notebook. Spark is lazy — it recomputes the full lineage of a DataFrame every time you call an action (count(), show(), write()). If you reference a DataFrame multiple times, call
df.cache()ordf.persist()after its first computation to avoid redundant reads. - Choosing Databricks for a simple Synapse-integrated ETL job. If your job reads from a Synapse dedicated pool, transforms a few columns, and writes back to another Synapse table, Synapse Spark is simpler and the native connector makes authentication trivial. Databricks adds unnecessary complexity for this scenario.
- Over-provisioning cluster sizes. Data engineers often request Large or XLarge nodes by default. Start with Medium nodes and scale up only if you see out-of-memory errors or spill-to-disk warnings. Over-provisioned clusters are the most common source of unnecessary Spark costs.
Summary
- Both Synapse Spark and Azure Databricks run Apache Spark, but they are optimised for different teams and workflows.
- Synapse Spark is simpler, integrates natively with Synapse SQL pools, and works well for SQL-centric teams that use Spark occasionally.
- Azure Databricks has the Photon engine, native MLflow, richer Delta Lake management, and is better for data science-heavy or Spark-first teams.
- Core PySpark code runs identically on both — only storage paths and platform-specific features differ.
- Use job clusters (Databricks) or auto-pause (Synapse) to avoid paying for idle Spark compute.
Frequently asked questions
Can I run the same PySpark code on both Synapse and Databricks?
Mostly yes. Standard PySpark code using DataFrames, SQL, and the standard library runs identically on both. The differences appear when you use platform-specific features: Databricks has its own Delta Lake implementation, MLflow integration, and proprietary Photon engine. Synapse Spark has native integration with dedicated SQL pools and Synapse Link.
Is Azure Databricks an Azure service?
Azure Databricks is a first-party service on Azure, jointly developed by Microsoft and Databricks. It appears in the Azure portal, uses Azure Active Directory for authentication, and integrates with Azure storage and networking. However, the Databricks control plane is managed by Databricks, Inc., not Microsoft, making it a jointly-managed service rather than a pure Microsoft service.
What is the Photon engine in Databricks?
Photon is Databricks's proprietary vectorised query engine written in C++. It replaces the standard JVM-based Spark SQL execution for SQL workloads and certain DataFrame operations, achieving 2–8x speedups on analytical queries. It is available on Databricks Runtime 9.1+ and is particularly effective for queries that would otherwise benefit from Synapse's dedicated SQL pool.