Home Database Time Travel & Zero-Copy Cloning: Data Restoration Guide
Intermediate 6 min · July 17, 2026

Time Travel & Zero-Copy Cloning: Data Restoration Guide

Master Snowflake Time Travel and Zero-Copy Cloning for data restoration, debugging, and instant cloning.

N
Naren Founder & Principal Engineer

20+ years shipping high-throughput database systems. Written from production experience, not tutorials.

Follow
Production
production tested
July 17, 2026
last updated
2,439
articles · all by Naren
Before you start⏱ 15-20 min read
  • Basic understanding of SQL (SELECT, CREATE, ALTER, DROP).
  • A Snowflake account with access to a warehouse and appropriate privileges.
  • Familiarity with Snowflake's basic concepts (databases, schemas, tables).
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer
  • Time Travel allows querying and restoring historical data up to 90 days.
  • Zero-Copy Cloning creates instant, storage-efficient copies of tables/schemas/databases.
  • Use AT/OFFSET/BEFORE keywords to query past states.
  • Cloning does not duplicate underlying data until changes are made.
  • Both features are crucial for data recovery, testing, and auditing.
✦ Definition~90s read
What is Time Travel, Zero-Copy Cloning, and Data Restoration?

Snowflake Time Travel and Zero-Copy Cloning are features that let you access historical data and create instant, storage-efficient copies of your data for recovery, testing, and auditing.

Imagine you have a notebook where you write your data.
Plain-English First

Imagine you have a notebook where you write your data. Snowflake's Time Travel is like having a magical undo button that lets you flip back to any page from the last 90 days, even if you've written over it. Zero-Copy Cloning is like making a photocopy of a page that doesn't use extra paper until you write on the copy. This way, you can experiment without wasting storage.

In the fast-paced world of data engineering, mistakes happen. A developer might accidentally drop a table, a faulty ETL job might corrupt data, or a user might update rows without a WHERE clause. Traditional databases often require restoring from backups, which can take hours and involve significant downtime. Snowflake, a cloud-native data warehouse, offers two powerful features to handle such scenarios: Time Travel and Zero-Copy Cloning.

Time Travel enables you to access and restore historical data at any point within a defined retention period (1 to 90 days, depending on your Snowflake edition). This means you can query data as it existed minutes, hours, or days ago, or even clone a table from a specific point in time. Zero-Copy Cloning, on the other hand, allows you to create an instant copy of a database, schema, or table without duplicating the underlying data. The clone shares the same storage until modifications are made, making it incredibly storage-efficient.

Together, these features provide a safety net for data recovery, enable rapid development and testing with production data, and simplify auditing and compliance. In this tutorial, you'll learn how to leverage Time Travel and Zero-Copy Cloning in Snowflake with practical SQL examples, understand their limitations, and see how they can save the day in a real-world production incident. By the end, you'll be equipped to implement these features in your own Snowflake environment.

Understanding Time Travel

Time Travel is a Snowflake feature that allows you to access historical data within a defined retention period. The retention period depends on your Snowflake edition: Standard (1 day), Enterprise (up to 90 days), and Business Critical (up to 90 days). You can query data as it existed at a specific timestamp, offset, or before a statement.

To use Time Travel, you use the AT or BEFORE clause in your SQL queries. The syntax is:

SELECT ... FROM <table> AT (TIMESTAMP => '<timestamp>'::TIMESTAMP) SELECT ... FROM <table> AT (OFFSET => -<seconds>) SELECT ... FROM <table> BEFORE (STATEMENT => '<query_id>')

SELECT FROM orders AT (OFFSET => -6030);

CREATE OR REPLACE TABLE orders_restored CLONE orders AT (OFFSET => -60*30);

This creates a new table that contains the data as it was 30 minutes ago. The clone is a full, independent table that you can modify without affecting the original.

Time Travel is also used for undropping objects. If you accidentally drop a table, you can restore it with:

UNDROP TABLE orders;

This command recovers the table from the Time Travel retention period. However, if the table was dropped and then another table with the same name was created, you may need to rename the existing table first.

time_travel_examples.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- Query table as of 1 hour ago
SELECT * FROM orders AT (OFFSET => -3600);

-- Query table before a specific statement (query ID)
SELECT * FROM orders BEFORE (STATEMENT => '0192a3b4-5c6d-7e8f-9a0b-1c2d3e4f5g6h');

-- Clone table from 30 minutes ago
CREATE OR REPLACE TABLE orders_restored CLONE orders AT (OFFSET => -1800);

-- Undrop a table
UNDROP TABLE orders;

-- Show Time Travel retention for a table
SHOW TABLES LIKE 'orders';
Output
-- (No output for queries; SHOW TABLES returns metadata including retention_time)
🔥Time Travel Retention Limits
📊 Production Insight
Always set a reasonable Time Travel retention for critical tables. For example, ALTER TABLE orders SET DATA_RETENTION_TIME_IN_DAYS = 30; This ensures you have a longer window to recover from mistakes.
🎯 Key Takeaway
Time Travel lets you query and restore data as it existed at any point within the retention period using AT, BEFORE, or UNDROP.

Zero-Copy Cloning: Instant Copies Without Storage Overhead

Zero-Copy Cloning is a Snowflake feature that creates an instant copy of a database, schema, or table. The clone shares the same underlying storage as the original until modifications are made. This means you can create clones almost instantly and without incurring additional storage costs until you start changing data.

Cloning is incredibly useful for
  • Creating development or test environments that mirror production.
  • Taking a snapshot of data before running risky operations.
  • Performing data analysis on a point-in-time copy without affecting production.
  • Auditing and compliance by preserving data states.

CREATE DATABASE dev_db CLONE prod_db; CREATE SCHEMA dev_schema CLONE prod_schema; CREATE TABLE dev_table CLONE prod_table;

CREATE TABLE orders_backup CLONE orders AT (OFFSET => -3600);

This combines both features: you get an instant copy of the table as it was one hour ago.

Important considerations
  • Clones are writable. You can insert, update, or delete data in the clone without affecting the original.
  • When you modify data in either the clone or the original, Snowflake allocates new storage for the changed data. The unchanged data remains shared.
  • Cloning a database clones all its schemas and tables. Cloning a schema clones all its tables.
  • You can clone across accounts using shares, but that's beyond this tutorial.
zero_copy_cloning.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- Clone entire database
CREATE DATABASE prod_clone CLONE prod_db;

-- Clone a schema
CREATE SCHEMA analytics_clone CLONE analytics;

-- Clone a table
CREATE TABLE orders_clone CLONE orders;

-- Clone from a specific time
CREATE TABLE orders_snapshot CLONE orders AT (TIMESTAMP => '2025-03-15 10:00:00'::TIMESTAMP);

-- Verify storage savings (query INFORMATION_SCHEMA)
SELECT table_name, bytes / 1024/1024/1024 AS gb
FROM information_schema.tables
WHERE table_name IN ('ORDERS', 'ORDERS_CLONE');
Output
TABLE_NAME | GB
ORDERS | 2.5
ORDERS_CLONE | 0.0 (until modifications)
💡Cloning for Safe Deployments
📊 Production Insight
Cloning a large table is instantaneous, but subsequent DML on the clone will incur storage costs for the changed data. Monitor storage usage to avoid surprises.
🎯 Key Takeaway
Zero-Copy Cloning creates instant, storage-efficient copies that share data until changes are made. It's ideal for testing, snapshots, and safe deployments.

Restoring Data with Time Travel and Cloning

When data is accidentally deleted or corrupted, you can combine Time Travel and Zero-Copy Cloning to restore it. The typical workflow is:

  1. Identify the point in time before the incident.
  2. Query the table at that point to verify the data is correct.
  3. Create a clone of the table at that point.
  4. Replace the current table with the clone.

For example, suppose a DELETE statement removed all rows from the 'orders' table 15 minutes ago. To restore:

-- Step 1: Verify data exists at a point before the delete SELECT COUNT() FROM orders AT (OFFSET => -6015);

-- Step 2: Create a clone from that point CREATE OR REPLACE TABLE orders_restore CLONE orders AT (OFFSET => -60*15);

-- Step 3: Swap tables (or rename) ALTER TABLE orders RENAME TO orders_bad; ALTER TABLE orders_restore RENAME TO orders;

-- Optionally, drop the bad table DROP TABLE orders_bad;

UNDROP TABLE orders;

If the table was dropped and a new table with the same name was created, you need to drop or rename the new table first, then UNDROP the old one.

For more complex scenarios, like restoring specific rows, you can use a MERGE statement:

MERGE INTO orders AS target USING (SELECT FROM orders AT (OFFSET => -6015)) AS source ON target.order_id = source.order_id WHEN MATCHED THEN UPDATE SET ... WHEN NOT MATCHED THEN INSERT ...;

This allows you to selectively restore missing or corrupted rows.

restore_scenario.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- Scenario: orders table has been corrupted by a bad update
-- Step 1: Check current state
SELECT COUNT(*) FROM orders;

-- Step 2: Check historical state (10 minutes ago)
SELECT COUNT(*) FROM orders AT (OFFSET => -600);

-- Step 3: Create a clone of the good state
CREATE TABLE orders_good CLONE orders AT (OFFSET => -600);

-- Step 4: Replace the corrupted table
ALTER TABLE orders RENAME TO orders_corrupt;
ALTER TABLE orders_good RENAME TO orders;

-- Step 5: Clean up
DROP TABLE orders_corrupt;
Output
-- COUNT(*) returns 0 for current, 100000 for historical
-- Cloning and renaming complete.
⚠ Time Travel and Cloning Costs
📊 Production Insight
For large tables, consider using a temporary clone and then performing a selective merge to minimize downtime. For example, if only a few rows are affected, use MERGE instead of full table swap.
🎯 Key Takeaway
Restoring data involves identifying the correct point in time, cloning from that point, and swapping tables. Always verify the historical data before restoring.

Time Travel and Cloning for Auditing and Compliance

Time Travel and Zero-Copy Cloning are powerful tools for auditing and compliance. You can use them to: - Track changes over time by querying historical states. - Create periodic snapshots of data for regulatory retention. - Investigate who changed what and when (using QUERY_HISTORY).

For example, to see the state of a table at the end of each month, you can create a clone:

CREATE TABLE orders_end_of_month CLONE orders AT (TIMESTAMP => '2025-01-31 23:59:59'::TIMESTAMP);

You can also use Time Travel to compare current data with a previous state to identify changes:

SELECT FROM orders MINUS SELECT FROM orders AT (OFFSET => -86400);

This returns rows that are new or changed in the last day.

For compliance, you might need to retain data for a specific period. Snowflake's Time Travel retention can be set to up to 90 days. For longer retention, you can export data to external storage or use Snowflake's Fail-safe (7 days, not queryable).

Additionally, you can use the QUERY_HISTORY view to see which queries modified data. For example:

SELECT query_id, query_text, start_time, user_name FROM snowflake.account_usage.query_history WHERE query_text ILIKE '%DELETE FROM orders%' ORDER BY start_time DESC;

This helps identify the exact query that caused data loss.

auditing_examples.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- Compare current data with yesterday's data
SELECT * FROM orders
MINUS
SELECT * FROM orders AT (OFFSET => -86400);

-- Find queries that deleted from orders
SELECT query_id, query_text, start_time, user_name
FROM snowflake.account_usage.query_history
WHERE query_text ILIKE '%DELETE FROM orders%'
  AND start_time >= CURRENT_TIMESTAMP - INTERVAL '7 days'
ORDER BY start_time DESC;

-- Create a monthly snapshot
CREATE TABLE orders_2025_01 CLONE orders AT (TIMESTAMP => '2025-01-31 23:59:59'::TIMESTAMP);
Output
-- MINUS query returns rows that are new/changed.
-- QUERY_HISTORY returns a list of DELETE queries.
-- Snapshot created.
🔥Audit Log Retention
📊 Production Insight
Automate snapshot creation using Snowflake tasks or external schedulers. For example, create a task that runs daily to clone critical tables for compliance.
🎯 Key Takeaway
Time Travel and cloning enable point-in-time snapshots and change tracking, essential for auditing and compliance.

Best Practices and Limitations

While Time Travel and Zero-Copy Cloning are powerful, they have limitations and best practices you should follow.

Limitations: - Time Travel retention is limited to 90 days maximum (Enterprise edition). Data beyond that is not recoverable via Time Travel. - Time Travel does not work on external tables (data stored outside Snowflake). - Cloning a table that has a large number of micro-partitions may take slightly longer, but still much faster than a full copy. - You cannot clone a table across regions or accounts without using data sharing. - Time Travel queries consume compute credits; they are not free.

Best Practices: 1. Set appropriate data retention for each table based on business needs. Use ALTER TABLE ... SET DATA_RETENTION_TIME_IN_DAYS = N. 2. Use Zero-Copy Cloning for development and testing instead of copying data manually. 3. Before running destructive operations (DELETE, DROP, UPDATE without WHERE), create a clone as a backup. 4. Monitor Time Travel storage usage. Time Travel data is stored and billed separately. 5. Use the UNDROP command as a first resort for dropped objects. 6. Document your recovery procedures and test them regularly. 7. Use roles and permissions to restrict who can drop or truncate tables.

Cost Considerations: - Time Travel storage: The historical data is stored as separate micro-partitions. The cost is proportional to the amount of change over time. - Cloning: No additional storage until changes are made. However, querying clones consumes compute. - Use the ACCOUNT_USAGE views to track storage and compute costs.

best_practices.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- Set retention for critical table
ALTER TABLE orders SET DATA_RETENTION_TIME_IN_DAYS = 30;

-- Create a backup clone before risky operation
CREATE TABLE orders_before_update CLONE orders;

-- Perform risky operation
UPDATE orders SET status = 'archived' WHERE date < '2020-01-01';

-- If something goes wrong, restore from clone
-- (swap tables or merge)

-- Monitor Time Travel storage
SELECT * FROM snowflake.account_usage.table_storage_metrics
WHERE table_name = 'ORDERS';
Output
-- Retention set.
-- Clone created.
-- Update executed.
-- Storage metrics show time_travel_bytes.
⚠ Time Travel Storage Costs
📊 Production Insight
For very large tables, consider using a separate 'history' table to track changes instead of relying solely on Time Travel, as Time Travel storage costs can be high.
🎯 Key Takeaway
Understand the limitations and costs of Time Travel and cloning. Set retention wisely, use clones for backups, and monitor storage.

Advanced Use Cases: Time Travel with Streams and Tasks

Snowflake Streams capture change data capture (CDC) on tables. Combined with Time Travel, you can reprocess changes from a specific point in time. For example, if a stream missed some changes due to a bug, you can recreate the stream from a historical point.

However, streams are typically append-only and track changes after creation. To reprocess historical changes, you can use a combination of Time Travel and a temporary table.

Another advanced use case is using Time Travel with Snowflake Tasks to automate data recovery. For example, you can create a task that runs every hour to check for data anomalies and restore from a known good state if needed.

Example: Create a task that clones a table every day at midnight for backup:

CREATE TASK daily_backup WAREHOUSE = my_wh SCHEDULE = '1440 minute' AS CREATE OR REPLACE TABLE orders_backup CLONE orders;

This creates a daily snapshot. You can then use Time Travel to go back to any of these snapshots.

You can also use Time Travel to implement a 'soft delete' pattern. Instead of physically deleting rows, you can mark them as deleted and use Time Travel to query the original state if needed.

Finally, Time Travel can be used for debugging ETL pipelines. If a pipeline produces unexpected results, you can query the source tables at the time the pipeline ran to see what data was processed.

advanced_use_cases.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- Create a daily backup task
CREATE TASK daily_backup
  WAREHOUSE = my_wh
  SCHEDULE = '1440 minute'
AS
  CREATE OR REPLACE TABLE orders_backup CLONE orders;

-- Start the task
ALTER TASK daily_backup RESUME;

-- Use Time Travel to debug ETL: compare source at pipeline time
SELECT * FROM source_table AT (TIMESTAMP => '2025-03-20 02:00:00'::TIMESTAMP)
MINUS
SELECT * FROM target_table;

-- Soft delete pattern: instead of DELETE, set a flag
UPDATE orders SET is_deleted = TRUE WHERE order_id = 123;
-- To see original data, query before the update
SELECT * FROM orders AT (OFFSET => -60) WHERE order_id = 123;
Output
-- Task created and resumed.
-- Debug query returns differences.
-- Soft delete applied.
💡Automate Backups with Tasks
📊 Production Insight
When using tasks for backups, ensure the warehouse is appropriately sized. A small warehouse may cause the task to run longer than the schedule interval.
🎯 Key Takeaway
Combine Time Travel with Streams, Tasks, and soft deletes to build robust data pipelines and recovery mechanisms.
● Production incidentPOST-MORTEMseverity: high

The Accidental Drop That Cost $50k in Compute

Symptom
Users reported missing data in the 'orders' table. Queries returned empty results for recent months.
Assumption
The developer assumed the table was accidentally truncated, but a quick check showed the table still existed with zero rows.
Root cause
A developer ran 'DELETE FROM orders' without a WHERE clause, thinking they were in a test environment. The table was not dropped, but all rows were deleted.
Fix
Used Time Travel to query the table as it was 5 minutes before the delete: SELECT FROM orders AT (OFFSET => -605). Then created a clone of the table at that timestamp and swapped it with the current table.
Key lesson
  • Always use transactions with explicit COMMIT/ROLLBACK for destructive operations.
  • Set up Time Travel retention to at least 1 day for critical tables.
  • Use Zero-Copy Cloning to create a backup clone before running risky operations.
  • Implement role-based access control to prevent accidental deletes in production.
  • Monitor and alert on large-scale DELETE/UPDATE operations.
Production debug guideSymptom to Action4 entries
Symptom · 01
Table exists but rows are missing (accidental DELETE).
Fix
Query the table using AT(OFFSET => -60*N) where N is minutes before the incident. If data is there, clone the table at that timestamp and swap.
Symptom · 02
Table is dropped entirely.
Fix
Use UNDROP TABLE <name> to restore the table from the Time Travel retention period. If beyond retention, restore from backup.
Symptom · 03
Data corruption due to bad ETL.
Fix
Identify the timestamp of the last good state. Clone the table at that timestamp and compare with current data. Use MERGE to reconcile.
Symptom · 04
Need to test a new transformation on production data without risk.
Fix
Create a Zero-Copy Clone of the schema or database. Run tests on the clone. When done, drop the clone.
★ Quick Debug Cheat SheetImmediate actions for common data loss scenarios.
Rows deleted accidentally
Immediate action
Query historical data with AT(OFFSET => ...)
Commands
SELECT * FROM table AT(OFFSET => -60*5) LIMIT 10;
CREATE OR REPLACE TABLE table_backup CLONE table AT(OFFSET => -60*5);
Fix now
Swap table: ALTER TABLE table RENAME TO table_corrupt; ALTER TABLE table_backup RENAME TO table;
Table dropped accidentally+
Immediate action
UNDROP the table
Commands
UNDROP TABLE table;
SHOW TABLES HISTORY LIKE 'table';
Fix now
If UNDROP fails, restore from backup.
Need a copy of production for testing+
Immediate action
Create a Zero-Copy Clone
Commands
CREATE DATABASE test_db CLONE prod_db;
CREATE SCHEMA test_schema CLONE prod_schema;
Fix now
Use the clone for testing; drop when done.
FeatureTime TravelZero-Copy Cloning
PurposeAccess historical dataCreate instant copies
StorageStores historical versionsShares storage until modified
CostCompute for queries + storage for historyNo initial storage cost; compute for queries
Retention1-90 days (edition dependent)No retention; clone exists until dropped
Use CaseData recovery, auditingTesting, development, snapshots
SyntaxAT, BEFORE, UNDROPCLONE keyword
⚙ Quick Reference
6 commands from this guide
FileCommand / CodePurpose
time_travel_examples.sqlSELECT * FROM orders AT (OFFSET => -3600);Understanding Time Travel
zero_copy_cloning.sqlCREATE DATABASE prod_clone CLONE prod_db;Zero-Copy Cloning
restore_scenario.sqlSELECT COUNT(*) FROM orders;Restoring Data with Time Travel and Cloning
auditing_examples.sqlSELECT * FROM ordersTime Travel and Cloning for Auditing and Compliance
best_practices.sqlALTER TABLE orders SET DATA_RETENTION_TIME_IN_DAYS = 30;Best Practices and Limitations
advanced_use_cases.sqlCREATE TASK daily_backupAdvanced Use Cases

Key takeaways

1
Snowflake Time Travel allows querying and restoring data from any point within the retention period using AT, BEFORE, or UNDROP.
2
Zero-Copy Cloning creates instant, storage-efficient copies that share data until modifications are made.
3
Combining Time Travel and cloning provides a powerful data recovery mechanism for accidental deletes, corruption, or testing.
4
Always set appropriate retention periods for critical tables and use clones as backups before risky operations.
5
Monitor costs associated with Time Travel storage and compute to avoid unexpected bills.

Common mistakes to avoid

5 patterns
×

Assuming Time Travel works for external tables.

×

Forgetting to set a custom retention period for critical tables.

×

Thinking clones are read-only.

×

Using Time Travel without considering costs.

×

Attempting to undrop a table when a table with the same name exists.

INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What is Snowflake Time Travel and how do you use it?
Q02SENIOR
Explain Zero-Copy Cloning and its advantages over traditional copying.
Q03SENIOR
How would you recover a table that was accidentally dropped 2 days ago, ...
Q04SENIOR
What are the cost implications of using Time Travel and Zero-Copy Clonin...
Q05SENIOR
Can you use Time Travel with external tables?
Q01 of 05JUNIOR

What is Snowflake Time Travel and how do you use it?

ANSWER
Time Travel allows you to access historical data within a retention period (1-90 days). You use the AT or BEFORE clause in SELECT statements, or UNDROP to restore dropped objects. For example: SELECT * FROM table AT (OFFSET => -3600);
FAQ · 5 QUESTIONS

Frequently Asked Questions

01
How long does Snowflake Time Travel retain data?
02
Does Zero-Copy Cloning incur storage costs?
03
Can I use Time Travel to restore a dropped database?
04
Is there a limit on the number of clones I can create?
05
Can I clone a table across different Snowflake accounts?
N
Naren Founder & Principal Engineer

20+ years shipping high-throughput database systems. Written from production experience, not tutorials.

Follow
Verified
production tested
July 17, 2026
last updated
2,439
articles · all by Naren
🔥

That's Snowflake. Mark it forged?

6 min read · try the examples if you haven't

Previous
SQL: Querying, Filtering, Joins, and Window Functions
7 / 33 · Snowflake
Next
Streams and Tasks: Automated Real-Time Data Pipelines