Alter column data type in Amazon Redshift
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Amazon Redshift does not support directly altering a column's data type with ALTER TABLE ... ALTER COLUMN ... TYPE. Instead, you perform a four-step workaround: add a new column, copy data with a cast, drop the old column, and rename the new one. This limitation exists because Redshift stores data in compressed, columnar format, and in-place type changes would require rewriting every block on disk.
Why Redshift Cannot Alter Column Types Directly
Traditional row-oriented databases like PostgreSQL can rewrite individual rows during an ALTER COLUMN TYPE operation. Redshift is a columnar, MPP (massively parallel processing) warehouse. Each column is stored independently, sorted and compressed per its encoding. Changing a column's type would mean decompressing, casting, re-encoding, and redistributing the entire column across all slices. Rather than hiding that cost behind a single DDL statement, Redshift forces you to perform the migration explicitly so you control the timing and transaction boundaries.
The Four-Step Column Type Migration
Here is the standard pattern wrapped in a transaction to ensure atomicity.
Wrapping in BEGIN / COMMIT ensures that if any step fails, the table reverts to its original state.
Handling Columns with Constraints and Dependencies
Real production tables rarely have bare columns. Foreign keys, NOT NULL constraints, default values, sort keys, and distribution keys all need attention during migration.
Columns Referenced by Foreign Keys
Drop the foreign key on the referencing table before you drop the original column, then recreate it afterward.
Columns That Are Sort Keys or Distribution Keys
Redshift does not allow you to drop a column that is the distribution key or part of the sort key. For these columns, you must use the deep-copy approach: create a new table with the desired schema, insert data, drop the old table, and rename.
Comparison of Migration Approaches
| Approach | When to use | Keeps sort/dist keys | Downtime |
| Four-step add/copy/drop/rename | Simple columns with no key dependencies | No (column moves to last position) | Low for small tables |
| Deep copy (create new table) | Columns that are dist/sort keys or when you need to re-encode | Yes (you define them on the new table) | Higher, proportional to table size |
| CTAS (CREATE TABLE AS SELECT) | Large tables where INSERT INTO is slow | Yes | Moderate, single scan |
| Unload/reload via S3 | Very large tables (billions of rows) | Yes | Highest, but avoids cluster pressure |
Preserving Column Order
The four-step approach appends the new column at the end of the table. If column order matters (for example, SELECT * in downstream pipelines), you can use CTAS to reorder.
Validating the Migration
Always verify that the data migrated correctly before dropping the original column or table.
Common Type Conversions and Their Gotchas
| Source type | Target type | Cast syntax | Risk |
| INTEGER | BIGINT | col::BIGINT | None, lossless widening |
| VARCHAR(50) | VARCHAR(256) | ALTER TABLE t ALTER COLUMN c TYPE VARCHAR(256) | Redshift allows this directly since 2023 |
| FLOAT | DECIMAL(18,4) | col::DECIMAL(18,4) | Precision loss on values beyond 4 decimal places |
| TIMESTAMP | DATE | col::DATE | Time component is silently dropped |
| VARCHAR | INTEGER | col::INTEGER | Fails on non-numeric strings; filter first |
| CHAR(10) | VARCHAR(10) | col::VARCHAR(10) | Trailing spaces from CHAR are preserved |
Note that Redshift now supports ALTER TABLE ... ALTER COLUMN ... TYPE VARCHAR(n) when you are only increasing the length of a VARCHAR column. This is the one case where you do not need the four-step workaround.
Common Pitfalls
Forgetting the transaction wrapper. Without BEGIN/COMMIT, a failure at step 3 leaves you with two columns and no rollback path. Always wrap the migration in a transaction.
Running the migration during peak query hours. The UPDATE statement acquires a table-level write lock. On a table with hundreds of millions of rows, this can block reads for minutes. Schedule migrations during maintenance windows or low-traffic periods.
Ignoring views and materialized views. Views that reference the dropped column will break silently. Query pg_views and stv_mv_info to find all dependent objects before starting.
Assuming column order is preserved. The new column is appended at the end of the table. Any downstream code relying on ordinal column positions (such as COPY without a column list) will break.
Skipping validation. Cast operations can introduce NULLs or truncated values. A VARCHAR-to-INTEGER cast on a column with non-numeric strings will fail the entire UPDATE. Filter or clean the data first.
Summary
Altering a column's data type in Amazon Redshift requires a manual migration because the columnar storage engine does not support in-place type changes (with the exception of VARCHAR length increases). The standard approach is add, copy, drop, rename, wrapped in a transaction. For columns involved in sort or distribution keys, use a deep-copy strategy with a new table. Always validate data integrity after migration, account for dependent objects like foreign keys and views, and schedule the operation during low-traffic windows to minimize locking impact.
Related reading
- Alter MySQL table to add comments on columns
- ALTER TABLE to add a composite primary key
- Altering a column from null to not null
- Alternatives to Red Gate SQL Comparison SDK?
- Amazon - DynamoDB Strong consistent reads, Are they latest and how?
- Amazon Athena no viable alternative at input
- Amazon AWS DynamoDB Desktop Client - Does one exist?
- Amazon DynamoDB Attribute Type with CloudFormation

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.