# Data Flow Sources

- URL: https://betteranalyst.com/docs/data-flows/sources
- Updated: 2026-11-01
- Author: Better Analyst

What each Data Flow source type can deliver — databases, warehouses, Airtable, Tableau, Google marketing data (Meta Ads coming soon), and Google Sheets — how much data it reads per run, and the limits that apply.

Every flow starts from one or more sources. Each run reads the source again from scratch — it never reuses the previous result — so the limits below apply to *each* run, not to the total amount of data you move over time.

## Source Types

| Source | Where it comes from | Can be re-read on a schedule |
| - | - | - |
| Databases and warehouses — Snowflake, BigQuery, PostgreSQL, Supabase, MySQL, SQL Server | **Data flow** chat mode | Yes |
| Airtable | **Data flow** chat mode | Yes |
| Tableau | **Data flow** chat mode | Yes |
| Google Analytics 4 | **Data flow** chat mode | Yes |
| Google Search Console | **Data flow** chat mode | Yes |
| Google Ads | **Data flow** chat mode | Yes |
| Meta Ads (Facebook and Instagram), coming soon | **Data flow** chat mode | Yes, once available |
| Google Sheets | The Google Drive picker on the Data Flows page | Yes |
| Uploaded files | Chat attachments | No |
| Information read from a web page | Chat | No |

Ask for a **complete table** from the connected source in **Data flow** chat mode. The output picker then shows whether each result can be delivered on a schedule.

Uploaded files and information read from a web page are captured once, so there is nothing to pull again on a later run. To deliver that data automatically, connect the system it came from and pull it from there.

A Google Sheet attached to a chat cannot become a flow source. To read a Sheet on every run, create the flow from **Already have a Google Sheet?** and pick the tab through the Google Drive picker.

## How Much Data a Run Reads

Data Flows read a **complete result** every run. If a source would return more than the limits below, the run fails with an explicit error rather than delivering part of the data — a partial sync is worse than no sync, because you cannot tell from the destination that rows are missing.

| Source type | Row limit per run | Size limit per run |
| - | - | - |
| Google Sheets | 100,000 data rows | 500,000 cells (rows × columns) |
| Google Analytics 4, Search Console, Google Ads | 100,000 rows | 16 MB |
| Meta Ads (coming soon) | 50,000 rows per report | 16 MB |
| Databases, warehouses, Airtable, and Tableau | 100,000 rows | 16 MB |

These are technical limits that protect run reliability. They are the same on every plan — upgrading does not raise them.

The row limit counts **data rows**, not the spreadsheet's grid size. A Google Sheet tab with a million empty rows below a 5,000-row table reads fine; only the populated rows count.

### If Your Source Is Too Large

The fix is always to make the source smaller before it reaches the flow, not to split the flow:

- **Aggregate instead of exporting raw rows.** A daily summary by campaign is almost always more useful in a spreadsheet than a million raw events, and it is what the destination can actually hold.
- **Shorten the date range.** A rolling 30-day window keeps the flow current and bounded; a growing all-time range eventually crosses the limit.
- **Filter to the rows that matter.** Drop test accounts, internal traffic, or inactive records in the transform step.
- **Select fewer columns.** For Google Sheets sources the cell limit binds before the row limit when a tab is very wide — a 50-column tab reaches the cell limit at 10,000 rows.

## Rolling Date Ranges

For a flow to keep producing current data, its source must use a **rolling** date range such as "the last 30 days" rather than a fixed calendar range such as "January 1 to January 31."

A flow built on a fixed range would deliver the same numbers every run. The output picker blocks these results and explains why, so you can rebuild the request with a rolling range before saving the flow.

For **Meta Ads** (coming soon), ask for a moving window ("the last 30 days, by day"). Each run reads that window again in the ad account's time zone, so recent days also pick up late-attributed conversions.

## Combining Sources

A single flow can combine several supported sources into one prepared dataset — for example joining a PostgreSQL orders table to Google Ads spend by date, or GA4 sessions to an Airtable campaign list. The limits above apply to each source's own read.

Combined flows replay the same join and calculation logic on every run, so the sources must all be re-readable. If any one of them cannot be pulled again automatically, the output picker blocks the result and names the source that caused it.

## Schema Changes at the Source

Data Flows detect when a source's shape changes and stop rather than writing misaligned data:

- **Google Sheets:** if the header row no longer matches the columns the flow was built on, or the tab gains columns beyond its original width, the run fails with a schema-drift error. Restore the header or rebuild the flow against the new shape.
- **Chat-built sources:** if the transform's expected columns are missing from a later run, the run fails before the destination is touched.
- **Meta Ads (coming soon):** a flow keeps the columns of the report it was built on. Conversion columns such as `actions.purchase` come back empty on a run with no activity for that action, and an action type that first appears later is not added. Fetch the report again in chat and update the flow to pick up new columns.

This is intentional. A flow that silently adapted to a renamed column would quietly corrupt the destination table it has been maintaining.

## Reconnecting a Source

When a source's sign-in expires or loses access, the next run stops with a reconnect-required error and the flow owner gets a notice naming the source. Reconnect it from **Connected Data Sources**, then resume the flow. Temporary provider problems, such as an API rate limit, are retried automatically.

## Next Steps

- [Create a flow](https://betteranalyst.com/docs/data-flows/create-a-flow)
- [Choose a destination and write mode](https://betteranalyst.com/docs/data-flows/destinations)
- [Write to a database table](https://betteranalyst.com/docs/data-flows/database-destinations)
