BigQuery Data Transfer Service in Google Cloud
A friendly, step-by-step guide to the service that automatically brings data from ad platforms, files, other clouds, and other warehouses into BigQuery on a schedule: what it is, how a transfer runs inside, how to set it up safely, and how to fix it when it misbehaves.
Imagine you run a large grocery chain. Every morning, trucks arrive from dozens of suppliers carrying boxes of different shapes. Some boxes come from a dairy, some from a bakery, some from a farm across the border. A worker must receive each delivery, check the label, carry the boxes to the right shelf in the warehouse, and write down that it arrived. If the worker oversleeps, the shelves stay empty and the shops cannot sell. Now imagine you could hire a reliable robot that knows each supplier’s schedule, collects every delivery at the right time, places everything on the correct shelf, and sends you a message if a truck is late.
The BigQuery Data Transfer Service is that robot for your data. BigQuery is Google’s giant data warehouse, a place where companies keep huge tables and ask questions of them. The Data Transfer Service moves data into BigQuery automatically, on a schedule, from many different sources. This guide assumes you know nothing about the topic. Every new word is explained when it first appears. By the end you will understand how the service works, how to set it up, how to read its status, and how real teams use it to keep their analysis fresh.
WWhat Is the BigQuery Data Transfer Service?
Start with the big picture, in plain words.
The simple definition
A data warehouse is a system built to store large amounts of data from many places and to answer questions about it quickly. BigQuery is Google Cloud’s data warehouse. It stores data in tables, and you ask questions using a language called SQL.
The BigQuery Data Transfer Service, often shortened to BigQuery DTS or just DTS, is a fully managed Google Cloud service that automates the movement of data into BigQuery on a schedule. Managed means Google runs and repairs the machinery. You do not rent servers, install software, or write the code that copies the data. You choose a source, a destination, and a schedule, and the service does the rest.
Think of a mail-forwarding service. You tell the post office, “Every day at six in the morning, collect my letters from these five addresses and deliver them to my new home.” After that you never think about it again. If a delivery fails, you receive a note. The Data Transfer Service is the forwarding service, and BigQuery is your new home address.
What it moves
The service can bring data from several families of sources. Google’s own marketing and advertising products, such as Google Ads and YouTube reports, are supported. Files that sit in cloud storage, including Google Cloud Storage, Amazon S3, and Azure Blob Storage, are supported. Other data warehouses, such as Teradata and Amazon Redshift, can be migrated. A growing list of third-party applications is also available through connectors. Google updates this list over time, so always confirm the current sources in the official documentation.
What else it does
Two other everyday BigQuery features run on the same machinery. Scheduled queries let you run a SQL statement on a timetable and save the result into a table. Dataset copies let you copy a whole dataset to another location. We will look at both in later chapters.
Why it exists
Without such a service, every team writes its own copy scripts. Those scripts break when a password changes, when a file arrives late, when an advertising company updates its report format, or when the one engineer who understood them leaves. A managed service puts the common work in one well-tested place, so teams can spend their effort on analysis, not plumbing.
The service is built for batch movement, which means moving data in chunks at set times, such as hourly or daily. It is not designed for second-by-second streaming. For instant streams, other Google Cloud tools fit better, and we will compare them later.
TThe Problem: Data Lives Everywhere
To value a delivery service, first see the mess without one.
Scattered data
A modern company keeps its information in many separate places. Advertising numbers live inside ad platforms. Sales files sit in cloud storage buckets. An older reporting system lives in a data center. A partner sends a daily file. Each place has its own format, its own login, and its own schedule. Questions that matter, such as “Which advertisement brought the most paying customers?”, need data from several of these places at once.
Pipelines, ETL, and ELT
A data pipeline is an automated path that moves data from where it is created to where it is analyzed. ETL stands for Extract, Transform, Load. You extract data from a source, transform it into a clean shape, and load it into a warehouse. ELT flips the last two steps: you load the raw data first and transform it inside the warehouse afterward, which works nicely with BigQuery because it is powerful at transforming large tables. The Data Transfer Service handles the extract and load parts, and your SQL, scheduled queries, or other tools handle the transform part.
Batch versus streaming
Batch processing handles data in groups at set times, like a bus that leaves the station every hour. Streaming handles each piece the moment it appears, like a river. Batch is simpler and cheaper, and is perfectly good for reports that update daily. Streaming is needed when seconds matter, such as fraud detection.
What goes wrong with hand-made scripts
Scripts break silently
A changed password or renamed column stops the copy, and nobody notices for days.
Re-runs double the data
A failed script that is run again may load the same rows twice.
Missed days
If the server was off during the schedule, that day is missing forever.
Credentials scattered
Passwords end up pasted into scripts, which is a security risk.
Knowledge walks away
Only one engineer understands the script, and then they leave.
Source changes
The ad platform adds fields, and the script cannot cope.
Production example: marketing numbers in one place
A marketing team at an online retailer runs campaigns on several advertising platforms. Each morning an analyst once copied reports by hand into a spreadsheet. With the Data Transfer Service, the reports arrive in BigQuery tables overnight, and a dashboard reads them directly. The analyst now spends the morning on decisions, not on copying.
Hand-made copy scripts look cheap on the first day. Their true cost shows up months later as late reports, wrong totals, and weekend repair work.
CCore Concepts of the Service
The vocabulary of the service, explained one word at a time.
Project and dataset
A project is the basic container of Google Cloud resources, carrying billing, permissions, and the list of switched-on services. Inside a project, BigQuery organizes tables into folders called datasets. A transfer always loads into one destination dataset. The dataset has a location, which is the geographic place where its data physically lives, and this location matters for transfers.
Data source
A data source is the kind of thing you are transferring from, such as Cloud Storage, Amazon S3, Google Ads, or Teradata. Each data source has its own settings, such as which account, which files, or which report types.
Transfer configuration
A transfer configuration is the saved set of instructions: the data source, the destination dataset, the schedule, the source settings, and the notification choices. It is like a standing order at a supplier. You create it once, and it triggers deliveries again and again.
Transfer run
A transfer run is one execution of a transfer configuration. If a configuration is set to run daily, you will see one run per day. Each run has a state, a start time, an end time, a log of messages, and a summary of what it loaded.
Schedule
The schedule says how often a configuration runs, such as every day at a given time, or every few hours. Different data sources support different schedule options. Some sources run on a fixed schedule defined by the service, so you cannot choose arbitrary times.
Backfill
A backfill is a request to load data for past dates. Suppose you set up a transfer today but want the last ninety days too. A backfill asks the service to run the transfer for those earlier dates. Not every data source supports backfills, and some limit how far back you can go.
Credentials
The service must prove its right to read the source and write to the destination. It can use user credentials, meaning the permissions of the person who created the transfer, or a service account, which is an identity for software rather than a person. Service accounts are strongly preferred for production, because they do not depend on one employee’s login or job.
Notifications
The service can send email notices about run failures and can publish run status messages to a Pub/Sub topic. Pub/Sub is Google’s messaging service. Publishing status to a topic lets your own automation react to a success or a failure.
| Term | Simple meaning | Example |
|---|---|---|
| Data source | The kind of origin | Cloud Storage, Amazon S3, Google Ads |
| Transfer configuration | The saved standing order | Load daily files from a bucket into a sales dataset |
| Transfer run | One execution of the order | Tuesday’s run at two in the morning |
| Destination dataset | Where the data lands | A dataset named marketing_raw |
| Backfill | A catch-up request for past dates | Load the previous ninety days |
| Service account | A software identity | An account used only by transfers |
A transfer configuration is a magazine subscription form. It names the magazine, your address, and the delivery frequency. Each issue that arrives is a transfer run. A backfill is ordering a few missing back issues. The credentials are the payment card the publisher checks before shipping.
AArchitecture: How the Pieces Fit Together
Follow a delivery from the source to a BigQuery table.
The service sits between your sources and BigQuery. A scheduler decides when a run should start. A worker connects to the source using the credentials you provided, reads the data, and hands it to BigQuery, which loads it into the destination table. Status and logs are recorded for each step.
flowchart LR
A["Transfer configuration with schedule"] --> B["Transfer scheduler"]
B --> C["Transfer run created"]
C --> D["Worker connects to the source"]
S1["Cloud Storage"] --> D
S2["Amazon S3 or Azure Blob"] --> D
S3["Google Ads and other apps"] --> D
S4["Teradata or Redshift"] --> D
D --> E["Data staged and validated"]
E --> F["BigQuery load into destination dataset"]
F --> G["Run status and logs recorded"]
G --> H["Email or Pub/Sub notification"]
Reading the diagram
Transfer configuration with schedule. This is your standing order. It holds the source, the destination, the settings, and the timetable.
Transfer scheduler. A scheduling component inside Google’s service watches the clock. When the time comes for a configuration, it creates a run.
Transfer run created. A new run record is made, with a pending state and a number for the date or time window it covers.
Worker connects to the source. Google’s managed workers use the stored credentials to open a connection. You do not manage these workers, and they scale as needed.
Data staged and validated. The data is read and checked. For files, the service finds the matching files and reads their formats. For ad platforms, it requests the day’s reports through the platform’s interface.
BigQuery load. The data is loaded into the destination table. For files, this uses the same kind of load job you could run yourself. A load job is a BigQuery operation that ingests a batch of data into a table, and it is efficient and, in many cases, free of the per-row cost associated with streaming inserts.
Run status and logs recorded. The final state, row counts, and any messages are saved so you can review them later.
Notification. If you set one, an email goes out on failure, or a message is published to a Pub/Sub topic.
The service pulls data in. Your source does not push anything. This means the source must allow Google’s service to read from it using the credentials you gave. For files in a bucket, that means permissions. For ad platforms, that means authorizing the account.
The architecture is like a milk round. A dispatcher (scheduler) looks at the timetable and sends a driver (worker) out. The driver visits each farm (source) using a key you provided, collects the milk, brings it to the dairy (BigQuery), and the dairy staff pour it into the right tank (table). A logbook records every trip, and the owner is texted if a trip fails.
SSupported Sources and What They Bring
A tour of the doors through which data can enter.
The list of supported sources grows over time, and some are in earlier release stages, called preview, where features may change. Treat this chapter as a map of the main families, and confirm the exact current list and release status on Google’s pages before you plan.
Google marketing and advertising platforms
Google offers connectors for several of its own products, such as Google Ads, Campaign Manager, Display and Video 360, Search Ads 360, Google Ad Manager, Google Play, and YouTube channel and content owner reports. These bring ready-made report tables into BigQuery. The result is a set of tables with a stable shape that analysts can combine with sales data.
Cloud storage files
The service can load files from Google Cloud Storage, Amazon S3, and Azure Blob Storage. This is the most flexible family, because many systems can export files. You describe which files to pick up, in which format, and how to treat repeats. Common formats include CSV, JSON, Avro, Parquet, and ORC, which are standard ways to lay out table data in files.
Data warehouse migrations
Teams moving from older warehouses can use connectors for systems such as Teradata and Amazon Redshift. These are intended for migration, meaning a one-time or short-term move of existing data, together with help from companion tools for translating old SQL into BigQuery’s dialect.
Third-party applications and databases
Through partners and newer connectors, the service can bring in data from business applications such as customer relationship and advertising tools, and some operational databases. Availability depends on the connector and its release stage, so check carefully.
Internal features built on the same service
Scheduled queries and dataset copy jobs run on the same engine and show up in the same list of transfers.
| Family | Typical examples | Best for |
|---|---|---|
| Google marketing platforms | Google Ads, Campaign Manager, YouTube reports | Marketing and campaign analytics |
| Object storage files | Cloud Storage, Amazon S3, Azure Blob Storage | Exports from any system that can write files |
| Warehouse migration | Teradata, Amazon Redshift | Moving off an older warehouse |
| Third-party applications | Partner and business application connectors | Bringing SaaS data into one place |
| Internal BigQuery jobs | Scheduled queries, dataset copies | Transformations and copies inside Google Cloud |
flowchart TD
A["Where is my data?"] --> B{"Google marketing product?"}
B -- "Yes" --> C["Use the matching Google connector"]
B -- "No" --> D{"Can the system export files?"}
D -- "Yes" --> E["Land files in Cloud Storage, S3, or Azure Blob"]
E --> F["Use a file transfer"]
D -- "No" --> G{"Is it a supported application or warehouse?"}
G -- "Yes" --> H["Use that connector"]
G -- "No" --> I["Consider other tools such as Datastream or Dataflow"]
Sources are like the different kinds of freight at a port. Some cargo arrives in standard shipping containers (files), some in special refrigerated trucks (Google’s own marketing data), and some is a full house being moved from one city to another (warehouse migration). The port has a handler for each type, and a general-purpose handler for anything that fits a container.
Connectors differ in how often they can run, how far back they can backfill, and whether they are generally available or still in preview. A connector in preview may change, so avoid building critical processes on it without a fallback.
IInternal Working: How a Run Actually Happens
Lift the lid and watch the gears turn.
Scheduling and the run window
The scheduler holds your timetable. For a daily transfer, each run covers a run time and often a run date, which tells the connector which slice of data to fetch. For example, a run at two in the morning may be asked to fetch yesterday’s report. This is why the same configuration can later be re-run for an older date: the date is a parameter of the run.
Authorization at run time
When a run starts, the service uses the stored credentials. If you used a service account, the service impersonates it, which means it obtains a short-lived token as that account. If you used user credentials, the service relies on a stored authorization from that person. If that authorization has expired or the person left the organization, the run fails with an authorization error. This is one of the most common reasons for failed runs.
Reading from the source
For file sources, the worker lists files in the bucket that match your path pattern and that have not been loaded before, using file modification times to decide. It then groups them and starts a BigQuery load job. For advertising sources, the worker calls the platform’s interface for the reports of the requested date, converts them to rows, and loads them. For warehouse migrations, an agent running near the old system extracts data and writes it into cloud storage first, and then a load into BigQuery follows.
Load jobs
The heart of many transfers is a BigQuery load job. BigQuery reads the staged data and writes it into the table in a single atomic step. Atomic means that it either fully succeeds or fully fails, with no half-finished table. This is a kind of safety property. If a run fails during the load, the table is left in its previous state.
Idempotence and duplicates
A step is idempotent when running it twice gives the same final result as running it once. Many connectors are designed to be idempotent for a given run date, for example by replacing the data for that date rather than adding it again. For file transfers, you choose the behavior using a write preference: append new rows to the table, or mirror the source by replacing the table contents. Understanding which one you chose is essential to avoid duplicate data.
Retries
If a run hits a temporary problem, such as a brief network error, the service may retry. Permanent problems, such as a missing permission or a missing dataset, fail the run immediately with a clear message in the log.
State tracking
The service remembers which files it has already loaded and which dates it has already run, so that normal schedules do not repeat the same work. This memory belongs to each configuration. If you delete a configuration and create a new one, the new one has no memory and may load old files again.
sequenceDiagram
participant Sch as "Scheduler"
participant Run as "Transfer run"
participant Auth as "Credentials"
participant Src as "Source system"
participant BQ as "BigQuery"
Sch->>Run: "Time reached, create run for date"
Run->>Auth: "Obtain token for service account or user"
Auth-->>Run: "Token"
Run->>Src: "Request files or reports for the run date"
Src-->>Run: "Data"
Run->>BQ: "Start load job into destination table"
BQ-->>Run: "Load succeeded or failed"
Run->>Run: "Record state, row counts, and logs"
Run-->>Sch: "Run complete"
A run is like a school bus route. The dispatcher sets the date. The driver shows a pass at the gate (credentials), picks up the children listed for the day (files or reports), and delivers all of them to the school at once (the atomic load). The driver also notes who has already been picked up, so that nobody boards twice.
When data looks doubled or missing, the cause is almost always one of three things: the write preference, the run date, or the memory of already-loaded files. Check those first.
SSetting Up: From Zero to First Transfer
A calm, ordered path that avoids the usual surprises.
Step one: prepare the project
Choose the project that will hold the destination dataset and enable the BigQuery Data Transfer API and the BigQuery API. Without the Data Transfer API turned on, creating a transfer fails with a message that says so.
Step two: create the destination dataset
Create a dataset to receive the data. Choose its location carefully. For many sources, the dataset location must match or be compatible with the source location, and the location cannot be changed later without recreating the dataset. For example, a dataset in one region cannot simply receive a bucket’s data from a different location in some transfer types.
Step three: decide on the identity
Create a dedicated service account for transfers, and grant it exactly what it needs: permission to read the source, permission to write to the dataset, and permission to run load jobs. The person creating the transfer needs permission to act as that service account. Keeping a dedicated account separates transfer duties from any human’s login.
Step four: prepare the source
For file sources, make sure the files are in a stable, predictable path, with consistent names and formats. For application sources, authorize the account that holds the data. For cloud-to-cloud transfers, create the access credentials in the other cloud with read-only permission.
Step five: create the transfer configuration
In the Console, open BigQuery, choose Data transfers, and create a transfer. Pick the data source, give the configuration a clear name, set the schedule, choose the destination dataset, and fill in the source-specific settings. You can do the same with the command-line tool or the API, which is better for repeatable setups.
Step six: run it once and inspect
Trigger a first run or a backfill for one day. Open the run details. Check the state, the log messages, and the row counts. Look at the table in BigQuery and compare a few numbers with the source. Only after you are satisfied should you rely on the schedule.
Step seven: add notifications
Turn on email notifications for failures, and where useful, a Pub/Sub topic that your automation can read. A transfer that fails quietly is worse than one that never existed.
Enable APIs
Switch on the BigQuery Data Transfer API in the project.
Create the dataset
Pick a location that fits the source and your rules.
Create the service account
Give it read access to the source and write access to the dataset.
Prepare the source
Stable file paths, authorized accounts, and read-only credentials.
Create the configuration
Name, schedule, destination, and source settings.
Test one run
Inspect status, logs, and data against the source.
Add notifications and monitoring
Email and Pub/Sub for failures, plus a dashboard for freshness.
Do not use a personal account as the long-term identity of a production transfer. If that person leaves or changes roles, the transfer will start failing. Use a service account wherever the source supports it.
Production example: infrastructure as code
A data platform team keeps transfer settings in versioned files and applies them with automation, so that every transfer in every environment is created the same way, and every change is reviewed. A new project gets its transfers in minutes, with the same names, schedules, and permissions as the others.
FFile Transfers in Depth: Cloud Storage, S3, and Azure
The most flexible family deserves its own chapter.
The big idea
File transfers watch a location, find matching files, and load them into a BigQuery table. Because nearly every system can export files, this family is the Swiss army knife of the service. Whatever your source, if you can get it to write files, this route works.
Choosing files with a path pattern
You describe the files with a URI pattern, which is a path that can include wildcards. A wildcard is a special character that stands for “anything here”. For example, one pattern can mean “all files in the sales folder whose names begin with orders”. Using a clear folder structure with dates makes patterns simple and keeps runs fast.
File formats
| Format | Nature | When to prefer it |
|---|---|---|
| CSV | Plain text rows with separators | Simple exports and human-readable files |
| JSON lines | One JSON object per line | Nested or flexible data |
| Avro | Compact binary with an embedded schema | Reliable schemas and fast loading |
| Parquet | Column-oriented binary | Large analytical datasets |
| ORC | Column-oriented binary | Data coming from Hadoop-style systems |
Self-describing binary formats such as Avro and Parquet carry their own schema, which reduces mistakes about column types. CSV is common but fragile, because a stray comma or a different date style can confuse a load.
Write preference: append or mirror
With append, each run adds newly found files’ rows to the table, leaving earlier rows alone. This suits event-style data that grows over time. With mirror, each run replaces the table contents with the data found in the matching files, so the table reflects the current set of files. This suits reference data, such as a product list that is re-exported in full each day.
Schema handling
The schema is the list of columns and their types. You can let BigQuery detect it, which is quick but can guess wrong, or you can specify it, which is safer for production. If the incoming file gains an extra column, the load may fail, unless you allow schema updates. Decide this deliberately.
Handling bad rows
You can set how many bad rows a load tolerates before it fails. A strict setting catches problems early. A tolerant setting keeps data flowing but may hide quality problems, so pair it with checks.
Runtime parameters and date-based tables
The destination table name and the path can include runtime parameters, which are placeholders filled in at run time, such as the run date. This lets one configuration load a different daily file into a different daily table, or into daily partitions of one table.
Partitioned tables
A partitioned table splits a large table into slices, usually by date, so that queries read only the slices they need. Loading into partitions keeps costs lower and queries faster.
Cleaning up source files
There is an option to delete files from the source after a successful load. This is tidy but dangerous. If a mistake happens in the pipeline, the original files are gone. A safer pattern is to move processed files to an archive folder with a rule that deletes them after a long time.
Cross-cloud transfers
For Amazon S3 and Azure Blob Storage, the service needs credentials in those clouds. Create read-only credentials limited to the specific bucket or container. Remember that moving data between clouds may incur data egress charges from the source cloud. Check those prices before you schedule large daily transfers.
flowchart TD
A["Source system exports file"] --> B["File lands in bucket folder by date"]
B --> C["Transfer run starts on schedule"]
C --> D["Find files matching the path pattern"]
D --> E{"Write preference"}
E -- "Append" --> F["Add rows from new files to table or partition"]
E -- "Mirror" --> G["Replace table contents with matching files"]
F --> H["Run succeeds and state is remembered"]
G --> H
H --> I["Optionally archive processed files"]
A file transfer is like a mailroom clerk who checks a pigeonhole each hour. With the append rule, the clerk adds each new envelope’s contents to a running ledger. With the mirror rule, the clerk throws away the old ledger and writes a fresh one from the envelopes currently in the pigeonhole.
Production example: nightly sales exports
A retail company’s point-of-sale system writes one file per store per night into a bucket folder named by date. A transfer with an append rule loads each night’s files into a partitioned sales table. The next morning, dashboards show yesterday’s sales by store, without any person touching a file.
SScheduled Queries and Dataset Copies
Two everyday features that run on the same engine.
Scheduled queries
A query is a question you ask BigQuery in SQL. A scheduled query is a question that BigQuery asks itself on a timetable, saving the answer into a table. For example, every night at one o’clock, it can total the previous day’s sales by region and write the result into a summary table. Dashboards then read the small summary table instead of scanning the huge raw table each time, which is faster and cheaper.
Scheduled queries appear in the list of data transfers because the same scheduling and run-tracking machinery powers them. Each execution is a run with a state, a log, and an optional notification. You can pass the run date into the query so that it knows which day to process, and you can choose to append to or overwrite the destination table.
Daily rollups
Total large raw tables into small reporting tables once a night.
Transform raw to clean
Turn loaded raw data into tidy, typed tables for analysts.
Data checks
Count rows and look for odd values after each transfer, and record the result.
Point-in-time copies
Save a table’s state each day to track change over time.
Chaining transfers and queries
A typical flow is two steps: a transfer brings in raw data at one in the morning, and a scheduled query transforms it at two. The weakness of this design is that the second step runs by the clock, not by the success of the first. If the transfer is late, the query may run on missing data. Teams fix this by leaving a safety gap, by using notifications to trigger the next step, or by using a workflow tool that links steps by dependency. We will return to this in the patterns chapter.
Dataset copy
A dataset copy transfer copies all tables in one dataset to another dataset, possibly in a different project or a different region. It is useful for disaster recovery, for sharing data with another team’s project, for moving data to another location, and for keeping a read-only copy for analysts. It can run once or on a schedule, and it can be incremental, which means it copies only what has changed since the last run.
flowchart LR
A["Raw files in bucket"] --> B["Transfer at 1 AM loads raw table"]
B --> C["Scheduled query at 2 AM builds clean table"]
C --> D["Scheduled query at 3 AM builds summary table"]
D --> E["Dashboard reads summary"]
C --> F["Dataset copy to reporting project"]
Think of a bakery. The first worker receives flour at dawn (the transfer). The second worker mixes and bakes at seven (a scheduled query). The third worker boxes the bread for shops (another query or a dataset copy). If flour arrives late, a clock-driven baker may start with an empty bin, so a good bakery lets each worker wait for a ready signal.
A scheduled query is billed like any other query by the amount of data it reads. Partition your tables by date and filter by date in the query, so each night reads one slice, not the whole history.
RRun Lifecycle, Schedules, and Backfills
Understand when runs happen, what states they pass through, and how to catch up.
Run states
Every run moves through a small set of states. Pending means it is waiting to start. Running means work is in progress. Succeeded means the load completed. Failed means an error stopped it, and the log says why. Cancelled means someone or something stopped it on purpose. Some runs may also show a state that means it was skipped because nothing new was found.
stateDiagram-v2
[*] --> Pending: "Run created"
Pending --> Running: "Worker starts"
Running --> Succeeded: "Load completes"
Running --> Failed: "Error occurs"
Pending --> Cancelled: "Stopped by user"
Running --> Cancelled: "Stopped by user"
Failed --> Pending: "Manual re-run or backfill"
Succeeded --> [*]
Cancelled --> [*]
Choosing a schedule
Schedules can be daily, weekly, monthly, or at custom intervals, depending on the source. Some sources only provide data once per day, so running them hourly achieves nothing. Match the schedule to how often the source really changes, and to how fresh the business needs the data. Fresher is not always better, because every run uses resources and may cost money.
Time zones
Schedules are expressed in a time standard, usually Coordinated Universal Time, shortened to UTC. A transfer set for two in the morning UTC may run in the evening for a team on another continent. Always write the time zone in the configuration name or description to avoid confusion, and remember that the run date inside the data may follow the source’s time zone, not yours.
Manual runs
You can start a run on demand for testing or for a one-off catch-up. A manual run does not replace the schedule.
Backfills
When you need earlier dates, you request a backfill for a range of days. The service creates one run per day and works through them. Because backfills can create many load jobs and consume quotas, avoid launching enormous backfills during business hours, and prefer small batches. Not every connector supports backfills, and some limit the maximum span, so check before promising a history to your analysts.
Re-running a failed day
When one day fails, fix the cause first, whether that is a permission, a missing file, or a changed column, and then re-run only that day. For connectors that replace data per date, a re-run is safe. For append-style file transfers, check whether the failed attempt loaded anything before running again. Since loads are atomic, a failed load normally leaves no partial data, but confirm with a row count.
Pausing and disabling
You can disable a configuration to pause its schedule without deleting it. This keeps its memory of already-loaded files, which is why disabling is safer than deleting when you only want a break.
Notice the failure
An email, a notification message, or a dashboard shows a failed or missing run.
Open the run details
Read the error message and the log lines for that run.
Fix the root cause
Permissions, source files, expired authorization, dataset settings, or schema changes.
Re-run the affected date
Use a manual run or a small backfill for exactly the missing days.
Verify the data
Compare row counts and key totals with the source.
Record what happened
Write down the cause and fix so the next person solves it faster.
Deleting and recreating a transfer to “fix” it. The new configuration forgets what was loaded and may load old data again, creating duplicates. Prefer fixing and re-running the existing configuration.
DData Flow and Lifecycle of a Transfer Project
Follow the story from first idea to retirement.
Define the need
Decide what question the data will answer, how fresh it must be, and who will use it.
Choose the source and shape
Pick the connector or file format, the schema, and the partitioning plan.
Build the foundation
Create the project settings, the dataset, the service account, and the permissions.
Create and test the transfer
Run one day, inspect the data, and compare it with the source.
Backfill history
Load past data in small batches and validate each batch.
Operate and monitor
Watch run states, freshness, and data quality checks each day.
Evolve
Handle new columns, new files, new sources, and changed schedules with care.
Retire
Disable the schedule, archive or delete data per policy, and remove access.
The three layers of data
Many teams organize loaded data into layers. The raw layer holds data exactly as transferred, untouched, so you can always return to the original. The clean layer holds data with fixed types, removed duplicates, and standard names. The reporting layer holds summaries ready for dashboards. Transfers fill the raw layer, and scheduled queries or other tools build the others. Keeping raw data safe means a mistake in cleaning can always be repaired by re-running from the raw layer.
flowchart LR
A["Sources"] --> B["Data Transfer Service"]
B --> C["Raw dataset - untouched copies"]
C --> D["Clean dataset - typed and de-duplicated"]
D --> E["Reporting dataset - summaries"]
E --> F["Dashboards and analysts"]
C --> G["Quality checks and alerts"]
Never transform data on the way in if you can transform it after landing. Landing raw first gives you a safe fallback and a clear audit trail.
AAdvantages, Disadvantages, and Alternatives
An honest look at when this service is the right tool, and when it is not.
Advantages
- No code for common sources: choose a source and a schedule.
- Fully managed: no servers to run or patch.
- Built-in scheduling and tracking: run history, logs, and states.
- Backfills: catch up on history for many connectors.
- Native to BigQuery: uses load jobs and fits the permission model.
- Notifications: email and Pub/Sub for failures.
- Reduces fragile scripts: fewer late-night repairs.
Disadvantages
- Batch only: not for second-by-second streams.
- Limited transformations: mostly extract and load.
- Connector limits: schedule options and features differ by source.
- Preview connectors: may change or have gaps.
- Location rules: dataset location and source location must be compatible.
- Dependencies by clock: chaining steps needs extra care.
- Authorization drift: user-based credentials can expire.
Alternatives and companions
| Tool | Best for | Compared with Data Transfer Service |
|---|---|---|
| BigQuery load jobs by hand | One-off loads and custom control | You write the scheduling and tracking yourself |
| Storage Write API and Pub/Sub subscriptions | Near real-time streaming into BigQuery | Streaming instead of batch |
| Datastream | Change data capture from operational databases | Continuous replication of row changes |
| Dataflow | Complex transformations in batch or streaming | More powerful, but you build and run pipelines |
| Cloud Composer or Workflows | Orchestrating many dependent steps | Complements transfers by controlling order |
| Dataform and SQL pipelines | Managing SQL transformations inside BigQuery | Handles the transform step after loading |
| Third-party ELT tools | Hundreds of application connectors | Broader connector catalog, extra vendor and cost |
The pairing most beginners meet is a Data Transfer Service load followed by scheduled queries. As needs grow, teams add an orchestrator to control dependencies and a transformation tool to manage SQL. The service remains the dependable first mile that brings data to the warehouse door.
The Data Transfer Service is a scheduled delivery truck on a fixed route. A streaming tool is a conveyor belt that carries each item as it appears. A transformation pipeline is the kitchen that prepares the ingredients. You may need all three in a large restaurant, but a small cafe may need only the delivery truck at first.
SSecurity, Access, and Compliance
Moving data is also moving risk, so build the road with guardrails.
Roles and permissions
IAM, Identity and Access Management, is the rulebook of who may do what. Creating and managing transfers needs specific permissions, which are included in certain BigQuery roles, and the transfer must be able to write to the destination dataset. A good design separates three jobs: the people who manage transfers, the service account that runs them, and the analysts who read the results. Each gets only what its job needs.
| Who | What they need to do | Approach |
|---|---|---|
| Data engineers | Create and edit transfer configurations | Permission to manage transfers in the project, plus permission to use the service account |
| Transfer service account | Read source, write destination, run load jobs | Narrow read access to the source and writer access to the dataset only |
| Analysts | Query the loaded tables | Viewer on the reporting dataset, not on raw data unless needed |
| Auditors | Review history and access | Read access to logs and configuration metadata |
Service accounts over personal credentials
User credentials tie a transfer to one person’s account. If that account is disabled, loses permission, or has its authorization expire, the transfer fails. A service account is independent of people and is easier to audit. Where a connector only supports user authorization, use a dedicated, managed account and document who owns it.
Protecting source credentials
For cloud-to-cloud transfers, the credentials for the other cloud must be stored in the transfer configuration. Use read-only, narrowly scoped keys, restrict them to the specific bucket or container, and rotate them on a schedule. Never reuse an administrator key.
Encryption
Data is encrypted in transit and at rest by default. If your organization requires control over the encryption key, you can apply a customer-managed encryption key, created in Cloud KMS, to the destination dataset. Check the documentation for how customer-managed keys interact with each connector.
Data location and residency
The dataset location decides where the loaded data physically lives. If a law or contract limits where data may be stored, choose the dataset location first and make sure every transfer respects it. Organization policies can block creating datasets in disallowed locations.
Network boundaries
VPC Service Controls create a protective perimeter around Google Cloud services. Support for the Data Transfer Service within perimeters has specific requirements, so test early if your organization uses them, and read the current documentation.
Sensitive data
Advertising and sales files may include personal information such as names or email addresses. Decide in advance which columns should be loaded, masked, or dropped. BigQuery offers column-level access controls and data masking that can protect sensitive fields after loading. Landing raw data in a restricted dataset and exposing only a cleaned version to analysts is a common approach.
Audit logging
Changes to transfer configurations and the runs themselves are visible in Cloud Logging and audit logs. Review who created or modified transfers and who changed permissions on datasets. This record answers the question “who changed this transfer last week?” without guesswork.
Dedicated service account
Run transfers as software, not as a person.
Least privilege
Read-only on the source, writer on one dataset.
Scoped cloud keys
Limit cross-cloud keys to one bucket and rotate them.
Customer-managed keys
Control encryption when regulations ask for it.
Dataset location
Choose the region that satisfies your residency rules.
Audit logs
Track who changed transfers and permissions.
Giving the transfer identity broad BigQuery admin rights “so it works”. If that identity is ever misused, the attacker can read or delete every dataset. Grant write access to the one destination dataset instead.
Production example: separating raw and reporting data
A healthcare-adjacent analytics team loads partner files into a locked raw dataset, readable only by the transfer account and two engineers. A scheduled query removes direct personal identifiers and writes the result to a reporting dataset that analysts can read. A leak on the analyst side cannot expose raw identifiers, because they never reach that dataset.
MMonitoring, Logging, and Troubleshooting
When data goes missing, ask the right questions in the right order.
What to watch
There are two different things to watch. The first is the health of the transfer: did the run succeed, how long did it take, and how many rows did it load? The second is the freshness and quality of the data: is the newest row recent, do the totals match the source, and are there suddenly many empty values? A transfer can succeed technically and still deliver wrong or stale data, so watch both.
Where to look
- The Data transfers page in the Console: shows each configuration, its recent runs, their states, and error messages.
- Run details and logs: shows the messages written during each run.
- Cloud Logging: holds log entries for transfer runs, where you can search and create log-based alerts.
- Pub/Sub notifications: let automation react to each run’s final state.
- Email notifications: a simple first alarm for failures.
- BigQuery information schema views: let you query metadata, including load jobs, to see what ran and how much it processed.
Freshness checks
A simple and powerful habit is a small scheduled query that looks at the newest date in each loaded table and compares it with today. If the gap is larger than expected, it writes a row to a monitoring table or triggers an alert. This catches the case where the transfer silently stops creating runs, which a failure email would never report.
A troubleshooting checklist
Is the run failed or missing?
A failed run has an error. A missing run suggests a disabled configuration or a changed schedule.
Read the error message
It usually names the cause: permission, location, missing file, or authorization.
Check the credentials
Has the user left, has the authorization expired, or has the service account lost a role?
Check the source
Do the files exist at the expected path, in the expected format, with the expected names?
Check the destination
Does the dataset exist, in the right location, with permission to write?
Check the schema
Did the source add, remove, or rename a column or change a type?
Check quotas and limits
Too many load jobs or too much data in a short window can cause errors.
| Symptom | Likely cause | First thing to try |
|---|---|---|
| Access denied on the source | Missing read permission or expired key | Check the identity and the source-side permissions |
| Access denied on the dataset | Service account cannot write to destination | Grant writer on the destination dataset only |
| Dataset not found in location | Dataset and source location mismatch | Create a dataset in the correct location and update the transfer |
| Authorization expired | User-based credentials went stale | Re-authorize, or switch to a service account |
| No files found | Wrong path pattern or files not yet created | Check the pattern and the file creation time |
| Load failed on a column | Schema or type mismatch in new files | Compare file columns with the table schema |
| Duplicate rows | Append mode with re-run, or recreated configuration | Check write preference and run history |
| Data looks old | Source not updated, or schedule paused | Check the source timestamp and configuration state |
| Quota exceeded | Large backfill or many small files | Slow down, batch files, spread runs over time |
If the transfer works in a test project but fails in production, compare the identity and the location. Almost every difference between the two comes from one of those two settings.
PPerformance, Quotas, and Cost
Practical limits and how to live comfortably within them.
What affects speed
The time a run takes depends on how much data there is, how many files, the format, and the source’s own speed. Many small files are slower than a few large ones, because each file adds overhead. Binary formats such as Avro and Parquet load faster than text formats such as CSV, because BigQuery reads them more efficiently.
Make files friendly
When you control the export, aim for fewer, larger, compressed files rather than thousands of tiny ones. Use consistent names and date-based folders. This reduces runs that take too long and avoids hitting limits on the number of files per load.
Quotas and limits
Google sets quotas, which are limits on how many load jobs you can run per table per day, how large a load can be, and how many files a single load may include. Transfer features may also have their own limits, such as the minimum interval between runs for certain sources and the maximum number of transfer configurations. These numbers can change, so read the current quota and limits pages, especially before large backfills.
How cost works
Pricing differs by connector and can change, so use Google’s pricing page as the authority. In general, think about four cost buckets. First, the transfer itself: some connectors, especially those for Google marketing products, have no separate transfer charge, while some others, including certain third-party and migration connectors, may charge. Second, BigQuery storage for the data you load. Third, BigQuery queries, including scheduled ones, which are billed by data processed or by reserved capacity. Fourth, data egress from other clouds, which you pay to the source cloud when moving data out of it.
Practical ways to save
- Match the schedule to need. Daily is often enough. Hourly doubles complexity for little gain if nobody looks hourly.
- Partition and cluster tables. Queries read only the slices they need.
- Set table expiration for raw staging data that you only need for a few weeks.
- Avoid transforming the same data many times. Build shared clean tables instead of many private copies.
- Choose compact, compressed formats to shrink both storage and egress.
- Review old transfers. Disable those whose reports nobody uses anymore.
flowchart TD
A["Transfer cost review"] --> B{"Is anyone using this data?"}
B -- "No" --> C["Disable transfer and set expiry on tables"]
B -- "Yes" --> D{"Is the schedule more frequent than needed?"}
D -- "Yes" --> E["Reduce frequency"]
D -- "No" --> F{"Are queries scanning full history?"}
F -- "Yes" --> G["Partition tables and filter by date"]
F -- "No" --> H{"Moving data across clouds?"}
H -- "Yes" --> I["Compress files and estimate egress charges"]
H -- "No" --> J["Cost is healthy - review again next quarter"]
Controlling cost is like running a home kitchen. You do not buy fresh bread every hour if you eat it once a day. You store what you use in sensible portions, and you throw out leftovers after a few days. Matching the schedule to need and expiring old staging tables are the same habits applied to data.
Whether a connector is free, paid, or in preview changes over time. Verify on the pricing and release notes pages before you commit a large budget or promise a launch date.
DDesign Patterns and Anti-Patterns
Habits that help, and habits that hurt.
Helpful patterns
Land raw, then transform
Keep an untouched raw layer and build clean and reporting layers from it.
Date-partitioned landing
Load into partitions by date so re-runs replace one day cleanly.
Dedicated service account
One identity for transfers, with narrow rights and clear ownership.
Freshness monitor
A scheduled check that alerts when the newest data is too old.
Event-driven chaining
Use status notifications to start the next step only after a success.
Configuration as code
Create transfers from reviewed files so environments stay identical.
Anti-patterns to avoid
What it looks like
Creating a production transfer with your own personal account as the credential.
Why it hurts
When you change teams, leave, or your authorization expires, the transfer fails, often on a weekend.
Do this instead
Use a dedicated service account with narrow rights and a documented owner.
What it looks like
Scheduling a query at a fixed time right after a transfer, with no check that the transfer finished.
Why it hurts
When the transfer is late, the query runs on incomplete data and produces wrong totals that look correct.
Do this instead
Trigger the next step from the success notification, or use an orchestrator with dependencies.
What it looks like
Deleting and recreating a transfer whenever something goes wrong.
Why it hurts
The new configuration loses its memory and may reload old files, duplicating data.
Do this instead
Fix the root cause and re-run the existing configuration for the affected dates.
What it looks like
Letting analysts query the raw landing tables directly and building reports on them.
Why it hurts
Source changes break many reports at once, and sensitive columns are exposed to too many people.
Do this instead
Build stable clean and reporting layers, and restrict access to the raw layer.
What it looks like
Enabling “delete source files after transfer” with no archive and no checks.
Why it hurts
If a bug corrupts the load, the original files are gone and cannot be replayed.
Do this instead
Move processed files to an archive folder and expire them with a lifecycle rule after a safe period.
What it looks like
Relying on schema auto-detection for production files with no review.
Why it hurts
A column that looks like numbers one day and text the next changes type and breaks downstream queries.
Do this instead
Define the schema explicitly, or use self-describing formats, and review changes before they go live.
BBest Practices and Common Mistakes
A short, practical rulebook you can pin to the wall.
Best practices
- Choose the dataset location first. It cannot be changed later and affects every connector.
- Use service accounts for production. Personal credentials are fine for experiments only.
- Test one day before backfilling a year. Compare numbers with the source before trusting them.
- Land raw data unchanged. Transform afterward in layers.
- Choose the write preference on purpose. Append for growing events, mirror for full snapshots.
- Partition by date. It makes re-runs, queries, and expiry clean and cheap.
- Prefer self-describing formats such as Avro or Parquet when you control the export.
- Turn on notifications and a freshness monitor. Silent failure is the real enemy.
- Archive files rather than deleting them. Keep a replay path for a reasonable period.
- Document ownership. Each transfer should name a team, a purpose, and a contact.
- Keep configurations in code. Review changes like any other change.
- Review quarterly. Retire unused transfers and tighten permissions.
Common mistakes beginners make
Mistakes
- Forgetting to enable the Data Transfer API
- Mismatched locations between source and dataset
- Using personal credentials for production
- Choosing append when mirror was needed, or the reverse
- Backfilling a huge range without testing a small one
- Ignoring time zones and run dates
- No alert when the transfer simply stops
Better habits
- Follow the setup path in order
- Create the dataset in the right place first
- Use a documented service account
- Write down the write preference and why
- Backfill in small batches and validate each
- Write the time zone in the name and notes
- Monitor data freshness, not just run status
A green run does not prove the data is right. It proves the job finished. Check totals against the source now and then, especially after the source system changes.
RReal-World Usage Patterns
How different teams put the delivery robot to work.
The marketing analytics team
A consumer brand runs advertising on several Google platforms and wants one view of spending and results. Transfers bring campaign reports into BigQuery each night. A scheduled query joins those reports with online sales data, and a dashboard shows the cost to win each customer by campaign. The team no longer copies reports by hand, and campaign managers see yesterday’s results by nine in the morning.
The retail chain with nightly store files
Hundreds of stores send daily sales files into dated folders in a bucket. A file transfer with an append rule loads them into a date-partitioned table. A freshness monitor checks that every store sent a file, and alerts the operations team about missing stores before the finance team asks. The same pattern works for returns, stock counts, and staff schedules.
The company moving off an older warehouse
An organization running a legacy Teradata or Redshift warehouse uses the migration connectors to copy historical tables into BigQuery. Companion tools help translate old SQL. For several weeks, both warehouses run side by side, and the team compares results table by table. Once the numbers agree, they switch the dashboards and retire the old system.
The multi-cloud analytics team
A data team inherits logs and exports stored in Amazon S3 from an acquired business. Scoped, read-only credentials let the transfer pull compressed Parquet files into BigQuery each day. They plan the schedule around egress costs, choose compact formats, and gradually move the source exports into Google Cloud Storage to cut those charges.
The reporting platform with layers
A platform team standardizes all transfers into raw datasets with strict permissions. Scheduled queries build clean tables, and a dataset copy publishes finished reporting tables to a separate project that analysts can browse. When an upstream source changes a column, only the clean layer needs an update. Dashboards keep working because they depend on the reporting layer.
flowchart TD
A["Ad platforms"] --> T["Data Transfer Service"]
B["Store files in buckets"] --> T
C["Other cloud storage"] --> T
D["Old warehouse"] --> T
T --> R["Raw datasets"]
R --> Q["Scheduled queries build clean tables"]
Q --> P["Reporting dataset"]
P --> X["Dashboards and analysts"]
R --> M["Freshness and quality checks"]
M --> N["Alerts to the data team"]
Notice what these stories share. The service is not the whole data platform. It is the dependable first mile that brings data to the warehouse door on time. The value comes from the habits around it: raw landing, clear layers, monitoring, and tidy ownership.
FFrequently Asked Questions
Quick answers to the questions beginners ask most.
It is a managed Google Cloud service that automatically loads data into BigQuery on a schedule from sources such as advertising platforms, cloud storage files, other clouds, and other data warehouses.
Not for the common cases. You choose a source, a destination dataset, and a schedule in the Console, command line, or API. You may still write SQL to transform the data after loading.
A configuration is the saved set of instructions. A run is one execution of it. A daily configuration produces one run per day.
No. It is designed for batch loading on a schedule. For continuous streams, look at tools such as the BigQuery Storage Write API, Pub/Sub, Datastream, or Dataflow.
It is a request to run a transfer for past dates, so that you can load history after setting up a new configuration. Support and limits depend on the connector.
Many sources require that the destination dataset be in a compatible location, and a dataset’s location cannot be changed after creation. Choose the location before creating the transfer.
Append adds rows from new files to the existing table. Mirror replaces the table contents with the rows from the currently matching files. Use append for growing event data and mirror for full snapshots.
Common reasons are expired or revoked authorization, a changed file format or column, a deleted dataset, lost permissions, or a moved source location. The run’s error message normally names the cause.
Use a dedicated service account for production wherever the connector allows it. Personal credentials depend on one person and can expire or disappear.
Choose the right write preference, load into date partitions, avoid deleting and recreating configurations, and check run history before re-running an append-style transfer.
Scheduled queries use the same scheduling and run-tracking machinery, so they appear in the same list. They run SQL on a timetable and save results into tables.
It depends on the connector and can change over time. Some Google connectors have no separate transfer fee, while others may charge. You also pay for BigQuery storage, queries, and any cross-cloud egress. Check Google’s pricing page for current terms.
Turn on email notifications and a Pub/Sub topic, and add a freshness monitor that checks the newest date in the destination table. This catches both failed runs and runs that never started.
Mostly no. The service focuses on extracting and loading. Land the raw data first, and transform it afterward with SQL, scheduled queries, or a transformation tool.
Test one day and compare it with the source, confirm permissions and location, set notifications, set up a freshness check, document ownership, and write down the plan for re-running and backfills.
SSummary and Key Takeaways
Everything important, in one place.
Key Takeaways
- The BigQuery Data Transfer Service is a managed, scheduled delivery system. It loads data into BigQuery from ad platforms, cloud files, other clouds, and warehouses without servers or custom copy scripts.
- A configuration is the standing order and a run is one delivery. Each run has a state, logs, and counts, and the service remembers what it already loaded.
- Choose location, identity, and write preference on purpose. A mismatched dataset location, a personal credential, or the wrong append or mirror setting causes most first-month problems.
- Land raw, then transform. Keep an untouched raw layer, build clean and reporting layers with SQL, and let scheduled queries and dataset copies do the next steps.
- Backfill carefully. Test a single day, load history in small batches, and validate each batch against the source.
- Secure the road. Use dedicated service accounts, narrow read and write rights, scoped cross-cloud keys, the right dataset location, and audit logs.
- Watch freshness, not just success. Turn on notifications, add a freshness monitor, review cost and unused transfers regularly, and remember that batch is the design, not a streaming tool.