Zero Copy Isn't Zero Cost. So What?
Share on LinkedInThe name does a lot of selling. Zero copy. No pipelines, no duplicate data, no storage bill. It’s easy to hear “zero cost” in there, and plenty of people do.
Salesforce Data 360 (formerly Data Cloud) can read your Snowflake or Databricks data where it lives. That part is true, and it’s genuinely useful. But connecting the data is free; using it isn’t.
The concept in one sentence
Zero copy lets Data 360 query your data lake instead of copying the data in, which trades a one-time loading cost for a charge every time the data is read.
So what?
About the numbers: every rate and estimate in this post comes from Salesforce’s published list rates as of October 2026 and is for illustration only. Rates change, contracts vary, and your org may be on a different credit model, so check your own contract before deciding anything.
You pay per read, not per table. Federated data is billed on rows accessed: the records Data 360 actually retrieves from the lake each time a segment, calculated insight, or query touches them. On Salesforce’s published rate card, that’s 70 credits per million rows. Copying data in by batch costs 2,000 credits per million rows, once, plus whatever changes later.
Do the division and you get a rule of thumb worth remembering:
If the same rows will be read more than about 29 times, copying them in is cheaper. For streaming ingestion, which costs 5,000 credits per million rows, the break-even is closer to 70 reads.
There’s a second bill. A federated query runs on your lake’s compute, so Snowflake or Databricks charges for it too. That invoice goes to the data team, not to whoever owns Data 360, which is how it surprises people. File federation avoids most of it, because Data 360 reads the files directly instead of asking the lake to run a query. Caching sits in between, and it has its own trap.
Caching is a copy, on a schedule. Acceleration is a setting on each zero copy data stream, and you can turn it on or off. Off, every read goes to the lake as a live query, which is the per-read billing above. On, Data 360 keeps a cached copy of the lake data, refreshed anywhere from every 15 minutes to every 7 days, and reads hit the cache instead of the lake. But Salesforce bills loading that cache exactly like copying data in: 2,000 credits per million rows. So the refresh type matters more than anything else:
- Incremental refresh loads only new or changed rows. It costs about the same as copying the data in.
- Full refresh deletes the cache and reloads every row, every time. It’s also what you get unless someone sets up incremental refresh with a record-modified field.
Cache a 50 million row table with a daily full refresh and you’re loading 1.5 billion rows a month. Even incremental refresh can overshoot: in Salesforce’s own billing example, refreshing a cache every 30 minutes costs 28,800 credits a month against 4,200 for live queries. Match the schedule to how often the data actually changes. (Incremental refresh also doesn’t remove deleted rows, so Salesforce recommends an occasional full refresh anyway.)
Volume matters, but not the way you’d think. What’s billed is rows read, not the size of the table. Salesforce’s billing documentation says it directly: rows accessed depend on the structure of the query and aren’t the same as the number of rows in the source.
That’s easiest to see with one table and two uses. Take a fictional retailer with 50 million orders in Snowflake, adding 1.5 million a month. One use is a daily segment of last month’s buyers, built on a Snowflake view that only holds recent orders. The other is a daily calculated insight for lifetime spend, which needs every order. That one isn’t a contrived worst case: a batch calculated insight processes every record in the objects it’s built on, each time it runs, and Salesforce’s own pricing example assumes the same thing for federated data.
| Daily segment: last month’s buyers | Daily insight: lifetime spend | |
|---|---|---|
| Rows pulled per run | 1,500,000 (one month of orders) | 50,000,000 (every order) |
| Runs per month | 30 | 30 |
| Federated, per month | 3,150 credits | 105,000 credits |
| Copied in instead | 100,000 once, then ~3,000 a month | 100,000 once, then ~3,000 a month |
| Cached, incremental refresh | 100,000 once, then ~3,000 a month | 100,000 once, then ~3,000 a month |
| Cached, daily full refresh | ~3,000,000 a month | ~3,000,000 a month |
| Cheaper option | Federate | Copy, or cache incrementally (pays for itself within a month) |
Try it with your own numbers. Pick either example from the dropdown, then change anything. Both start with the cache on Data 360’s default full refresh; switch it to incremental and watch that number drop.
Run your own numbers
Pick an example, then change any number to make it yours.
How the data is used (applies to every option)
If acceleration is on (only affects the middle result)
What each option costs (credits)
First year with acceleration off: 37,800 credits. On, with full refresh: 36,100,000. Acceleration off is more than 20x cheaper.
Federate with acceleration off. Over the first year that's about 37,800 credits, against about 136,000 credits to copy it in.
For illustrative purposes only. Verify all numbers independently before implementing a solution. All figures are credits, at Salesforce list rates as of October 2026: federation at 70 per million rows read; copying in and caching at 2,000 per million rows loaded (batch). Rates change and contracts vary. Federation also costs compute on your data lake for each query, not shown here. Charges for querying data inside Data 360 apply to every option and are left out.
Same table, same connection, opposite answers. The insight also runs a full-table scan on the Snowflake side every day, which is the second bill again. And it costs calculated insight credits whether the data is federated or copied, so that charge doesn’t change the comparison.
None of this is hypothetical. Salesforce’s own zero copy pricing example federates 25 million records from Snowflake and estimates 114 billion rows accessed in a year, because daily insights and thousands of daily queries keep reading the same records.
What goes wrong when teams miss this
Zero copy gets chosen because it sounds cheaper and simpler, and nobody models the reads. Six months later, two people ask questions on the same day. Finance asks why credit consumption climbed. The data team asks why the warehouse bill did too.
The other version is quieter. Someone builds a calculated insight or a broad segment against a federated table, runs it daily, and nobody notices that each run reads the whole thing. Nothing breaks. It just costs more every day.
The question to ask your team
Before choosing zero copy for a dataset, ask this:
“How many rows will each read touch, how often will it be read, and how often does the data change?”
Read often, changes rarely: copy it, or cache it with incremental refresh on a schedule that matches how often the data changes. Changes constantly, read rarely or narrowly: federate it, with acceleration off. Audited or regulated: copy it, whatever it costs. And wherever you federate, filter at the source, with views or conditions in the lake, so each read pulls back only what it needs.
Often the answer is a mix. Federate the big table for narrow lookups, and copy in a summarized version for the insight that needs everything.
The external data lakes guide walks through all four options and has a short helper for this exact decision. The rates will move over time; the questions won’t.
I write about building with AI and the Salesforce platform. Follow along on LinkedIn.
Share on LinkedIn