Short answer: CTAS and RTAS are atomic in Spark with Iceberg when you use SparkCatalog, because that catalog implementation stages the metadata change and commits it in a single transition. SparkSessionCatalog does not provide the same atomic commit behavior. RTAS, when atomic, replaces the current table pointer but preserves snapshot history, which means you can recover an earlier state if snapshots are still retained. These statements reflect the documented behavior of Iceberg for Spark and the Iceberg table format, as of the Iceberg documentation and spec checked on November 9, 2026.
How Iceberg implements atomic CTAS and RTAS
Iceberg separates data files and table metadata. Writes produce new data files and then create or rewrite metadata files that point to those data files. Atomic CTAS and RTAS depend on how the metadata file updates are staged and committed. When a catalog coordinates metadata updates by writing temporary metadata and then atomically moving the table pointer, the operation appears atomic to clients. When a catalog does not coordinate that transition, partial-visible states can appear, such as a new table directory with data files but no committed metadata pointer, or a table pointer that points to a partially written metadata file.
Iceberg documents the mechanics for Spark in its Spark DDL and writes documentation, which explains how table metadata and commits are performed for different catalog types. See the Iceberg Spark DDL documentation for the DDL semantics and the Iceberg Spark writes guide for write behavior. The Iceberg spec describes snapshot and manifest behavior that underpins RTAS snapshot history (sources cited below).
Atomic staged table commit. Each stage has a result that can be checked before the next stage begins.
Diagram 1, Atomic staged table commit
Sketch: writer produces data files, writer produces a new metadata draft that references those data files, catalog atomically swaps the table metadata pointer to the new metadata draft. If the swap succeeds, clients see the new table. If the swap fails and the catalog never pointed at the new metadata draft, the table remains unchanged, and temporary metadata and data files can be garbage collected later.
Catalogs that matter: SparkCatalog versus SparkSessionCatalog
Spark exposes multiple catalog integrations for Iceberg. The two most commonly discussed are SparkCatalog and SparkSessionCatalog. They differ in how they manage metadata locations, staging, and commits.
SparkCatalog is an Iceberg catalog implementation that integrates with external catalog stores (for example a REST catalog, Hive Metastore, or Glue). When configured to do the metadata pointer swap as an atomic operation using the catalog store API, SparkCatalog can stage metadata and then commit the table metadata change as one atomic transition. Because the catalog controls the table pointer, concurrent readers see either the old or the new table state, not an intermediate state.
SparkSessionCatalog is the Spark default catalog that treats table metadata more like a Hive style table on the file system. In many deployments it writes metadata files to a filesystem location and relies on eventual visibility of those files. That does not, by itself, guarantee the same atomic swap semantics as a catalog that provides a compare-and-set or single-pointer update to the table location. In practice, CTAS or RTAS using SparkSessionCatalog may expose transient states where data files or metadata drafts exist but the catalog pointer is inconsistent.
SparkCatalog versus SparkSessionCatalog. Each technical risk needs a matching test, boundary, or operating signal.
Diagram 2, SparkCatalog versus SparkSessionCatalog
Use this diagram to visualize where the pointer-swap happens for SparkCatalog and where it is absent or weaker for SparkSessionCatalog.
RTAS and snapshot history
Replace-table-as-select rewrites the table metadata so that the current table snapshot points to a new set of manifests and data files, but Iceberg retains earlier snapshots unless they are explicitly expired or removed by retention settings. That means you get a recovery path back to previous snapshots, subject to retention and garbage collection rules. RTAS changes the table pointer while preserving the snapshot chain so you can roll back by restoring an older snapshot id or by creating a new table state using a historical snapshot.
RTAS snapshot history. The loop turns table or catalog signals into controlled operational changes.
Diagram 3, RTAS snapshot history
Important caution, stated clearly: RTAS snapshot history is only useful while snapshots remain retained. If retention policies or explicit expire-snapshots operations have removed the historical snapshots, you cannot recover the prior state from Iceberg metadata. Always verify retention settings before relying on RTAS history for rollback.
Partitioning and CTAS gotchas
CTAS does not infer every property from the source table. You must declare partitioning deliberately if you need it. Many users expect CTAS to copy partitioning and table properties exactly. In Spark with Iceberg, CTAS creates a new table using the SELECT output schema and default properties unless you explicitly specify partitioning, format, or other table-level options. That means CTAS can produce a table with a different partition layout than the source, which affects file sizes, pruning, and read performance.
Practical rule: always specify partitioning and table properties in your CTAS DDL if you care about physical layout. If you need an exact structural copy you can create the table from the source schema and then run an INSERT INTO SELECT, rather than CTAS, to ensure the table metadata is explicit and deliberate.
Worked example: configure SparkCatalog
This section shows an example Spark configuration for SparkCatalog. Verify your Spark and Iceberg versions against the official Iceberg Spark DDL documentation before applying, because configuration keys and catalog capabilities can vary by version (facts checked on November 9, 2026).
Example steps below assume a REST catalog or a metastore-based catalog that supports atomic pointer updates. Replace the example values with your catalog endpoint and credentials. The goal is to direct SparkCatalog to use an external catalog implementation so metadata pointer swaps are coordinated by the catalog.
Notes on the snippet above: the catalog implementation key points SparkCatalog at an implementation that can provide atomic metadata updates, such as a REST-based catalog. If you use a Hive Metastore or Glue, substitute the documented implementation class and configuration keys. See the Iceberg Spark DDL documentation for the exact keys and for capabilities that vary by catalog type.
For readers using Dremio documentation, the Dremio blog post explaining the Apache Iceberg REST catalog is useful to understand how a catalog like RESTCatalog works and why catalog-managed pointer swaps are atomic when the catalog supports them. That post gives deployment context and examples that complement the generic Iceberg docs linked in Sources.
Worked example: run CTAS and RTAS
These examples assume Spark in your shell or notebook is already configured with the SparkCatalog named my_catalog from the previous section. They use SQL DDL compatible with Iceberg as implemented for Spark. Verify the DDL options in the Iceberg Spark DDL docs for your version.
<!--
-- CTAS: create a new table from a query result, specifying partitioning and format
spark.sql("CREATE TABLE my_catalog.db.my_ctas_table USING iceberg PARTITIONED BY (country, dt) AS SELECT * FROM source_db.source_table WHERE dt > '2026-01-01'")
-- RTAS: replace the table contents atomically, keeping snapshot history
spark.sql("REPLACE TABLE my_catalog.db.my_ctas_table USING iceberg AS SELECT * FROM another_source WHERE dt > '2026-01-01'")
-->
Behavior to verify after each statement: with SparkCatalog, the CREATE TABLE ... AS SELECT should appear in the catalog only after the metadata pointer swap completes. The REPLACE TABLE ... AS SELECT should update the table pointer to a new snapshot while keeping previous snapshots. Check the Iceberg metadata or the table history (time travel) to confirm older snapshots are available.
For inspecting metadata, the Iceberg metadata tables expose internals. If you want a Dremio-specific explanation of querying metadata tables and what to look for in manifests and snapshots, see the Dremio blog post on Iceberg metadata tables and querying the internals. It shows how to read the metadata tables to confirm manifests, snapshots, and file lists after your CTAS or RTAS run.
Worked example: inject a failed write and verify table visibility
To test atomicity, inject a failure between data file creation and metadata commit and verify whether the table is visible to readers. The following sequence can be used in a test cluster, for example Apache Iceberg Partition Statistics: compute_partition_stats, Pruning, and Query Planning or Parquet Bloom Filters in Apache Iceberg: Configuration, Selectivity, and Row-Group Skipping. Use a controlled environment only; do not run destructive tests on production without approval.
Test sequence outline:
1. Start a CTAS job that writes data files to the table location but pause the job or block the metadata commit. You can do this by instrumenting the catalog or by using a network rule that blocks the catalog endpoint briefly. If you are using a REST catalog you can return a failure for the commit call. Run this on a test cluster such as Apache Iceberg Partition Statistics: compute_partition_stats, Pruning, and Query Planning so you can safely control the catalog endpoint.
2. While the job is paused after data file creation, try listing the table from another session. With an atomic catalog, other sessions should not see the new table until the metadata commit completes. With a non-atomic catalog, you might see partial files or a directory that looks like a new table but lacks a valid committed metadata pointer.
3. Allow the metadata commit to fail or to be canceled. Observe whether the table pointer changed. If the catalog is atomic, the pointer either remains at the old state or the new table is absent. If the catalog is non-atomic, you may need to run a cleanup pass to remove unregistered data files and metadata drafts. Confirm using the Iceberg metadata tables or the catalog API that no new snapshot is visible.
4. Now allow a successful run. The metadata commit should swap the pointer and the table should appear in queries. For RTAS, verify that the new snapshot id is present and that the older snapshot id is still listed in the table history unless you have explicitly expired snapshots.
Failure injection and rollback test. A reversible canary keeps an unsupported client or unsafe policy from becoming a fleet-wide incident.
Diagram 4, Failure injection and rollback test
Practical rollout checklist
Before you use CTAS or RTAS in production, run this checklist in a staging environment.
Verify catalog type and version. Confirm the catalog implementation provides atomic pointer updates. Consult the Iceberg Spark DDL documentation for behavior per catalog type.
Confirm Spark and Iceberg versions. DDL and catalog behavior can vary across versions; test with your exact versions.
Define partitioning explicitly when creating tables with CTAS to avoid unintended layout changes.
Set snapshot retention policy and snapshot expiration processes that match your recovery objectives. If you need RTAS rollback, ensure snapshots are retained long enough.
Run failure-injection tests similar to the sequence above on Apache Iceberg Partition Statistics: compute_partition_stats, Pruning, and Query Planning or Parquet Bloom Filters in Apache Iceberg: Configuration, Selectivity, and Row-Group Skipping, to validate commit atomicity and cleanup paths.
Plan garbage collection for orphaned data files generated during failed attempts. Use the catalog and metadata tables to find unreferenced files.
Document procedures for rollback using snapshot ids and for restoring metadata if you must recover after snapshot expiration, noting that recovery may be impossible if metadata history is pruned.
Failure modes and recovery
Expect the following failure modes and design for them.
Metadata commit failure: If the catalog commit fails after data files are written, an atomic catalog will not point to the new metadata. Orphan data and temporary metadata files remain and must be collected. If your catalog is non-atomic, partial state may be visible and manual reconciliation is needed.
Partial CTAS visibility: Readers may see a new directory with data files but no metadata pointer. This breaks queries that expect a complete Iceberg table and may cause inconsistent reads. Detect by checking whether the table has a valid current snapshot in the metadata table.
RTAS snapshot loss: If retention or explicit expire-snapshots has removed earlier snapshots, you cannot roll back. Always check retention windows before relying on snapshot history for rollback. The Iceberg spec and write docs describe how snapshots are recorded and expired.
Partition mismatch: CTAS without explicit partitioning can create different partitioning than the source, causing performance regressions. Measure file size distribution, partition counts, and read latency after CTAS.
What to measure after deployment
After you deploy CTAS and RTAS in production, collect these metrics and audit signals regularly.
Commit success and failure rates for CTAS and RTAS operations, including duration from write start to metadata commit. Spikes in commit latency often indicate catalog contention or network issues to the catalog endpoint.
Number of orphaned data files and total bytes of unreferenced files. If this grows, your cleanup or garbage collection process is not keeping up.
Snapshot counts and age distribution. Track how long snapshots remain and whether retention policies are removing snapshots earlier than you expect.
Query latency and scan bytes for tables created by CTAS, especially when partitioning differs from the source. Compare query profiles before and after CTAS.
Manifest and file counts per snapshot. Very large numbers of small files indicate partitioning or file-size configuration issues.
Evaluation sequence and decision points
When deciding whether to use CTAS or RTAS with a given catalog, run this evaluation sequence.
1) Confirm catalog atomicity: Run an isolated CTAS with failure injection on a test cluster (Apache Iceberg Partition Statistics: compute_partition_stats, Pruning, and Query Planning or Parquet Bloom Filters in Apache Iceberg: Configuration, Selectivity, and Row-Group Skipping). If the table never appears until the commit completes, your catalog is behaving atomically.
2) Check metadata visibility and history: After RTAS, list snapshots and ensure older snapshots exist and reference correct manifests. Use the Iceberg metadata tables to validate snapshot lineage.
3) Validate partitioning and performance: Create a CTAS table with and without explicit partitioning, run representative queries, and capture scan bytes and latency to pick correct defaults.
4) Measure cleanup: Force a failed run and measure time and tools required to remove orphan files. If cleanup is manual and error prone, consider changing catalog or adding automation.
5) Decide production readiness: If atomicity, snapshot retention, and cleanup behavior meet your recovery and performance needs, proceed. Otherwise adjust configuration or use CREATE + INSERT pattern instead of CTAS.
Limits and when to avoid CTAS/RTAS
Avoid using CTAS as a shortcut when you need guaranteed copy of all source table properties unless you explicitly set those properties. Avoid RTAS if your retention policy purges snapshots aggressively and you require rollback protection. If your catalog does not support atomic pointer updates, prefer CREATE TABLE then INSERT INTO, which lets you control the commit step more explicitly and lets you validate the table before you switch production traffic.
FAQ
Does Spark guarantee CTAS atomicity for Iceberg tables?
No. CTAS atomicity depends on which catalog you use. SparkCatalog implementations that coordinate metadata commits can provide atomic CTAS, but SparkSessionCatalog does not provide the same guarantee. Verify your catalog type and implementation against the Iceberg Spark DDL documentation (facts checked on November 9, 2026).
Will RTAS let me roll back to the previous table state?
Usually yes, RTAS preserves snapshot history so you can revert to an earlier snapshot id, provided those snapshots have not been expired or garbage collected. Confirm snapshot retention settings before relying on this for recovery.
How do I test whether my catalog is atomic?
Run a CTAS while blocking the catalog commit call, then query the table from a separate session. If no partial state is visible until commit completes, the catalog is acting atomically. Use controlled failure injection on a test cluster, such as Apache Iceberg Partition Statistics: compute_partition_stats, Pruning, and Query Planning or Parquet Bloom Filters in Apache Iceberg: Configuration, Selectivity, and Row-Group Skipping.
What happens to orphaned data files after a failed CTAS?
If the metadata commit never completes, data files and temporary metadata may be orphaned. You must run a cleanup process to remove unreferenced files, using the catalog API or metadata table listings to find files not referenced by any snapshot manifests.
Does CTAS copy partitioning from the source table?
No. CTAS produces a table based on the SELECT output schema and the table creation options you supply. If you need the same partitioning, declare it explicitly in the CTAS DDL or create the table separately and run an INSERT INTO.
Which docs should I read to understand the commit and snapshot mechanics?
Start with the Iceberg Spark DDL guide and the Iceberg Spark writes documentation to understand write and commit mechanics. For the table format and snapshot model, read the Iceberg spec. Links to all three are provided in the Sources section. Also read the Dremio posts I referenced for REST catalog behavior and for how to inspect metadata tables.
Related Dremio guides
Continue with these related implementation guides.
Intro to Dremio, Nessie, and Apache Iceberg on Your Laptop
Editor’s note, September 2026. This post was published in September 2023 and some product details have changed since. Nessie is still available and self-deployable under the Apache-2.0 licence, and it remains the clearest implementation of catalog-level branching. It is not an Apache Software Foundation project, and its development has slowed considerably. For how the current […]
Oct 12, 2026·Dremio Blog: Open Data Insights
Apache Iceberg Table Statistics: NDV, Puffin and Query Plans
Iceberg keeps per-file bounds automatically but table-level NDV statistics only when you compute them. Why that decides join order, and how to keep them fresh.
Aug 16, 2023·Dremio Blog: News Highlights
5 Use Cases for the Dremio Lakehouse
With its capabilities in on-prem to cloud migration, data warehouse offload, data virtualization, upgrading data lakes and lakehouses, and building customer-facing analytics applications, Dremio provides the tools and functionalities to streamline operations and unlock the full potential of data assets.