HomeArticles

Chapter 2 of Analytics databases: ClickHouse, Postgres and warehouses

GCP Dataflow vs Dataproc: The Real-World Decision Guide

GCP Dataflow versus Dataproc: managed Beam streaming against managed Spark, cost, control, existing code, ML workloads, hybrid use and team skills.

Dataflow vs Dataproc in three questions: streaming or batch, existing Spark code, and how much ops time the team has.

You're building a data pipeline on Google Cloud. Someone says "use Dataflow." Someone else says "DataProc is simpler." Both are wrong — and both are right. This choice still trips up teams that should know better.

Here's the truth: Dataflow and Dataproc solve different problems. But Google's marketing makes them look interchangeable. They're not. Pick wrong and you'll burn months of engineering time. Pick right and you'll sleep through pipeline failures.

This guide shows how to decide, with code for both.

What We're Actually Comparing

Dataflow is Google's fully managed stream and batch processing service based on Apache Beam. It handles auto-scaling, checkpointing, and exactly-once semantics out of the box. You write Beam pipelines — Java, Python, or SQL — and Google manages the workers.

Dataproc is managed Spark and Hadoop. It's a cluster manager that spins up VMs, installs Spark/Hive/Presto, and tears them down when you're done. You control the cluster size, the software versions, and the failure handling.

Both process data. Both scale. But they're built for fundamentally different workloads.

The Core Difference Nobody Talks About

Here's the contrarian take: Dataflow is for pipeline thinking. Dataproc is for cluster thinking.

With Dataflow, you define transformations and Google decides how many workers to run. With Dataproc, you decide the cluster size and Spark decides how to split work across nodes.

Most teams think this is a minor architectural choice. It's not. It determines your operational model, your debugging workflow, and your cost structure.

When Dataflow Wins (And Why It Stings Sometimes)

Streaming is Dataflow's Killer Feature

If your data arrives in real-time — clickstreams, IoT sensors, financial transactions — Dataflow is the obvious choice. It maintains state across windows, handles late-arriving data, and provides sub-second latency.

The Beam model of event-time processing and watermarks removes the need for custom checkpointing code. With Spark Streaming on Dataproc, expect to spend time tuning batch intervals.

Auto-scaling That Actually Works

Dataflow's autoscaler is absurdly good. It predicts needed workers based on backlog, scales up before latency spikes, and scales down when throughput drops. Dataproc's autoscaler? It's reactive. By the time it adds nodes, your Spark jobs are already failing with OOM errors.

The Cost Trap

Here's where most people get burned. Dataflow's streaming pricing is high — $0.056 per Compute Engine unit-hour plus per-GB data processing. Dataproc's basic compute pricing is cheaper per core-hour.

But total cost includes your engineering time. Dataflow jobs that run for months without breaking? That's zero ops cost. Dataproc clusters that need nightly tuning? That's a full-time engineer.

When Dataproc Dominates

You Need Control

Dataflow is a black box. You can't control the JVM flags. You can't pin specific worker types. You can't run custom monitoring agents.

Dataproc gives you full SSH access to workers. You can install anything. You can tune Spark's memory allocation down to the executor level.

If your processing needs custom libraries that conflict with Beam's dependencies, Dataproc with a custom image is the option.

Existing Spark Code

If you have 50,000 lines of PySpark running in production, rewriting it as Beam pipelines is a year-long project. Dataproc runs Spark as-is. No rewrites. No refactoring.

Converting working Spark code to Beam takes a long time and does not by itself make the pipeline faster.

ML Training Pipelines

Dataproc integrates tightly with AI Platform for distributed training. Dataflow doesn't. If your pipeline feeds GPU-heavy model training, Dataproc's co-located compute is simpler.


SIDEBAR: gcp dataflow vs dataproc for batch processing

This is where the choice gets muddy. Both handle batch. Dataflow's batch mode is actually Beam's batch runner — it processes bounded data the same way as streams. Dataproc's batch is traditional Spark.

For batch jobs under 1TB, Dataflow is faster to iterate on. You write a pipeline, test locally, deploy to cloud. No cluster management.

For batch jobs over 10TB, Dataproc wins. Spark's shuffle is more efficient for massive datasets. Dataflow's shuffle can hit disk bottlenecks.


Code: Real Pipelines

Dataflow Streaming Pipeline (Python)

import apache_beam as beam
from apache_beam.options.pipeline_options import PipelineOptions

options = PipelineOptions(
    streaming=True,
    project='my-project',
    runner='DataflowRunner',
    temp_location='gs://my-bucket/temp',
    region='us-central1'
)

with beam.Pipeline(options=options) as p:
    (p
     | 'ReadFromPubSub' >> beam.io.ReadFromPubSub(
         subscription='projects/my-project/subscriptions/events'
     )
     | 'ParseJson' >> beam.Map(lambda x: json.loads(x.decode('utf-8')))
     | 'FilterHighValue' >> beam.Filter(lambda x: x['amount'] > 10000)
     | 'WindowInto' >> beam.WindowInto(
         beam.window.FixedWindows(60),
         allowed_lateness=beam.window.Duration(5 * 60)
     )
     | 'WriteToBigQuery' >> beam.io.WriteToBigQuery(
         table='my-project:analytics.high_value_events',
         write_disposition=beam.io.BigQueryDisposition.WRITE_APPEND
     ))

This pipeline runs continuously.

Dataproc PySpark Batch Job

from pyspark.sql import SparkSession
from pyspark.sql.functions import col, window

spark = SparkSession.builder     .appName("daily_aggregation")     .config("spark.sql.shuffle.partitions", "500")     .config("spark.executor.memory", "4g")     .config("spark.dynamicAllocation.enabled", "true")     .getOrCreate()

df = spark.read.parquet("gs://my-bucket/raw/events/")
aggregated = df     .groupBy(window("timestamp", "1 hour"), "user_id")     .agg({"amount": "sum"})     .filter(col("sum(amount)") > 50000)

aggregated.write     .mode("overwrite")     .parquet("gs://my-bucket/aggregated/hourly_high_value/")

Notice the manual partition config? Dataflow wouldn't need it. But Dataflow also wouldn't let you tune it if something went wrong.

gcp cloud run vs kubernetes — The Companion Decision

Comparison of Cloud Run + Dataflow (serverless, event-driven) vs GKE + Dataproc (Kubernetes teams, Spark libraries)

You can't talk about Dataflow vs Dataproc without addressing the orchestration layer. Your data pipelines need processing, but they also need service infrastructure.

["Cloud Run vs Kubernetes influences your Dataflow vs Dataproc decision more than you'd think."]

Two common patterns:

  • Cloud Run + Dataflow: Serverless everything. Cloud Run hosts microservices that trigger Dataflow jobs. No cluster to manage. Best for event-driven pipelines.

  • GKE + Dataproc: Kubernetes manages your Spark clusters. Dataproc runs on GKE nodes. You get Kubernetes' resilience with Spark's processing. Best for teams already running Kubernetes.

Cloud Run + Dataflow is the simpler default for new projects. GKE + Dataproc fits when there is an existing Kubernetes investment or a need for Spark-specific libraries.

The Hybrid Approach Nobody Talks About

Most articles present this as either/or. That's wrong.

A strong architecture uses both:

  1. Dataflow for the real-time streaming layer (ingestion, enrichment, alerts)
  2. Dataproc for the heavy batch layer (daily aggregations, model training)

The streaming pipeline writes to BigQuery and Parquet. The batch pipeline reads from Parquet and produces ML features. No single job does everything.

Cost Comparison

Dataproc's cheaper compute often doesn't make up for its ops overhead.

But here's the kicker: if you already have Spark expertise on staff and your pipeline runs 24/7, Dataproc's lower compute cost wins.

Choosing Based on Team Skillset

Be honest: what does your team know?

  • Data engineers who know Beam: Dataflow is natural. They understand windows, PCollections, and side inputs.

  • Data scientists who know Spark: Dataproc is safer. PySpark has lower cognitive overhead for SQL-heavy transformations.

["Skillset alignment is the single biggest factor I see overlooked. Choose the tool your team can debug at 2 AM."]

FAQ

Can Dataflow run Spark jobs?

No. Dataflow runs Beam pipelines. Spark code won't run on Dataflow. If you need Spark, use Dataproc.

Is Dataproc good for streaming?

It's okay. Spark Structured Streaming works on Dataproc. But it's not as robust as Dataflow. You'll need to handle checkpointing, late data, and state management yourself.

Which is cheaper for small jobs?

For jobs under 1TB data and running less than 2 hours, Dataflow is cheaper. No cluster management overhead. Dataproc minimum cluster size adds cost.

Can I use both in one pipeline?

Yes. A common architecture uses Dataflow for real-time and Dataproc for batch. They integrate through GCS, BigQuery, or Pub/Sub.

Does Dataflow support custom containers?

Yes. You can use custom Docker images with the Beam PortableRunner. But it's complex. Dataproc's custom images are simpler.

Which has better monitoring?

Dataflow has the better out-of-box experience. The pipeline graph with step-level latency and throughput is excellent. Dataproc relies on Spark UI and GCP Monitoring dashboards.

What about serverless Spark alternatives?

Dataproc Serverless exists. It's better than standard Dataproc but still less mature than Dataflow.

The Decision Framework

A simple three-question test:

  1. Is your data streaming or batch? Streaming → Dataflow. Batch → ask question 2.

  2. Do you have existing Spark code? Yes → Dataproc. No → ask question 3.

  3. How much ops time do you have? Under 2 hours/week → Dataflow. Over → Dataproc.

It's not perfect, but it is a good starting point.

Final Thoughts

Pick Dataflow for greenfield streaming with managed workers; pick Dataproc for existing Spark and fine-grained control.

The gcp dataflow vs dataproc debate isn't a technical competition. It's an operational one.

Dataflow is Google saying "trust us with the complexity." Dataproc is Google saying "here are the levers, you fly the plane."

If you're building greenfield and your data is mostly streaming, pick Dataflow. Your team will thank you at 3 AM when the pipeline auto-heals a node failure.

If you're running existing Spark workloads or need fine-grained control, pick Dataproc. Just budget for the ops time.

And if someone tells you one is always better than the other? They haven't run either in production for a year.

Want to talk this through?

Sivaro Enterprise →