skip to content

How do you choose among Pub/Sub BigQuery subscriptions, Dataflow, direct Storage Write API and the Data Transfer Service?

level: principalimportance: nice to knowfreq 32%

answer

  1. ask what the consumer's freshness SLA really is
  2. transformation need splits pass-through from pipeline
  3. count the components someone must operate at 3am
  4. scheduled pulls from other people's systems are managed

basics

~20 s

Pick by how much transformation you need and who owns the failure modes. Pub/Sub BigQuery subscriptions for raw pass-through, Dataflow when rows need enrichment or windowing, the Storage Write API when your own service already holds the rows, and the Data Transfer Service for scheduled pulls from SaaS and other warehouses.

solid answer

~50 s

I ask three questions. **Does the row need transforming?** If it lands as-is from a topic, a Pub/Sub BigQuery subscription writes it straight to the table with no code to run or operate. If it needs enrichment, joins, windowing or a dead-letter path, that is Dataflow's job. **Who already holds the data?** If my own service produces the rows, calling the Storage Write API directly is the shortest path and avoids a hop, at the price of owning retries, backpressure and stream lifecycle. **Is it a scheduled pull from someone else's system?** Then the BigQuery Data Transfer Service — managed, scheduled, with backfills and run history for SaaS sources, Cloud Storage and other warehouses — and no custom code to maintain. Layered on top: if the freshness SLA is minutes, none of the streaming options is required and scheduled batch loads are cheaper. The decision is mostly about which failure modes the team is willing to own.

code

text · 6 lines
text
needs seconds?   no  -> scheduled load jobs from GCS (no per-byte ingest charge)
                 yes ->
  needs transform? no  -> Pub/Sub BigQuery subscription (managed pass-through)
                   yes -> Dataflow (enrich, window, dead-letter, fan-out)
  we own the producer and can couple to it -> Storage Write API directly
someone else's system, on a schedule       -> BigQuery Data Transfer Service

go deeper

for a junior

Know that BigQuery can be fed by scheduled batch loads, by a Pub/Sub subscription that writes directly to a table, by Dataflow pipelines and by the managed Data Transfer Service.

for a middle

Explain what each path can and cannot do — in particular that a Pub/Sub BigQuery subscription does no transformation and that the Data Transfer Service is a scheduled pull, not an ETL engine.

for a senior

Drive the choice from the consumer's freshness SLA and the transformation requirement, and be explicit about the retries, backpressure and schema evolution you take on by calling the Storage Write API yourself.

for a principal

Own the operational surface and the standing cost across the whole estate: set a default of micro-batching, require a stated SLA to justify streaming, and prefer managed pass-through paths over bespoke clients the team must run.

## Frame it as ownership, not features Every ingestion path into BigQuery ends in the same two places — a load job or the Storage Write API. What differs is who writes the retry logic, who runs the process, and who gets paged. That is the axis a principal-level answer is graded on. ## Pub/Sub BigQuery subscription Pub/Sub can deliver messages **directly** into a BigQuery table by writing through the Storage Write API on your behalf. There is no pipeline to deploy and nothing to run: you configure the subscription with the destination table and either write the whole message into a column or map the topic's schema onto table columns. Use it when the message is already table-shaped and needs nothing done to it. Its limitation is exactly its virtue — there is no place to put transformation logic. Messages that fail to conform go to the subscription's dead-letter topic; anything richer than that belongs elsewhere. ## Dataflow Dataflow (managed Apache Beam) is the choice when rows need real processing on the way in: parsing and validating, joining against a reference source, windowed aggregation, deduplication, fan-out to several sinks, or a custom dead-letter path. It writes to BigQuery via the Storage Write API, and Google publishes templates for the common shapes so "Dataflow" does not automatically mean writing Beam code. The cost is a running service with its own scaling, cost and failure modes. A team that adopts Dataflow to reformat one field has bought an operational surface it did not need. ## Direct Storage Write API from your own service When the rows originate inside a service you already run, calling `AppendRows` from that service removes an entire hop — no queue, no pipeline, lowest latency. In return you own the client: connection management, retries, backpressure when BigQuery pushes back, stream lifecycle if you need exactly-once via offsets, and schema evolution when the table changes shape. This is a fine choice for a mature team and a poor one for a service that must not block on an analytics sink. Buffer or decouple through a queue if losing analytics writes could stall the request path. ## BigQuery Data Transfer Service DTS is a **managed, scheduled pull**. It moves data on a schedule from Google's own SaaS sources (Google Ads, YouTube, Campaign Manager and similar), from Cloud Storage, and from other warehouses and object stores for migrations. It gives you run history, retries and backfills without any code. What it is not is a transformation engine: it lands data on a schedule in the shape the source provides. Reshaping happens afterwards in SQL, which is often the right split — land raw, transform in the warehouse. ## The batch option you should keep considering None of the above is required if the consumer needs minutes rather than seconds. Landing files in Cloud Storage and running scheduled load jobs remains the cheapest path — no per-byte ingestion charge, atomic commits, trivially idempotent reruns. A large share of pipelines built on streaming would have been better and cheaper as micro-batches; establishing the true freshness requirement is the first move, not the last. For change data capture out of operational databases, Google's Datastream is the managed option that lands changes in BigQuery, again with no pipeline code to own. ## A decision sequence 1. **Freshness SLA from the consumer.** Minutes → scheduled batch loads. Seconds → continue. 2. **Transformation required?** No → Pub/Sub BigQuery subscription. Yes → Dataflow. 3. **Do we already own the producing process, and is analytics ingestion safe to couple to it?** Yes → Storage Write API directly. 4. **Is the source someone else's system on a schedule?** → Data Transfer Service. 5. **Duplication tolerance** then selects the stream type underneath whichever path you chose. ## What separates a strong answer Naming the products is the easy half. The judgment is in refusing to let "real-time" be assumed, in counting the operational surfaces the team will have to run at 3am, and in noticing that a managed pass-through path removes a whole class of incidents that a hand-written client will eventually produce. State the assumption you are making about the freshness requirement out loud — that is the variable the whole decision hangs on.

  • When is a Pub/Sub BigQuery subscription the wrong choice despite being the simplest?
    When the message needs work before it lands: enrichment from a lookup source, windowed aggregation, splitting into several tables, or per-record validation with a custom dead-letter path. The subscription is a pass-through with schema mapping and a dead-letter topic; anything richer belongs in Dataflow, or in SQL transformations after landing raw.
  • What does the Data Transfer Service give you that a scheduled load job does not?
    Managed connectors, run history, retries and backfill as first-class features for sources you do not control — Google SaaS products, other warehouses, Cloud Storage on a schedule. A hand-rolled scheduled load job is fine when you already produce the files; DTS earns its place when someone else owns the source and its extraction protocol.
  • A team wants sub-second freshness for a dashboard nobody watches at night. How do you respond?
    Push back on the requirement before designing for it. Sub-second ingestion means a standing ingestion bill and an always-on operational surface. Ask which decision is made faster because the data is one second old rather than five minutes; if none is, micro-batching gives the same business value at materially lower cost and far fewer failure modes.

saying these in an interview costs you the question

  • Choosing Dataflow for pipelines that do no transformation at all
  • Assuming streaming is required without asking the consumer's SLA
  • Calling the Storage Write API from a request path with no decoupling
  • Expecting the Data Transfer Service to transform data on the way in
  • Comparing only features and ignoring who operates each component

context