Snowflake Zero-Copy Cloning: How It Works and Why Your Dev Team Needs It
Last updated: March 2025
Quick answer: Zero-copy cloning creates a metadata-only snapshot of a Snowflake table, schema, or database. The clone shares the original's underlying micro-partitions until you write to it. That means you get a full copy of production data in seconds, at zero additional storage cost, until modifications diverge the two copies.
What Zero-Copy Cloning Actually Does
Snowflake stores table data in immutable micro-partitions - compressed columnar files ranging from 50–500 MB each. When you clone a table, Snowflake doesn't duplicate those files. It creates a new metadata entry that points to the same set of micro-partitions. The original and the clone share storage until one of them changes.
Think of it like a hard link in a filesystem, but at the partition level. The moment you INSERT, UPDATE, or DELETE rows in the clone, Snowflake writes new micro-partitions for the affected data. The unchanged partitions? Still shared. You only pay for what diverges.
This is fundamentally different from a CREATE TABLE AS SELECT (CTAS), which scans every row and writes entirely new micro-partitions. A CTAS on a 2 TB table takes minutes to hours and immediately doubles your storage. A clone of that same table finishes in under 10 seconds and costs nothing until you modify it.
How to Clone: Tables, Schemas, and Databases
The syntax is straightforward. You can clone at three levels:
Cloning a Table
CREATE TABLE analytics.orders_dev CLONE production.orders;
This creates analytics.orders_dev as a metadata pointer to the same micro-partitions as production.orders. Columns, constraints, clustering keys, and comments all come along.
Cloning a Schema
CREATE SCHEMA dev_db.sales_dev CLONE prod_db.sales;
Every table, view, sequence, file format, and stored procedure inside prod_db.sales gets cloned into dev_db.sales_dev. Views reference the cloned tables, not the originals.
Cloning a Database
CREATE DATABASE staging_clone CLONE production_db;
This recursively clones every schema and every object inside them. A 500-table database clones in seconds.
Use Cases That Actually Matter
Dev/Test Environments from Production Data
The most common use case. Instead of maintaining a separate ETL pipeline to populate dev databases with sample data, clone production every morning. Developers get realistic data volumes, realistic distributions, and realistic edge cases - without touching production or paying for doubled storage.
Safe Experimentation Before Migrations
Planning a schema migration? Clone the target tables first. Run your ALTER TABLE statements, test your downstream queries, and verify everything works. If something breaks, drop the clone and start over. Zero risk to production.
Point-in-Time Snapshots for Auditing
Compliance requirements often demand that you preserve data as it existed at a specific point. Clone the relevant tables at end-of-quarter, tag them with a date, and leave them untouched. Since nobody writes to audit snapshots, they stay free - sharing storage with the original indefinitely.
CI/CD Integration Testing
This is where cloning really shines for engineering teams. You can build a pipeline that clones your production schema before every test run, executes integration tests against real data, and drops the clone when tests finish. Here's a practical example:
-- Step 1: Create a fresh clone for this test run CREATE OR REPLACE DATABASE ci_test_db CLONE production_db; -- Step 2: Run your dbt models or stored procedures against the clone USE DATABASE ci_test_db; CALL run_etl_pipeline(); -- Step 3: Validate results SELECT COUNT(*) FROM ci_test_db.analytics.daily_revenue WHERE report_date = CURRENT_DATE(); -- Step 4: Tear down after tests pass DROP DATABASE ci_test_db;
The whole cycle - clone, test, drop - typically runs in under a minute for databases with hundreds of tables. Compare that to restoring a backup or running a full CTAS refresh. Your CI pipeline becomes fast enough to run on every pull request.
Storage Implications: When Does It Stop Being Free?
The clone costs zero additional storage at creation time. But the moment you modify data in either the original or the clone, the shared micro-partitions start diverging. Here's how it works:
- INSERT into the clone: New micro-partitions are created and owned exclusively by the clone. The original's storage doesn't change.
- UPDATE or DELETE in the clone: Snowflake writes new micro-partitions for the affected rows. The old partitions remain shared (they're immutable), but the new ones belong to the clone.
- UPDATE or DELETE in the original: Same mechanics. New partitions are written for the original. The clone still points to the old (now unshared) partitions.
The practical implication: if you clone a 1 TB table and then update 5% of the rows in the clone, you'll pay for roughly 50 GB of new storage (the changed micro-partitions), not the full 1 TB. If you never modify the clone, you pay nothing extra.
Use TABLE_STORAGE_METRICS to track how much storage each clone actually consumes:
SELECT table_name,
active_bytes / (1024*1024*1024) AS active_gb,
retained_for_clone_bytes / (1024*1024*1024) AS clone_retained_gb
FROM snowflake.account_usage.table_storage_metrics
WHERE table_catalog = 'PRODUCTION_DB'
ORDER BY active_bytes DESC;
Cloning with Time Travel
You can combine cloning with Snowflake Time Travel to clone a table as it existed at a past point. This is incredibly useful for recovering from accidental changes.
-- Clone the table as it was 2 hours ago CREATE TABLE orders_recovered CLONE production.orders AT(OFFSET => -7200); -- Clone from a specific timestamp CREATE TABLE orders_snapshot CLONE production.orders AT(TIMESTAMP => '2026-02-26 14:00:00'::TIMESTAMP_LTZ); -- Clone from just before a specific query executed CREATE TABLE orders_pre_update CLONE production.orders BEFORE(STATEMENT => '01b2c3d4-0000-0000-0000-000000000000');
The Time Travel clone window depends on your table's DATA_RETENTION_TIME_IN_DAYS setting. Standard Edition supports up to 1 day; Enterprise Edition supports up to 90 days.
Limitations You Should Know About
Cloning isn't a universal copy mechanism. Several object types can't be cloned:
- External tables - they reference files in external storage, so there's no Snowflake micro-partition to share.
- Internal and external stages - stages are storage references, not data objects.
- Pipes - Snowpipe configurations are tied to specific stages and notification channels.
When you clone a database or schema that contains these objects, Snowflake skips them silently. It won't throw an error - it just won't include them in the clone. This can surprise you if your pipeline depends on pipes or stages existing in the cloned environment.
Security: How Grants Work After Cloning
Cloned tables inherit the grants that existed at clone time. If DATA_ANALYST role had SELECT on the original table, it'll have SELECT on the clone too. But from that point forward, grants on the original and the clone are independent.
Granting new privileges on the original after cloning won't affect the clone. And revoking privileges from the clone won't touch the original. This is important for role-based access control planning - if you clone production into a dev environment, developers will have whatever access was configured at clone time unless you explicitly modify it afterward.
For tighter control, consider using managed access schemas. In a managed access schema, only the schema owner (not individual table owners) can grant privileges. This gives you a single point of control after cloning.
Key Takeaways
- Zero-copy cloning is a metadata-only operation - it creates pointers to existing micro-partitions, not copies of data.
- Clones are free until you modify them. Only changed micro-partitions incur additional storage costs.
- You can clone tables, schemas, and entire databases. External tables, stages, and pipes are excluded.
- Combine cloning with Time Travel to recover from accidental changes or create point-in-time snapshots.
- Grants are inherited at clone time but diverge immediately - plan your access control accordingly.
- For CI/CD, cloning lets you spin up a production-realistic test environment in seconds and tear it down when tests finish.
Frequently Asked Questions
Q: Does a Snowflake zero-copy clone use additional storage?
Not initially. The clone shares the original table's micro-partitions through metadata pointers. Storage costs only increase when you modify data in the clone, since Snowflake writes new micro-partitions for those changes.
Q: Can you clone an entire Snowflake database?
Yes. CREATE DATABASE ... CLONE clones the database, all its schemas, and all tables within them. Each cloned object shares the original's micro-partitions until modified.
Q: Can you clone a Snowflake table from a past point in time?
Yes. You can combine cloning with Time Travel by using CREATE TABLE ... CLONE ... AT(TIMESTAMP => ...) to clone a table as it existed at a specific timestamp, within your Time Travel retention window.
Q: What can't you clone in Snowflake?
You cannot clone external tables, internal or external stages, or pipes. Cloning is limited to databases, schemas, tables (permanent, transient, temporary), streams, sequences, file formats, tasks, and stored procedures.
