Docs /Tables and storage /Snapshots and clones
Tables and storageTables

Table snapshots and table clones in BigQuery

A BigQuery table snapshot is a read-only copy that you keep as long as you like. A table clone is a writable copy. Both are billed only for the data that differs from the base table. How to create them, what blocks you, and how to restore from one.

A table snapshot is a read-only copy of a table at one moment. A table clone is a writable copy. Neither copies the data when you create it: BigQuery shares the base table’s storage, and you pay only for bytes that later differ from the base table. Use a snapshot to keep a table as it was, for longer than the 7-day time travel window allows. Use a clone when you want to change the copy, for a test or a sandbox.

Create a snapshot

CREATE SNAPSHOT TABLE sales.orders_2026_10_06
CLONE sales.orders
OPTIONS (expiration_timestamp = TIMESTAMP '2027-01-01 00:00:00+00');

The keyword is CLONE for snapshots too. The source can be a table, a clone or another snapshot. You can query the snapshot like any table.

Add FOR SYSTEM_TIME AS OF to snapshot the table as it was earlier, inside its time travel window. This is also how you freeze a table’s state from before a bad change, before the window ends:

CREATE SNAPSHOT TABLE sales.orders_before_fix
CLONE sales.orders
FOR SYSTEM_TIME AS OF TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 3 HOUR);

A snapshot never overwrites. If the name is taken, the statement fails with Already Exists, IF NOT EXISTS skips it, and OR REPLACE isn’t allowed at all:

CREATE OR REPLACE is refusedBigQuery rejects this query
12
CREATE OR REPLACE SNAPSHOT TABLE sales.orders_snapshot
CLONE sales.orders
Error in BigQuery

OR REPLACE is not allowed with CREATE SNAPSHOT TABLE. at [1:1]

To refresh a snapshot, drop it and create it again. A snapshot is dropped with its own statement. DROP TABLE on a snapshot fails with Cannot drop ... which has type SNAPSHOT. A table was expected.

DROP SNAPSHOT TABLE sales.orders_2026_10_06;

Create a clone

CREATE TABLE sales.orders_dev
CLONE sales.orders;

The clone takes the same options as CREATE TABLE, and FOR SYSTEM_TIME AS OF works here too. The result is a table you can query, insert into, update and drop with DROP TABLE. After creation it is independent: changes to the base table don’t show up in the clone, and the other way round.

In Querylab.io, a table’s SQL Templates include CLONE TABLE (DDL operations), and Bulk Generate writes a CREATE TABLE ... CLONE statement for every table in a dataset that matches a name pattern (Bulk operations).

We created a 3-row table, a snapshot and a clone of it, then deleted a row from the base and inserted one into the clone. The row counts:

TableRows
base2
snapshot3
clone4

The snapshot kept what the table looked like when it was taken. The clone moved on by itself.

Snapshots are read-only

INSERT, UPDATE, DELETE and ALTER TABLE ... ADD COLUMN on a snapshot all fail:

Table myproject:mydataset.orders_snap is a snapshot, and snapshots are immutable.
ALTER TABLE does not support modifying the schema of a(n) SNAPSHOT: orders_snap

You can change a snapshot’s metadata: description, expiration and access policy.

Restore from a snapshot

A snapshot is restored by cloning it into a table:

CREATE TABLE sales.orders_restored
CLONE sales.orders_2026_10_06;

We ran this on a test snapshot and the new table had all 3 of the snapshot’s rows. To replace the broken table itself, drop it (inside its own time travel window you can still undo that, see Time travel) and create a clone under the old name.

How a snapshot or a clone shows up in metadata

INFORMATION_SCHEMA.TABLES has the type and the base table:

SELECT table_name, table_type, base_table_name, snapshot_time_ms
FROM sales.INFORMATION_SCHEMA.TABLES;

In our test this returned BASE TABLE, CLONE and SNAPSHOT for the three tables, with the base table’s name in base_table_name for the last two. snapshot_time_ms holds the moment the copy was taken, which is the time travel timestamp if you used one. The ddl column of a snapshot is a ready CREATE SNAPSHOT TABLE ... CLONE ... FOR SYSTEM_TIME AS OF statement, with the exact snapshot time in it.

What it costs

Creating either one costs nothing in storage at first. After that:

  • A snapshot or clone has the same storage type as its source. A snapshot of long-term data is long-term.
  • When you change or delete data in the base table that a snapshot also holds, the snapshot is charged for those bytes. If several snapshots hold the same changed data, only the oldest is charged.
  • In a clone, the changes you make to the clone are charged to the clone. New data in the base table after the clone was made stays on the base table’s bill.
  • With physical storage billing, the time travel and fail-safe charges for the base table are not applied while snapshots hold the data. They are charged when the snapshot is deleted.
  • A copy job (bq cp) of a snapshot or clone, to the same or to another region, is a full copy and is billed as a full table.

To see how many bytes a table, snapshot or clone holds, use INFORMATION_SCHEMA.TABLE_STORAGE. See Storage pricing.

Limits

  • A snapshot or clone must be in the same region, and the same organization, as its base table. Cloning across projects is allowed. Cloning from an EU dataset into a US dataset is not. If you pick a dataset in another region for a snapshot, BigQuery makes a full copy there instead.
  • You can’t snapshot or clone a view, a materialized view or an external table. For a view, BigQuery answers Cannot snapshot ... which has type VIEW. Allowed types: [TABLE, SNAPSHOT], and the clone error is the same with “clone”.
  • Data in the streaming buffer (recently streamed rows) is not in the copy.
  • The snapshot time can’t be older than the table’s time travel window. Google’s snapshot guide says 7 days.
  • A partitioned table’s partition expiration is not kept by a snapshot. The snapshot uses the destination dataset’s default partition expiration. Google’s advice is to copy the table instead if you need to keep it.
  • A clone can’t append to an existing table. To add data to a table, use a normal copy.
  • A clone takes a variable time to create, because storage is managed dynamically.

Snapshot, clone or copy?

A snapshot is read-only, a clone is writable, and a copy (bq cp or CREATE TABLE AS SELECT) is a full, independent table that costs its whole size in storage from the start. Drop a snapshot with DROP SNAPSHOT TABLE, and a clone or copy with DROP TABLE. Use CREATE TABLE ... AS SELECT when the copy needs a different shape or a filter, because snapshots and clones always take the whole table.