Data Warehouse Insider

Warehouse-Specific Schema Evolution Behavior Compared

Different warehouses handle schema changes in incompatible ways.

Contributing Editor · · 14 min read
Cover illustration for “Warehouse-Specific Schema Evolution Behavior Compared”
Data Warehouses · September 26, 2026 · 14 min read · 3,164 words

Warehouse-Specific Schema Evolution Behavior Compared.

Schema changes are a runtime problem, not a storage problem

A pipeline doesn't break because someone ran an ALTER TABLE upstream. It breaks because the row that arrives next no longer matches the shape the target table expects, and what happens at that moment depends entirely on which warehouse is sitting on the receiving end. The failure isn't a storage event, it's a runtime decision, made by the warehouse's enforcement rules rather than anything the source database decided.

Plenty of teams treat schema evolution as something to solve upstream, with dbt contracts or catalog lineage tools that document what a table is supposed to look like. That's useful work, but it misses where the first fire actually starts. The crisis hits at ingestion, before a single transformation model has run, when a CDC stream tries to write a column the target table has never seen.

A column gets added, a column gets dropped, a type changes, or a nullability constraint shifts, and these four kinds of change cause nearly all of this trouble. Every one of these is routine in a production system with any lifespan at all. Someone adds a field to support a new feature. Someone drops a deprecated column six months after nobody's used it ovaledge.com. None of that is exotic. What varies, sharply, is whether the destination warehouse absorbs the change quietly, rejects the row outright, halts the whole pipeline until a human intervenes, or lets the row through in a way that quietly corrupts what a downstream dashboard thinks is true.

That's the throughline for the rest of this piece. A pipeline built assuming BigQuery's habits will misfire the moment it's pointed at Redshift. Understanding the specific policy each platform enforces is what determines the blast radius of an upstream schema change, and that's the only way to know, in advance, how much damage a single ALTER TABLE can do downstream.

How BigQuery handles schema changes at load time

BigQuery's default posture toward new columns is permissive to the point of being invisible. Column additions are absorbed automatically at load time, with no DDL required, because schema autodetection runs against the top nesting layer of whatever's coming in. A pipeline can keep running straight through a source-side column addition without throwing a single error.

That's convenient, until it isn't. The new column appears in the target table with no notification sent anywhere, so dashboards, BI tools, and ML pipelines downstream find out about the change only when someone happens to query the table and notices a field that wasn't there last week. BigQuery doesn't fail loudly because its enforcement layer changes shape underneath you without raising an error.

Drops don't get the same treatment as additions. When an upstream column disappears, BigQuery doesn't propagate that drop on its own, it leaves the column orphaned in the target table, and it's up to the ingestion tool to decide: the orphaned column either gets null-filled going forward or throws an error. Type changes are treated differently still: BigQuery's type system will tolerate widening, an INTEGER becoming a FLOAT, for instance, but narrowing or otherwise incompatible type changes fail the load outright. And nullability isn't something a load operation can quietly override. Once a column is marked REQUIRED, it stays REQUIRED until someone changes the schema on purpose, so a source system relaxing a constraint doesn't automatically relax it on the BigQuery side.

Getting deduplicated upserts right at any real scale takes deliberate design work, not the default configuration. On the semi-structured side, BigQuery has no type literally called VARIANT, but its native JSON type, generally available since October 2022, does the same job, and handling schema drift inside that JSON column takes different query patterns than the dot-notation approach Snowflake users are used to.

New columns appear in the target table without any notification to downstream consumers, and dashboards, ML pipelines, and BI tools discover the change only when they query the table. And because BigQuery is serverless, there's less to tune when ingestion performance dips after one of these events. There's no cluster to resize, no node count to bump. The knobs other platforms give you for working around a schema-change-triggered slowdown mostly don't exist here.

How Snowflake handles schema changes with ENABLE_SCHEMA_EVOLUTION

Snowflake takes the opposite default from BigQuery: nothing happens automatically until you tell it to. The ENABLE_SCHEMA_EVOLUTION flag has to be set explicitly on a table before new upstream columns will land without manual DDL; leave it off, and a new column appears as a load error instead. That's a meaningfully different failure mode from BigQuery's always-on detection, and it catches teams off guard in a specific way: whoever stands up a new table and forgets to flip the flag will watch ingestion fail the first time a source schema changes, rather than watching a column silently appear.

Column drops follow a similarly manual philosophy. Snowflake won't drop a column from the target table just because the upstream source dropped it: the column sticks around, filling with NULLs on every subsequent row, until the replication layer makes an explicit decision to issue the DDL that removes it. Type changes work the same way. Something like VARCHAR converting to NUMBER on the source side needs an explicit ALTER TABLE on the Snowflake side, or the pipeline fails trying to write it. Nullability shifts require the same explicit intervention: Snowflake supports NOT NULL constraints, and changing one after the fact means DDL, not a passive load-time adjustment.

For teams whose upstream schemas are semi-structured and change often, Snowflake's VARIANT type offers a way to sidestep the whole problem, at least temporarily. VARIANT handles JSON natively, with colon notation for direct field access and dot notation for traversing nested structures, and storing volatile fields there defers schema enforcement rather than solving it. It's a deferral, not a fix, but a useful one when the upstream shape is still settling.

Snowflake's Iceberg integration changes the math on one specific operation: renames. Rather than requiring a data rewrite, a rename under Iceberg becomes a metadata operation, which matters a great deal for teams operating at the lakehouse layer, though the ingestion pipeline still has to recognize the rename event and handle it, Iceberg doesn't make that recognition automatic. Snowflake compute runs $2.00 per credit on Standard, $3.00 on Enterprise, and $4.00 on Business Critical, with storage at roughly $23 per terabyte per month on-demand, and an X-Large warehouse left running overnight can burn around $32 an hour on Standard edition ovaledge.com. That's directly relevant when a schema change event triggers warehouse activation nobody planned for, since the meter runs whether or not the query was intentional.

Teams that forget to enable the flag on new tables will see ingestion failures rather than silent propagation, a different failure mode than BigQuery's always-on detection. The cost of that predictability is bookkeeping: the replication layer has to track flag state per table, and it has to handle the gap period on any table where the flag hasn't been set yet.

Databricks Delta Lake's schema evolution handling in streaming pipelines

Delta Lake covers more ground than any other platform in this comparison. Column additions, renames, reordering, drops, and type changes are all supported through a combination of explicit DDL and automatic schema evolution, which is the broadest surface area among the five warehouses examined here. Setting the mergeSchema option to true on a write lets new columns land automatically; leave it off, and a schema mismatch fails the write instead.

Databricks documentation describes how this plays out in an actual streaming pipeline, following a specific pattern. A Kafka topic carries Avro-encoded messages. The from_avro function is configured with avroSchemaEvolutionMode set to restart, and the query mode is set to FAILFAST, so the pipeline halts the instant it hits a corrupted or incompatible record. Schema definitions are pulled dynamically from the Confluent Schema Registry rather than hardcoded. And the Delta table on the receiving end supports automatic schema evolution, part of Databricks Delta Lake's support for column additions, renames, reorders, drops, and type changes. Databricks Jobs are then configured to auto-restart on failure, on the assumption that these failures are expected during schema changes and auto-restart allows the pipeline to resume without manual intervention.

FAILFAST is the design decision that matters most here. It turns a schema change into a visible, deliberate event instead of something that slips through silently. The pipeline stops, the new schema gets applied, and processing picks back up, which is close to the exact opposite of how BigQuery handles the same situation. Delta Lake also handles deeply nested data better than the other platforms compared here, which matters most for streaming workloads where the schema is evolving frequently and the data isn't flat to begin with.

Teams inheriting an existing Parquet-based data lake before standing up a CDC pipeline have a defined migration path: convert with PySpark's DeltaTable.convertToDelta(), or read the Parquet data into a DataFrame and write it out with format("delta"). The mergeSchema option applies once you're appending to an existing Delta table, not during the conversion step itself, so schema evolution is not active from day one just because the conversion happened. Unity Catalog sits above all of this, governing both Delta and Iceberg tables with lineage and audit trails, so a schema change event leaves a traceable record, which compliance-sensitive teams will care about a great deal.

Schema changes cause measurable, logged downtime rather than silent drift, which makes incident response easier but requires the pipeline operator to accept and plan for expected restarts.

How Redshift handles schema changes without native auto-evolution

Redshift doesn't try to guess what an upstream schema change means. There's no equivalent to BigQuery's load-time detection or Snowflake's opt-in evolution flag: a new column has to be added to the target table through an explicit ALTER TABLE before the pipeline can write to it at all. Drops work the same way in reverse. A column removed upstream just sits there, orphaned, until someone runs an explicit ALTER TABLE DROP COLUMN, and that operation isn't always straightforward given how Redshift's MPP architecture distributes data across nodes.

Most type conversions in Redshift require creating a new column, backfilling it with converted data, and dropping the old column, there's no in-place path for most type pairs. Nullability shifts demand a similarly multi-step DDL process.

What this adds up to, for a replication pipeline, is that every single upstream schema change becomes a manual operational event. Either the pipeline halts and waits for a person to run the DDL, or the ingestion layer has to be built to generate and execute that DDL on its own. There's no middle ground where Redshift quietly handles it for you. AWS's Zero-ETL connections to Aurora and DynamoDB reduce how often a pipeline needs to issue explicit DDL in certain patterns, but the underlying schema enforcement inside those integrations still follows the same Redshift rules.

On cost, Redshift Serverless starts at $1.50 an hour as of August 2026, the lowest entry point among the major warehouses covered here, which matters for teams trying to estimate what a CDC pipeline with variable throughput will cost them, especially around schema change events that spike compute demand unpredictably ovaledge.com. But cost and friction are separate variables. The manual model here is the least forgiving for teams facing high-frequency schema changes, and running Redshift as a CDC target means using either an ingestion tool that auto-generates DDL or a strict schema governance process on the source side that gates changes.

Engineers face a familiarity trade-off. Engineers who came up on-premises, with clusters, nodes, and capacity planning as part of daily vocabulary, find Redshift's traditional MPP model intuitive in a way the serverless platforms aren't, and the same design philosophy that makes it predictable for batch-heavy workloads is exactly what makes its schema evolution rigid. The rigidity isn't a bug bolted on; it's the same architecture that makes Redshift reliable for the workloads it was built for.

How ClickHouse handles schema changes for real-time analytics workloads

ClickHouse's design philosophy differs fundamentally from the other four platforms: it is optimized for high-throughput inserts and real-time analytical queries, not for the governed batch analytics model that shapes Snowflake, BigQuery, and Redshift's schema enforcement.

Adding a column is close to instant on most MergeTree table families. ALTER TABLE ADD COLUMN runs as a metadata operation, and existing rows get the new column's zero-value, an empty string or a zero depending on type, or a specified default, without any rewrite of existing data. Drops are supported too, but they behave differently underneath: ALTER TABLE DROP COLUMN removes the column from metadata immediately and deletes its files from disk, which for Wide parts is close to instant but for Compact parts can trigger a merge first. A pipeline has to account for that lag between the logical drop and the physical cleanup finishing.

Type changes are where ClickHouse gets strict. Narrowing conversions, or any type change that would force a rewrite of existing data, aren't supported in place, and the pipeline has to handle those explicitly rather than assuming ClickHouse will figure it out. Nullability works through an explicit Nullable wrapper specified at column creation time; converting a non-nullable column to nullable later takes an explicit ALTER TABLE MODIFY COLUMN, and while that's commonly a metadata-only operation on MergeTree tables, the exact behavior shifts depending on part format and ClickHouse version.

For a CDC pipeline, ClickHouse's fast, cheap handling of additive changes makes it a strong fit for upstream sources that frequently gain new columns, but type changes and nullability shifts still demand the same deliberate DDL handling that Redshift requires. It's positioned, across multiple sources, as the leading option for sub-second real-time analytics, and its schema behavior reflects exactly that priority: fast on anything additive, unforgiving on anything destructive or type-altering. There's also no schema registry or auto-detection layer built in anywhere in the platform, which means the ingestion tool owns schema change detection and DDL generation completely, with nothing native to lean on.

Apache Iceberg as a cross-platform schema evolution layer

By early 2026, every warehouse covered in this comparison reads and writes Apache Iceberg tables. That's a real shift in the competitive landscape: the table format itself has stopped being a point of differentiation, because everyone supports it, which means the real competition has moved up a layer, into the catalog that manages those tables.

Iceberg's specific contribution to schema evolution is that it tracks column identity by an internal ID rather than by name. That single design choice turns renames into metadata operations instead of full data rewrites, since the catalog just updates which name points to which ID. Column additions and drops follow Iceberg's own evolution rules, and whatever warehouse is reading the table simply honors those rules rather than enforcing its own separate logic on top. Type promotions, the widening kind, are supported the same way they are natively in BigQuery and Snowflake; type changes that aren't promotions still aren't.

The catalog is where the actual competition now sits. Databricks Unity Catalog offers an Iceberg REST Catalog API alongside Delta UniForm, giving it native interoperability with Iceberg tables, and it governs both data and AI models under one system, built in part on the 2024 acquisition of Tabular, the company founded by Iceberg's original creators. Snowflake's own Iceberg integration delivers the same rename-as-metadata-operation benefit, which is a meaningful change for any pipeline that used to have to run a full column rewrite every time a rename happened upstream.

None of this erases the operational questions a CDC pipeline still has to answer. Writing CDC events into Iceberg tables forces a choice between merge-on-read and copy-on-write, and that choice has real consequences during schema changes, since a merge triggered mid-schema-change carries a different cost profile under each strategy. High-frequency streaming CDC into Iceberg also tends to generate a lot of small files, a well-known problem that needs separate compaction configuration, and that compaction interacts with schema evolution operations whenever those operations trigger new file writes of their own. Iceberg lowers the cost of renames and reorders that used to be expensive, but it doesn't remove the ingestion layer's job: something still has to detect the change, translate it into an Iceberg schema update, and manage the catalog transaction that makes it official. What Iceberg changes for schema evolution specifically:.

Each warehouse's handling of the four change types a replication pipeline will face

Column additions sort out cleanly by how much friction they cause. BigQuery is at the bottom of the friction scale: always-on auto-detection, no DDL required, at the cost of doing all of it silently. Snowflake sits just above it when ENABLE_SCHEMA_EVOLUTION is turned on for the table in question, low friction in that case, but high friction the moment the flag was never set and the pipeline hits a load error it wasn't expecting. Databricks handles additions automatically too, through mergeSchema, and backs that up with the broadest support for renames, reorders, and drops of any platform here. ClickHouse adds columns about as fast as any of them, near-instant on MergeTree tables, as a metadata operation with no rewrite. Redshift is the outlier: every addition needs an explicit ALTER TABLE before the pipeline can write to it, full stop.

Drops tell a more uniform story. None of the five platforms auto-propagates a drop, and that consistency across otherwise very different architectures says something about how seriously destructive schema operations are treated industry-wide. BigQuery leaves an orphaned column and lets the ingestion tool decide what to do with it. Snowflake leaves the column in place, filling with NULLs, until someone issues the DDL. Redshift requires an explicit DROP COLUMN, complicated further by its MPP layout. ClickHouse will drop a column fast at the metadata level, but the physical cleanup on disk can lag behind that logical drop. Databricks supports drops as part of its broader schema evolution surface, same as additions.

Type changes are where every platform draws a hard line. Nobody here auto-converts an incompatible type: BigQuery accepts widening but rejects narrowing, Snowflake demands explicit DDL for anything incompatible, Redshift makes you build a new column and backfill it by hand, and ClickHouse refuses any type change that would force a rewrite. Nullability shifts follow the same pattern of universal manual handling, varying mostly in mechanism, whether that's a load-time schema modification, an explicit ALTER TABLE, or a MODIFY COLUMN statement, rather than in whether human intervention is required at all.

The pattern across all four change types is consistent enough to draw a real conclusion from: additive changes get progressively more automated the newer and more cloud-native the platform's architecture, while destructive and type-altering changes stay manual almost everywhere, because letting a warehouse guess how to handle data loss or type incompatibility on its own is a bet none of these vendors are willing to make on a customer's behalf. SOURCE PAGES (what the pages behind the outline's links say).

Filed underData Warehouses

More in Data Warehouses