The scenario
Hartwell Stores runs 340 retail locations. Every till transaction for the last seven years — about six terabytes — lives in a Snowflake warehouse the data team has spent three years curating. Now the personalization program needs store purchase history inside Data 360, joined to the unified profiles built in the fundamentals series.
The first proposal was the reflexive one: a nightly export pipeline copying Snowflake tables into Data 360. The data team pushed back hard, and they were right. A copy means double storage cost, a second source of truth that drifts from the first, up to 24 hours of staleness, and a pipeline someone has to own forever. The warehouse already answers these queries — the problem isn't the data, it's where it's queryable from.
This is the problem zero copy data federation exists to solve, and it's the most misunderstood feature in Data 360. This post assumes you know the DLO/DMO pipeline from Part 1 — here we go deep on the federation layer.
What zero copy actually is
When you federate a Snowflake table, Data 360 creates an external data lake object — a DLO that contains only metadata: the schema, the connection, and where the real rows live. No rows move. When a query touches that external DLO, Data 360 pushes the work down to the source — query federation — and stitches the results into the rest of the query.
The umbrella term covers three distinct capabilities, and mixing them up derails design conversations:
| Capability | Direction | What moves |
|---|---|---|
| Query federation | Warehouse → Data 360 | Nothing at rest; query results at query time |
| File federation | Warehouse → Data 360 | Nothing; Data 360 reads the underlying files (e.g. Iceberg) directly |
| Data share out | Data 360 → warehouse | Nothing; the warehouse queries Data 360 objects as shared tables |
Hartwell needs the first one. The same pattern works across the supported platforms — Snowflake, Google BigQuery and Databricks all expose their tables to Data 360 as external DLOs, with federated authentication supported for all three.
Worth internalizing: an external DLO behaves like any other DLO downstream. You map it to DMOs, join it in Calculated Insights, and reference it in queries — the fact that its rows live in Snowflake is invisible to consumers. That's the entire point.
Federate or ingest? The real decision
Zero copy is not automatically the right answer — it changes where compute happens and when you pay for it. The decision that held up at Hartwell:
| Factor | Federate (zero copy) | Ingest (copy in) |
|---|---|---|
| Freshness | As fresh as the source, at query time | As fresh as the last stream refresh |
| Cost profile | Source compute (e.g. Snowflake warehouse) burns on every federated query | Ingestion and storage credits once; queries hit local data |
| Hot-path use (segments, frequent CIs) | Risky — every refresh re-queries the warehouse | Designed for it |
| Huge, rarely-touched history | Ideal — pay only when you actually ask | Wasteful — terabytes stored to answer occasional questions |
| Ownership | Warehouse team keeps one source of truth | Two copies, two owners, drift risk |
Hartwell's split: the seven-year transaction history stays federated (occasionally scanned, painful to copy), while a slim, pre-aggregated monthly spend per loyalty member table is ingested normally, because it feeds identity-adjacent attributes and segment refreshes daily. Federate the archive, ingest the hot path — that hybrid is the pattern most real implementations land on.
Setting up the Snowflake connection
The setup is deliberately anticlimactic — that's the feature. In Data 360 Setup:
- Create the connection. Add a Snowflake connection with the account URL, a dedicated warehouse, and a role scoped to exactly the schemas Data 360 may see. Hartwell created a
DATA360_READERrole in Snowflake first — least privilege lives on the warehouse side. - Create the data stream. New data stream → Snowflake connector → pick the connection, database, schema, and the
STORE_SALEStable. Instead of scheduling a refresh that copies rows, this materializes an external DLO. - Map it. Map the external DLO's fields to DMOs exactly as you would any DLO — Hartwell maps
LOYALTY_IDto the same key their ingested profile data uses, which is what makes the join to unified profiles possible.
BigQuery and Databricks follow the same three steps with their own connectors; the external DLO you end up with is indistinguishable downstream.
The payoff: one query across both worlds
With Snowflake_Store_Sales__dlm mapped, warehouse history joins Data 360 objects in ordinary ANSI SQL. Hartwell's first production Calculated Insight — in-store spend per unified customer over 90 days:
SELECT
p.customer_id__c AS customer_id__c,
SUM(s.net_amount__c) AS store_spend_90d__c,
COUNT(DISTINCT s.store_id__c) AS stores_visited__c
FROM Snowflake_Store_Sales__dlm s
JOIN Loyalty_Profile__dlm p
ON p.loyalty_id__c = s.loyalty_id__c
WHERE s.sale_date__c >= CURRENT_DATE - INTERVAL '90' DAY
GROUP BY p.customer_id__c
What executes where: the scan and filter on Snowflake_Store_Sales__dlm are pushed down to Snowflake — six terabytes are reduced to a 90-day aggregate before anything crosses the wire — and Data 360 joins that slim result to the local profile data. The narrower your filters and projections, the less the warehouse does and the faster (and cheaper) the query returns.
That CI now feeds a "high in-store, low online" segment for the e-commerce team — unified profile attributes and warehouse history in one definition, with the SQL discipline from the Calculated Insights build applying unchanged.
The bill has two line items now
Federation's failure mode isn't technical — it's a surprise invoice. Every federated query costs twice: Data 360 consumption credits and source-side compute. Three rules keep Hartwell's setup boring:
- Never put an external DLO in a fast refresh loop. A segment refreshing every hour against federated data is a warehouse-compute subscription you didn't mean to buy. Aggregate federated data into a scheduled CI once a day; let segments and dashboards read the CI.
- Push aggregation down, always.
SELECT *from a federated DLO drags raw rows across the boundary. Filter and aggregate in the query so the warehouse ships summaries, not history. - Watch both meters for the first month. Data 360's consumption cards and the dedicated warehouse's billing, side by side — the same discipline as the analytics build, with a second bill attached.
What you learned
- Zero copy = external DLOs holding metadata only, with query federation pushing work down to Snowflake, BigQuery or Databricks at query time.
- Query federation, file federation and data share out are three different capabilities — be precise about which one you're proposing.
- Federate the huge, rarely-scanned archive; ingest the hot path that feeds segments and identity — hybrid is the normal answer.
- Filters and aggregation belong in the query so reduction happens warehouse-side; never fast-refresh against federated data.
- Budget both meters: Data 360 credits and source compute.
Next in the advanced series: data graphs — when the answer has to come back in milliseconds, not warehouse time. The full track lives on the Data 360 page.
Sources: Salesforce Help — Zero Copy Data Federation · Salesforce Developers — Zero Copy Data Federation with Snowflake · Data 360 Integration Guide — Databricks Connectors