Iceberg Interoperability Has a Bill: Who Pays When Another Engine Reads Your Snowflake Tables
Ed Ost. I work at Qlik, which sells data integration software that writes Iceberg tables. This post names no vendor’s integration product, and the analysis applies however your Iceberg tables get written.
Apache Iceberg promises that you can store data once and query it with whatever engine suits the job: Snowflake for governed analytics, Athena for cheap SQL transformations, Databricks for data science. The table format delivers on that promise. The economics and governance often don’t, at least not automatically.
When I traced what actually happens when Athena or Databricks reads a Snowflake-managed Iceberg table, the answer was rarely “it just reads the files.” Depending on the path, you may pay Snowflake compute for a query that runs in another engine, lose the row-level security you thought you had, or find that the other engine can’t read the table at all. None of this is bad faith by vendors. Iceberg is a specification, and the vendors made different, reasonable design choices. Interoperability comes from how those choices fit together, and they don’t always fit.
This post covers three things:
- Where the hidden compute and governance gaps are when engines share Iceberg tables.
- Where the real savings come from, with a cost model you can rebuild.
- A short set of design rules.
The capability details reflect vendor documentation as of October 2026. This area changes monthly, so check the statuses before you rely on them.
The two questions that decide everything
Most Iceberg interoperability discussions start with the file format. I think they should start with two questions:
- Who owns the write path? That is, which engine and catalog commit new snapshots to each table.
- Who owns the consumer catalogs? Note the plural. Each engine that reads the table reaches it through some catalog, and that catalog’s rules decide who pays and which security applies.
If Snowflake’s Horizon catalog owns a table, every other engine is a guest. Guests get in through one of a handful of doors, and each door has its own price and its own rules.
Five doors into a Snowflake-managed Iceberg table
| Path | How it works | Read / write | Whose security applies | Who pays |
|---|---|---|---|---|
| Spark or Trino through Horizon’s Iceberg REST endpoint | The engine gets table metadata and short-lived storage credentials, then plans and reads files itself | Read and write GA (write GA since May 2026) | Snowflake object grants, per role. Row and column policies are not applied | Your engine, plus catalog API calls (0.5 credits per million, billing scheduled from H2 2026) |
| Scan Plan API | The engine asks Snowflake to plan the scan. Snowflake applies row and masking policies by materializing a filtered copy in your storage, and the engine reads that | Read (Public Preview since September 2026; Enterprise edition and above) | Full Snowflake policies | Snowflake serverless compute, plus double I/O: Snowflake reads, filters and writes; your engine reads again |
| Snowflake connector for Spark | The connector detects protected tables and runs the query in a Snowflake warehouse | Read and write GA | Full Snowflake policies | Snowflake warehouse credits for every routed query, while your Spark cluster waits |
| Athena through Glue catalog federation | The Glue catalog proxies Horizon. Athena reads as one federation service principal | Read GA. Treat it as read-only: Snowflake documents writes as unsupported, and in an independent July 2026 test an Athena INSERT through federation failed | Snowflake grants of the federation principal as an upper limit, then Lake Formation policies declared again on the AWS side | Athena per-TB scan plus catalog calls |
| Databricks through a Unity Catalog foreign catalog | Unity federates to Horizon | Read-only | Unity grants, declared again | Databricks compute, if it can read the table (see delete files below) |
The common thread: row- and column-level security doesn’t cross a catalog boundary for free. Today only two mechanisms enforce Snowflake’s fine-grained policies for an external engine, the Scan Plan API and connector routing, and both run on Snowflake compute. Every federation path enforces only the policies the consumer declares again.
That is the hidden bill. If your plan for “use Athena or Databricks to save money” relies on those engines respecting Snowflake’s row access and masking policies, part of the work moves back onto Snowflake’s meter.
Three surprises worth designing around
1. Federation collapses identity. Glue federation, Unity foreign catalogs and Snowflake catalog-linked databases all connect to the remote catalog as a single service principal. The source catalog’s per-user security becomes an upper limit for everyone, and per-user rules have to be declared again on the consumer side. This is a separation-of-duties question as much as a security one. The platform engineer who configures that principal sets the maximum anyone downstream can see, and a different administrator grants access within that limit. That is two authorities over one dataset, and design reviews should name both.
2. Delete files are the real compatibility boundary, more than catalogs. CDC pipelines produce row-level deletes. Iceberg v2 records them in delete files; v3 adds deletion vectors. Engines differ:
- Databricks reads v3 deletion vectors but not v2 position or equality deletes.
- Athena SQL works only with v2 tables and writes merge-on-read deletes.
- External writers to Horizon can’t write equality deletes.
So a Silver table updated by Athena MERGE can be unreadable in Databricks until it is compacted, whichever catalog owns it. Choose the table version, merge mode and compaction schedule for each table based on who reads it.
3. Every federation hop adds metadata latency and limits. For example, Glue federation rejects tables whose metadata response exceeds 5 MB, and catalog-linked databases poll for changes every 30 seconds by default. These limits are manageable, but you only find them by testing.
The other direction: let the lake own the catalog
The alternative is to reverse ownership. Bronze and Silver tables live in a lake catalog (AWS Glue in this example), and Athena reads and writes them natively. Silver is then registered into Snowflake as externally managed Iceberg tables, with no copy, so Gold builds and governed consumers work in Snowflake as usual.
What this gives you:
- Athena does Bronze and Silver work with no federation hop, and that work runs on no Snowflake warehouse.
- Snowflake still applies full role-based access, masking and row access policies to anyone querying through Snowflake.
- Each consumer can use the catalog that suits it: Snowflake for Gold, Unity for data science, Glue for AWS engines. Each inherits its own catalog’s security.
What it costs, stated plainly:
- Two policy estates. Lake Formation governs the lake side and Snowflake governs the registered side. Policies don’t carry over between them.
- Refresh dependency. Snowflake reads the last registered snapshot, so freshness depends on the refresh cadence. A refresh mode that updates all tables together gives cross-table consistency for Gold builds, at the cost of some lag.
- Snapshot retention. If the writer’s maintenance deletes files that Snowflake’s registered snapshot still uses, queries fail until the next refresh. Line up retention with the refresh interval.
- A privileged storage role. Anyone who can assume the storage role bypasses both Snowflake and Lake Formation policies. Treat it as privileged.
Neither direction is free. The choice is between paying the source engine for governed external reads, or running a second governance estate.
Where the savings actually come from
There are two separate cost levers, and they add up:
- Ingestion efficiency: the compute used to apply CDC and maintain Iceberg tables. Public benchmarks put this lever at a large share of ingestion compute. That is a topic for another post.
- Fit-for-purpose transformation: running Bronze standardization and Silver conforming and de-duplication on Athena rather than on Snowflake warehouses. This lever is the subject of the model below.
I built a rough order-of-magnitude model for the second lever, for a large enterprise spending roughly $1–4M a year on Bronze and Silver compute in Snowflake. That is comparable to a large bank or a multi-hospital health system. Like the rest of this post, it is vendor-neutral. It is not based on any customer’s data, and I would trust each result to about ±50% at best.
The model
Snowflake bills by time: credits per hour × price per credit, including idle time. Athena has two pricing models, and they need different comparisons.
Athena on-demand bills by data scanned (5.00/TB, plus about 0.50/TB for S3 and Glue requests). The key input is your effective Snowflake cost per TB scanned, S:
S = (Snowflake credits billed × $/credit) ÷ TB scanned by the same warehouses
Athena compute = B × (k × $5.50) ÷ S
Here B is your current annual Snowflake spend on Bronze and Silver, and k is how many bytes Athena scans relative to Snowflake for the same work (assumed 1.1).
Athena capacity reservations bill by DPU-hour held ($0.30 per DPU-hour, no per-TB charge). This makes the comparison time-for-time, and the critical unknown is E: how many Athena DPU-hours it takes to do the work of one productive Snowflake credit-hour.
Productive credit-hours = (B ÷ $/credit) × Usf
Athena compute = productive credit-hours × E ÷ Uath × $0.30
Here Usf is the share of billed Snowflake time spent running queries, and Uath is the share of reserved Athena capacity actually in use. Reservations win whenever E is below (Uath × /credit) ÷ (*U*sf × 0.30). In the mid case, that means anything under about 14 DPU-hours per credit-hour.
Both models deduct the costs that exist only after the move:
- Iceberg table maintenance (10% of Athena compute).
- Snowflake-side refresh of the registered Silver tables (about $20K a year).
- A second governance estate (about 1–2 FTE).
The governance cost is the one people forget, and at small scale it decides the outcome.
Parameters
| Parameter | Conservative | Mid | Optimistic |
|---|---|---|---|
| S: Snowflake $ per TB scanned | $9.50 | $12.00 | $15.00 |
| Usf: Snowflake productive share | 0.7 | 0.6 | 0.5 |
| E: DPU-hours per Snowflake credit-hour | 8 | 5 | 3 |
| Uath: reservation utilization | 0.6 | 0.7 | 0.8 |
Assumed prices: 3.50 per Snowflake credit (list price less an assumed contract discount) and 200K per fully loaded engineer.
Results: net annual saving after offsets
| Current Bronze + Silver spend on Snowflake | Athena on-demand (Cons / Mid / Opt) | Athena reservations (Cons / Mid / Opt) |
|---|---|---|
| $1M a year | 0.06M / **0.21M** / $0.32M (6% / 21% / 32%) | –0.15M / **0.33M** / $0.56M (–15% / 33% / 56%) |
| $4M a year | 0.76M / **1.34M** / $1.79M (19% / 34% / 45%) | –0.12M / **1.78M** / $2.69M (–3% / 45% / 67%) |
For an enterprise in the 1–4M band, the mid case is about **0.2–1.8M a year**, roughly 20–45% of Bronze and Silver compute, depending on scale and pricing model. Three things stand out:
- Percentage savings increase with scale, because governance overhead is mostly fixed. At about $0.4M of spend, neither model reliably pays back the second governance estate.
- Reservations have more upside and a real downside. At the conservative value of E, they cost more than they save. E can only be measured by benchmark.
- On-demand’s risk is re-scanning. Frequent
MERGEstatements into large Silver tables re-read those tables each run, so micro-batching every few minutes erodes the advantage. Hourly or daily batches on well-partitioned tables favor Athena.
In practice a hybrid is likely: reservations for steady CDC processing and on-demand for bursty work. Reservations beat on-demand for a workload when each reserved DPU-hour scans more than about 60 GB (0.30 ÷ 5.00 per TB).
Build your own estimate
The whole model is available as a workbook, iceberg-athena-vs-snowflake-calculator.xlsx: edit the blue input cells and the scenario matrices recalculate. Its method note documents every input and formula. You can replace most of the assumptions with your own figures in an afternoon:
-
Measure S. Divide 30 days of warehouse credits by TB scanned for your Bronze and Silver warehouses:
SET price_per_credit = 3.50; -- your contracted rate WITH q AS ( SELECT warehouse_name, SUM(bytes_scanned) / POWER(1024, 4) AS tb_scanned FROM snowflake.account_usage.query_history WHERE start_time >= DATEADD(day, -30, CURRENT_TIMESTAMP()) GROUP BY 1 ), m AS ( SELECT warehouse_name, SUM(credits_used) AS credits FROM snowflake.account_usage.warehouse_metering_history WHERE start_time >= DATEADD(day, -30, CURRENT_TIMESTAMP()) GROUP BY 1 ) SELECT warehouse_name, tb_scanned, credits, credits * $price_per_credit / NULLIF(tb_scanned, 0) AS usd_per_tb_scanned FROM q JOIN m USING (warehouse_name);Below about
6/TB, on-demand savings are marginal. Above15/TB, you’re beyond my optimistic case. -
Estimate Usf by comparing busy hours in
warehouse_load_historywith billed hours inwarehouse_metering_history. -
Benchmark E. Run a representative Silver
MERGEworkload on a small Athena reservation and on its Snowflake warehouse, and compare DPU-hours with credit-hours. This is the one input you can’t estimate from a desk. -
Cost your governance honestly. Count the people and tooling needed to keep Lake Formation and Snowflake policies in step.
-
Account for commitments. If you have a multi-year Snowflake commitment, lower consumption reduces the bill only at renewal. Until then, the saving shows up as credits freed for other work.
Design rules I’d apply
- Decide catalog ownership tier by tier, based on which engine writes each tier. Don’t adopt a single platform-wide default.
- Use plain REST catalog access, with the client planning its own scans, for anything that doesn’t need source-enforced row or column security. Save the source-enforced paths (Scan Plan, connector routing) for genuinely protected, selective reads.
- For bulk data-science reads of sensitive data, publish a de-identified table instead of paying for per-query policy enforcement.
- Choose the delete strategy for each table (v2 or v3, merge-on-read or copy-on-write, compaction schedule) based on its readers, and test cross-engine reads of tables with deletes before going to production.
- Make governance declarative. Lake Formation tag-based access control, Snowflake tag-based policies and Unity attribute-based access control are all driven by tags. Treat one version-controlled classification taxonomy as the contract, and generate each platform’s policies from it. Stewards own the tags, security owns the policies, and platform engineering owns the per-platform generators. Adding an engine then means adding a generator, not rewriting policy. Limit the policy vocabulary to what all your platforms support.
- Name the owner of every federation principal, and review its grants as the upper limit they are.
- Test the claims your design depends on. At minimum: cross-engine reads of tables with deletes, whether Athena reads v3 tables yet (AWS guidance still listed it as unsupported in October 2026), how your catalog refresh behaves, and the actual billing for external reads.
The bottom line
Iceberg interoperability is real, but it is designed, not automatic. Decide who owns the write path and which catalogs serve which consumers, and you can capture substantial transformation savings on top of whatever you save on ingestion. Assume that “open format” means “free cross-engine access,” and you may end up paying your warehouse to serve queries that were supposed to move off it.
If you run the numbers on your own workload, I’d like to hear where they land, especially your measured E.
Sources
- Snowflake: external engine access through Horizon, external writes GA (2026-05-26), enforcing policies for external engines, Scan Plan API and its public preview note (2026-09-10), catalog-linked databases, Glue catalog integration, auto-refresh
- AWS: Glue catalog federation, federating to Snowflake Horizon, Athena pricing and capacity reservations, Iceberg v3 support by service
- Databricks: Iceberg support and limitations, cross-engine ABAC (GA on 2026-10-01 per the October 2026 release notes; read-only, billed as serverless compute)
- Independent test: reading and writing Snowflake-managed Iceberg tables from each Athena engine (Classmethod, July 2026)