Docs /Tools and APIs /Data Transfer Service
Tools and APIs

BigQuery Data Transfer Service explained

The BigQuery Data Transfer Service loads data into BigQuery on a schedule from SaaS apps, Google ad and analytics products, other clouds and other warehouses. Many connectors are free, the rest are billed in slot-hours, and scheduled queries and dataset copies run on the same machinery.

The BigQuery Data Transfer Service (DTS) is a managed scheduler with a library of connectors. You pick a source, a destination dataset and a schedule, and BigQuery pulls the data in on every run, with no code and no servers to run. It only loads data into BigQuery, never out. Two features you may already use are also built on it: scheduled queries and dataset copies are transfer configurations too.

What it can load

Google’s list, as of its 2026-10-05 update:

GroupSources
SaaSSalesforce, Salesforce Marketing Cloud, ServiceNow
MarketingFacebook Ads, HubSpot (Preview), Klaviyo (Preview), Mailchimp (Preview)
Payments and commercePayPal, Stripe, Shopify (all Preview)
Databases and warehousesAmazon Redshift, Apache Hive Metastore, Microsoft SQL Server (Preview), MySQL, Oracle, PostgreSQL, Snowflake, Teradata
Object storageCloud Storage, Amazon S3, Azure Blob Storage
Google productsGoogle Ads, Google Ad Manager, Campaign Manager, Display & Video 360, Google Analytics 4, Search Ads 360, Merchant Center (Preview), CSS Center (Preview), Google Play, YouTube Channel, YouTube Content Owner

Partners also publish connectors on Cloud Marketplace.

We listed the data sources the API reports for a project: 35, including one that Google’s list doesn’t mention, databricks_unity (Databricks Unity Catalog). The API also reports the minimum gap between runs per source, which the docs only give for a few:

SourceMinimum interval between runs
Scheduled query5 minutes
Cloud Storage, MySQL, PostgreSQL, Oracle, SQL Server, Databricks Unity Catalog, Salesforce, Salesforce Marketing Cloud, ServiceNow, HubSpot, Klaviyo, Shopify, Stripe, PayPal15 minutes
Hive Metastore30 minutes
Amazon S3, Azure Blob Storage, Snowflake, Teradata, Mailchimp1 hour
Google Ad Manager4 hours
Merchant Center6 hours
Dataset copy12 hours
CSS Center24 hours

Google Ads, GA4, Search Ads 360, Display & Video 360, YouTube, Google Play, Campaign Manager and Facebook Ads report no minimum. Campaign Manager and Ad Manager default to a run every 8 hours; every other source defaults to every 24 hours. Redshift reports no schedule at all.

What a transfer does on each run

A transfer configuration has a source, a destination dataset, a schedule and credentials. Each scheduled time creates a run, and the run starts load jobs (and, for some sources, merge jobs) into tables in the destination dataset. A few things follow from that:

  • The transfer lives in the destination dataset’s location. The configuration, the staging and the processing all happen there. The location of the source data doesn’t matter. Create the dataset first. For the Teradata migration, the staging bucket in Cloud Storage must be in the same location as the dataset.
  • A run is a load job, so load quotas apply. Google gives a formula for how many load jobs a project burns: transfers times tables per transfer times runs per day times the refresh window. A Google Ads transfer creates about 60 tables, Search Ads 360 about 50, so a few of them at a short refresh window can hit the daily load-job quota and make other loads fail with quotaExceeded. Scheduled queries are not transfers in this sense and don’t count against load limits.
  • Credentials belong to a transfer owner. The owner can be a user or, for sources that support it, a service account. Runs read the source with the owner’s credentials, so the transfer depends on that identity. Google documents an Update credentials action for changing it.
  • Run history is kept for 90 days, then deleted. Logs and run metrics go to Cloud Logging and Cloud Monitoring (the metric resource type is BigQuery DTS Config: active run count, completed run count and run latency).
  • DTS jobs use slots from a reservation only if your project, folder or organization is assigned to one with QUERY or PIPELINE job types. Dataset copy jobs never use reservation slots.

Cloud Storage transfers are not the same as a load job

A recurring Cloud Storage transfer looks like bq load on a timer, with rules worth knowing:

  • The destination table must already exist, and for CSV and JSON you must define its schema. A one-time load can create the table; a recurring transfer can’t.
  • The default write preference is APPEND. An unmodified file is loaded only once. If a file’s last-modified time changes, it is loaded again, which can duplicate rows. MIRROR instead overwrites the table on each run.
  • Every file matching the pattern must share one schema. A schema change between runs fails the transfer.
  • Archived (non-live) object versions aren’t read.
  • Google doesn’t guarantee that files modified during a run are loaded exactly once.
  • The minimum interval is 15 minutes. For fresher data, use an event-driven transfer: Cloud Storage notifies Pub/Sub when an object is added, and the transfer runs, with a wait of up to 10 minutes before the next run. Google recommends it for incremental ingestion that is cheap, and the Storage Write API for anything that must be near real time. See Streaming and Loading data.

Backfills

Most connectors let you rerun for a date or date range. You can start one from the console (Run transfer now, or Schedule backfill) with bq mk --transfer_run, or through the startManualRuns API call. The limits are the same everywhere:

  • A request covers at most 180 days. For longer, split it into 180-day chunks and wait for each to finish.
  • Simultaneous backfill requests aren’t supported.
  • How far back you can go depends on the source. Check its transfer guide.
  • A large backfill can take hours or days.

What it costs

The DTS charge is compute, in slot-hours, in two parts: orchestration (running the connector) and data loading and processing. Google’s pricing page says:

PartCost
Orchestration, free connectorsnothing. Cloud Storage, Amazon S3, Azure Blob Storage, Google Ads, Ad Manager, Campaign Manager, Display & Video 360, GA4, Search Ads 360, YouTube, Merchant Center, CSS Center, Redshift, Teradata, Snowflake migration, Hive
Orchestration, paid connectorsslot-hours. GA: Salesforce, ServiceNow, Salesforce Marketing Cloud, Facebook Ads, MySQL, PostgreSQL, Oracle. Preview connectors (Stripe, PayPal, HubSpot, Klaviyo, SQL Server) aren’t charged until they reach GA
Google Play$25 per month per unique package name in the Installs country table, prorated
Partner connectorsset by the partner
Loading into native tablesfree (standard load jobs)
Merge into native tablesstandard BigQuery rates
Loading and merging into Iceberg tablesstandard rates for those tables

For paid connectors the default price list shows $0.06 per slot-hour, and prices vary by region. Google’s rule of thumb for planning is up to 20 slot-hours for each hour a transfer runs, which comes to about $1.20 per run-hour in us-central1. That is an upper bound for budgeting, not a measurement.

Beyond that, you pay normal BigQuery storage and query costs for the data once it lands, plus anything the other side charges. Google calls out AWS and Azure data transfer fees for S3 and Blob transfers, and storage cost for files that stay in your Cloud Storage bucket after loading, because transfers don’t delete them unless you ask (the Cloud Storage option “Delete source files after transfer” is best effort).

To see the total, filter the billing report by the label key goog-bq-feature-type with value DATA_TRANSFER_SERVICE. Google says that from 11 August 2026 all DTS SKUs are unified under the value data_transfer_service, so check which spelling your billing data shows. See labels and billing export for querying it.

Scheduled queries and dataset copies

Both are transfer configurations. Scheduled queries use the data source scheduled_query and are the cheapest way to run recurring SQL: bytes billed as for any query, no DTS fee. Dataset copy (cross_region_copy) copies a dataset to another dataset, including across locations, with a 12-hour minimum between runs. You can find them with the same commands as other transfers:

bq ls --transfer_config --transfer_location=us \
  --filter=dataSourceIds:scheduled_query,cross_region_copy

Which tool to use

You wantUse
Daily files from Cloud Storage, S3 or Blob Storagea DTS transfer (event-driven for files that arrive irregularly)
Salesforce, Google Ads, GA4 and similarthe DTS connector, if one exists
Recurring SQL inside BigQuerya scheduled query
Moving a warehouse (Teradata, Redshift, Snowflake) oncethe DTS migration connectors, then see migrating to BigQuery
Rows within seconds from your applicationthe Storage Write API
Applying row changes with upserts and deletesnot DTS schedules: see change data capture

The Data delivery SLO applies only to scheduled transfers from sources inside Google Cloud. For third-party sources, an outage on their side affects your runs and the SLO doesn’t cover it.