Docs /Cost and pricing /Storage pricing
Cost and pricingCost

BigQuery storage pricing: active, long-term, logical and physical

BigQuery bills stored data per GiB-month at an active or long-term rate, measured in logical or physical bytes. How the 90-day rule works, what resets it, and what time travel adds to the bill.

BigQuery bills stored data in GiB-months, prorated per second, at one of two rates. Data in a table or partition that nobody has modified for 90 days moves to the long-term rate, and everything else is active. On top of that, each dataset picks how bytes are counted: logical (the uncompressed size, the default) or physical (the compressed size on disk). The first 10 GiB each month is free.

Storage is billed the same way whether your queries run on-demand or on capacity pricing.

The rates

Prices as of October 2026, in us-central1. Google lists them per GiB-hour, and the monthly figures below use a 730-hour month. Other locations, including the US multi-region, have different rates, so check yours on the pricing page.

Billing modelActive, per GiB-monthLong-term, per GiB-month
Logical$0.023$0.016
Physical$0.040$0.020

A full month of 1 TiB of active logical storage in us-central1 costs $23.55. Half a month of 100 GiB costs $1.15.

Google’s pricing page says the long-term price drops “by approximately 50%”. That holds for the physical rates above and not for the logical ones, where us-central1 shows about 30% off. Read the rates for your region rather than assuming a discount.

How big is a table? BigQuery counts bytes per column from the data types: 8 bytes for an INT64, 2 bytes plus the length for a STRING, and so on. The same sizes are used for query billing.

Active and long-term storage

If a table isn’t modified for 90 consecutive days, its storage is billed at the long-term rate. A partitioned table is judged one partition at a time, so last year’s partitions turn long-term while this month’s stay active. Nothing else changes: long-term data has the same speed, durability and availability.

four tables, two rates
123456789101112
WITH tables AS (
  SELECT 'orders_2026_10' AS table_name, 500 AS logical_gib, 3 AS days_since_modified
  UNION ALL SELECT 'orders_2025', 2000, 400
  UNION ALL SELECT 'orders_2026_07', 800, 91
  UNION ALL SELECT 'orders_2026_08', 800, 89
)
SELECT
  table_name,
  IF(days_since_modified >= 90, 'long-term', 'active') AS tier,
  ROUND(logical_gib * IF(days_since_modified >= 90, NUMERIC '0.016', NUMERIC '0.023'), 2) AS usd_per_month
FROM tables
ORDER BY table_name
Result in BigQuery
table_nametierusd_per_month
1orders_2025long-term32
2orders_2026_07long-term12.8
3orders_2026_08active18.4
4orders_2026_10active11.5
4 rows

orders_2025 was last modified 400 days ago, so its 2,000 GiB costs $32 a month. orders_2026_08 is the same size as orders_2026_07 but was modified 89 days ago instead of 91, so it still costs $18.40 instead of $12.80.

What resets the 90 days

Any change to the data puts the table, or the changed partition, back to active, and the 90-day timer starts again. Google’s pricing page lists these:

  • A load job or query job that appends to or overwrites the table
  • A copy job into the table
  • Writing query results to the table
  • DML (INSERT, UPDATE, DELETE, MERGE, TRUNCATE)
  • CREATE OR REPLACE TABLE
  • Streaming data into the table

These do not reset it: querying the table, creating a view over it, exporting from it, copying it to another table, and patching or updating the table resource.

Google’s cost guide disagrees on that last point. It says schema changes with ALTER, and changes to the description, labels or expiration, can also move data back to active storage. The two pages contradict each other, so don’t rely on metadata edits being free for old tables. Long-term pricing also only applies to data stored in BigQuery, not to external tables over Cloud Storage or Bigtable.

A common cause of a storage bill that goes up for no reason is a job that rewrites a whole old table, for example a nightly CREATE OR REPLACE TABLE that loads the same history again. Every partition restarts at active.

Logical or physical bytes

You set the billing model on each dataset. New datasets are logical. Your data is stored compressed either way, and the setting only changes what BigQuery measures and what it charges per GiB. Query speed doesn’t change.

Physical costs more per GiB, as the table above shows, so it only wins when your data compresses well. For active data, physical is cheaper when the logical size is more than about 1.7 times the physical size ($0.040 divided by $0.023). It also changes what else you pay for, which is the next section.

Time travel and fail-safe

When you change or delete data, BigQuery keeps the old version. For the time travel window (7 days by default, from 2 to 7 days) you can query the table as it was. After that, a fail-safe period of 7 more days lets Google Cloud support recover deleted data. You can’t read fail-safe data or change its length.

Whether you pay for those old bytes depends on the billing model:

LogicalPhysical
Active and long-term bytesBilledBilled
Time travel bytesIncluded in the logical rateBilled at the active physical rate
Fail-safe bytesIncluded in the logical rateBilled at the active physical rate

A table that was just created has no time travel or fail-safe cost. The cost appears when data is changed or deleted. In the physical model, a table that is overwritten or truncated often keeps up to 14 days of old versions on the bill. Google advises loading with append or MERGE instead of replacing tables, and shortening the time travel window if you don’t need seven days.

Deleting a table in a physical dataset can make the bill go up for a while. The deleted data stays billed at the active physical rate through time travel and fail-safe, and if it had been long-term data, it moves to active when it is deleted. Active physical bytes cost twice as much as long-term physical bytes.

This example compares two datasets that hold 1,000 GiB of logical data. events compresses to 250 GiB and rarely changes, so it carries only 25 GiB each of time travel and fail-safe data. orders compresses to only 600 GiB and is rewritten often, so it carries 100 GiB each of time travel and fail-safe data:

logical vs physical, with time travel
12345678910
WITH datasets AS (
  SELECT 'events' AS dataset, 1000 AS logical_gib, 250 AS physical_gib, 25 AS time_travel_gib, 25 AS fail_safe_gib
  UNION ALL SELECT 'orders', 1000, 600, 100, 100
)
SELECT
  dataset,
  ROUND(logical_gib * NUMERIC '0.023', 2) AS logical_usd,
  ROUND((physical_gib + time_travel_gib + fail_safe_gib) * NUMERIC '0.04', 2) AS physical_usd
FROM datasets
ORDER BY dataset
Result in BigQuery
datasetlogical_usdphysical_usd
1events2312
2orders2332
2 rows

Physical billing makes events about half the price and orders more expensive. The figures use us-central1 active rates for everything and ignore long-term data.

Switching a dataset

ALTER SCHEMA my_dataset
SET OPTIONS (
  storage_billing_model = 'PHYSICAL',
  max_time_travel_hours = 48
);

This statement is not run on this page. It passes a dry run. Some rules apply:

  • The change takes 24 hours to take effect.
  • After a change you must wait 14 days before changing again.
  • Tables in long-term storage stay long-term when you switch.
  • max_time_travel_hours is a multiple of 24 from 48 to 168. The default is 168.
  • You can’t enroll a dataset in physical billing if your organization has legacy flat-rate slot commitments in the same region. Commitments bought with an edition don’t count.
  • The storage_billing_model option is only available on datasets last updated after December 1, 2022. Older untouched datasets are logical.

Forecast both models for your data

INFORMATION_SCHEMA.TABLE_STORAGE_BY_PROJECT has the sizes in both models. This query prices each dataset under each model. The DECLARE lines hold the us-central1 rates from above:

DECLARE active_logical_gib_price FLOAT64 DEFAULT 0.023;
DECLARE long_term_logical_gib_price FLOAT64 DEFAULT 0.016;
DECLARE active_physical_gib_price FLOAT64 DEFAULT 0.04;
DECLARE long_term_physical_gib_price FLOAT64 DEFAULT 0.02;

SELECT
  table_schema AS dataset,
  ROUND(
    SUM(active_logical_bytes) / POW(1024, 3) * active_logical_gib_price
    + SUM(long_term_logical_bytes) / POW(1024, 3) * long_term_logical_gib_price, 2) AS logical_usd_per_month,
  ROUND(
    SUM(active_physical_bytes + fail_safe_physical_bytes) / POW(1024, 3) * active_physical_gib_price
    + SUM(long_term_physical_bytes) / POW(1024, 3) * long_term_physical_gib_price, 2) AS physical_usd_per_month
FROM `region-us`.INFORMATION_SCHEMA.TABLE_STORAGE_BY_PROJECT
WHERE table_type = 'BASE TABLE'
  AND NOT deleted
GROUP BY dataset
ORDER BY logical_usd_per_month DESC;

This follows Google’s own forecast example and is not run here. In the physical column, active_physical_bytes already includes time travel bytes, so adding fail_safe_physical_bytes covers both. The numbers are a snapshot, and your bill is the bytes multiplied by how long you held them. For accurate figures use TABLE_STORAGE_USAGE_TIMELINE, which records usage over time.

In Querylab.io, a dataset’s Storage tab prices its storage under both models and shows what switching would save, and its “If switched to” block opens the ALTER SCHEMA statement in a new tab. A table’s Storage tab splits its bytes into active, long-term, time travel and fail-safe (Storage statistics).

Other things that are or aren’t billed

  • Query results cache. Cached results are stored in temporary tables and are not billed. See Query cache.
  • Temporary tables. Session and multi-statement-query temporary tables are billed as active storage only, and not for fail-safe.
  • Snapshots and clones. You pay only for the data that differs from the base table. TABLE_STORAGE shows them at full size, which overstates the cost.
  • Loading. Batch loading is free, using the shared slot pool. Streaming through the Storage Write API is billed separately. Google lists $0.025 per GiB, with the first 2 TiB each month free, for its gRPC form in us-central1.
  • Expiration. Setting a table or partition expiration deletes data automatically. See Table expiration.

Comparing with the bill

The numbers in INFORMATION_SCHEMA won’t match an invoice exactly. The views use UTC, while the billing report’s days start at midnight Pacific time. The views don’t include taxes, adjustments or rounding. And a snapshot of bytes is not GiB-months: 31 GiB held for one day of a 31-day month is about 1 GiB-month.