Is Flink better than Spark for real-time?
Summary
- Neither engine is the right default for every real-time workload. The choice turns on your execution model, how much state you keep and for how long, how often the logic changes, and whether the same code must also run in batch.
- Apache Flink is built for stateful computations over unbounded and bounded streams. Its ProcessFunctions expose per-key state and timers, and savepoints let you stop, update and resume running jobs.
- Apache Spark Structured Streaming runs on the Spark SQL engine and processes micro-batches by default. Real-time Mode, added in Spark 4.1 for Scala stateless queries, is its low-latency option and keeps the same DataFrame API.
- Define "real-time" before you compare. Reacting to each event, keeping results continuously fresh and moving streams into tables are different requirements, and Flink's own docs separate event-driven applications from analytics and data pipelines.
- On Databricks, real-time mode for Structured Streaming is generally available on classic compute, so teams already on Spark can test low-latency workloads before adding a second engine.
Is Flink better than Spark for real-time?
Treat it as a fit question, not a ranking. Apache Flink processes unbounded streams continuously and gives developers low-level control over per-event state and timers. Spark Structured Streaming treats a stream as a table that's updated incrementally, runs micro-batches by default, and added Real-time Mode in Spark 4.1. Workloads built around custom per-event logic and large, long-lived state line up with Flink's model. Workloads that share code, tables and people with Spark batch and ML pipelines line up with Structured Streaming. The criteria below make the choice concrete.
What does "real-time" mean for your workload?
Three different requirements hide behind the word:
- Event-driven reactions. Each incoming event triggers a computation, a state update or an external action, such as an alert. Flink's documentation calls these event-driven applications.
- Continuously updated results. Aggregates and tables stay current as data arrives. Structured Streaming's model runs a query incrementally and updates the final result as new data keeps arriving.
- Streaming pipelines. Data is transformed, enriched and moved from one storage system to another. Flink's docs call these data pipeline applications, and in Spark they're streaming queries that write to a sink such as a table.
Write down a measurable freshness or reaction target for your own use case before comparing engines.
Decision criteria: Flink or Spark Structured Streaming
| Decision question | Points to Apache Flink when | Points to Spark Structured Streaming when |
|---|---|---|
| How must each event be handled? | Logic needs per-key state plus event-time or processing-time timers, which ProcessFunctions provide on keyed streams | Logic fits DataFrame operations, aggregations or transformWithState |
| How large and long-lived is state? | You want a choice of heap or embedded RocksDB state backends | The RocksDB state store provider, which keeps state in native memory and on local disk, fits your state |
| How often will stateful logic change? | Jobs must be updated from savepoints, with stable operator IDs set through uid(String) |
Stateful operators stay stable, since changing them isn't allowed between restarts from the same checkpoint |
| Which languages does the team use? | Java, Python through PyFlink, or Flink SQL | Python, Scala, Java or Spark SQL |
| Must streaming share code with batch? | Table API and SQL queries keep the same semantics on bounded and unbounded input | Streaming queries are written the same way as batch queries on static data |
| Which execution model do you need? | Continuous processing of unbounded streams; STREAMING is the default runtime mode | Micro-batch by default; Real-time Mode for stateless queries (Scala in Spark 4.1, PySpark trigger in Spark 4.2) |
Running both engines on shared tables
You don't have to standardize on one engine. Apache Iceberg supports both Flink's DataStream API and Table API, Delta Lake's Apache Flink connector reads from and writes to Delta tables, and Spark reads and writes both formats. A Flink job can own event-driven logic while Spark jobs run batch transformation and ML on the same tables, with one catalog governing access.
How Databricks approaches real-time processing
Databricks builds its streaming on Spark Structured Streaming. Real-time mode became generally available in March 2026 (announcement). Its reference lists classic compute in dedicated access mode, or standard access mode for Python, and notes that serverless compute isn't supported. It reads from Apache Kafka, Amazon Kinesis and Azure Event Hubs (through the Kafka connector), supports update output mode only, and doesn't support Delta as a source or sink. For mixed estates, Unity Catalog's Iceberg REST catalog lets Apache Flink read from and write to Unity Catalog-registered Iceberg tables.
FAQs
Does Spark Structured Streaming process one event at a time?
Not by default. It processes data as a series of small batch jobs. Real-time Mode, added in Spark 4.1 for Scala stateless queries and extended to PySpark triggers in Spark 4.2, is the low-latency option, and continuous processing remains experimental.
Can Flink run batch jobs?
Yes. The DataStream API has a BATCH runtime mode for bounded programs, set through execution.runtime-mode, and Flink SQL and the Table API return the same results on bounded and unbounded input.
Which engine provides exactly-once results?
Both do, with conditions. Flink guarantees exactly-once state consistency, and end-to-end exactly-once needs sources and sinks that take part in checkpointing. Structured Streaming's micro-batch engine gets there by pairing sources it can replay with sinks that tolerate reprocessing, while continuous processing is at-least-once.
Is Real-time Mode in open-source Spark the same as on Databricks?
Both run on Structured Streaming with a real-time trigger. Upstream Spark 4.1 scoped Real-time Mode to Scala stateless queries, and the Databricks reference also lists aggregations, stream-table joins and transformWithState as supported.
The information provided herein is for general informational purposes only and may not reflect the most current product capabilities or configurations.