BigQuery change history lets you track the history of
changes to a BigQuery table. You can use GoogleSQL
functions
to see particular types of changes made during a specified time range, so
that you can process incremental changes made to a table. Understanding what
changes have been made to a table can help you do things like incrementally
maintain a table replica outside of BigQuery while avoiding
costly copies.
Required permissions
To view the change history on a table, you need the bigquery.tables.getData
permission on that table. The following predefined Identity and Access Management (IAM)
roles include this permission:
roles/bigquery.dataViewer
roles/bigquery.dataEditor
roles/bigquery.dataOwner
roles/bigquery.admin
If a table has, or has had,
row-level access policies, then only
a table administrator can access historical data for the table. The
bigquery.rowAccessPolicies.overrideTimeTravelRestrictions permission is
required on the table and is included in the predefined roles/bigquery.admin
IAM role.
If a table has column-level security, you can only view the
change history on the columns that you have access to.
Change history functions
You can use the following functions to understand a table's change history:
APPENDS:
returns all rows appended to a table for given time range.
The following operations add rows to the APPENDS change history:
CHANGES:
returns all rows that have changed in a table for a given time range. To use
the CHANGES function on a table, you must set the table's
enable_change_history option
to TRUE.
The following operations add rows to the CHANGES change history:
Calling change history functions
incurs BigQuery compute costs.
Both the APPENDS and CHANGES functions require processing all data written
to the table within the specified time range. This processing applies to all
writes, including both append and mutation operations.
Setting a table's enable_change_history option to FALSE does not reduce the data processed by APPENDS.
When you set the
enable_change_history option
on a table to TRUE in order to use the CHANGES function,
BigQuery stores table change metadata. This stored metadata
incurs additional BigQuery storage costs
and BigQuery compute costs.
The amount billed depends on the number and type of changes made to the table,
and is typically small. Tables that have many change operations, especially
large deletions, are the most likely to incur noticeable costs.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-25 UTC."],[[["\u003cp\u003eBigQuery change history allows tracking of modifications to BigQuery tables, enabling users to identify specific changes within a given timeframe.\u003c/p\u003e\n"],["\u003cp\u003eAccessing change history requires the \u003ccode\u003ebigquery.tables.getData\u003c/code\u003e permission, included in roles like \u003ccode\u003eroles/bigquery.dataViewer\u003c/code\u003e, \u003ccode\u003eroles/bigquery.dataEditor\u003c/code\u003e, \u003ccode\u003eroles/bigquery.dataOwner\u003c/code\u003e, and \u003ccode\u003eroles/bigquery.admin\u003c/code\u003e.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003eAPPENDS\u003c/code\u003e function returns all rows appended to a table within a specified time range, while the \u003ccode\u003eCHANGES\u003c/code\u003e function, which requires enabling the \u003ccode\u003eenable_change_history\u003c/code\u003e option, returns all changed rows within a given range.\u003c/p\u003e\n"],["\u003cp\u003eUtilizing change history functions incurs BigQuery compute costs, as they must process all data written to the table during the designated time period, and setting \u003ccode\u003eenable_change_history\u003c/code\u003e to \u003ccode\u003eTRUE\u003c/code\u003e adds storage and compute costs.\u003c/p\u003e\n"],["\u003cp\u003eThis is currently a pre-GA feature and it is available "as is", therefore the support may be limited, and any questions or feedback about it should be directed to bq-change-history-feedback@google.com.\u003c/p\u003e\n"]]],[],null,["# Work with change history\n========================\n\n|\n| **Preview**\n|\n|\n| This product or feature is subject to the \"Pre-GA Offerings Terms\" in the General Service Terms section\n| of the [Service Specific Terms](/terms/service-terms#1).\n|\n| Pre-GA products and features are available \"as is\" and might have limited support.\n|\n| For more information, see the\n| [launch stage descriptions](/products#product-launch-stages).\n| **Note:** For support during the preview, contact [bq-change-history-feedback@google.com](mailto:bq-change-history-feedback@google.com).\n\nBigQuery change history lets you track the history of\nchanges to a BigQuery table. You can use GoogleSQL\n[functions](/bigquery/docs/reference/standard-sql/table-functions-built-in)\nto see particular types of changes made during a specified time range, so\nthat you can process incremental changes made to a table. Understanding what\nchanges have been made to a table can help you do things like incrementally\nmaintain a table replica outside of BigQuery while avoiding\ncostly copies.\n\nRequired permissions\n--------------------\n\nTo view the change history on a table, you need the `bigquery.tables.getData`\npermission on that table. The following predefined Identity and Access Management (IAM)\nroles include this permission:\n\n- `roles/bigquery.dataViewer`\n- `roles/bigquery.dataEditor`\n- `roles/bigquery.dataOwner`\n- `roles/bigquery.admin`\n\nIf a table has, or has had,\n[row-level access policies](/bigquery/docs/row-level-security-intro), then only\na table administrator can access historical data for the table. The\n`bigquery.rowAccessPolicies.overrideTimeTravelRestrictions` permission is\nrequired on the table and is included in the predefined `roles/bigquery.admin`\nIAM role.\n\nIf a table has column-level security, you can only view the\nchange history on the columns that you have access to.\n\nChange history functions\n------------------------\n\nYou can use the following functions to understand a table's change history:\n\n- [`APPENDS`](/bigquery/docs/reference/standard-sql/time-series-functions#appends):\n returns all rows appended to a table for given time range.\n\n The following operations add rows to the `APPENDS` change history:\n - [`CREATE TABLE` DDL statement](/bigquery/docs/reference/standard-sql/data-definition-language#create_table_statement)\n - [`INSERT` DML statement](/bigquery/docs/reference/standard-sql/dml-syntax#insert_statement)\n - [Data appended as part of a `MERGE` DML statement](/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement)\n - [Loading data](/bigquery/docs/loading-data) into BigQuery\n - [Streaming ingestion](/bigquery/docs/write-api)\n- [`CHANGES`](/bigquery/docs/reference/standard-sql/time-series-functions#changes):\n returns all rows that have changed in a table for a given time range. To use\n the `CHANGES` function on a table, you must set the table's\n [`enable_change_history` option](/bigquery/docs/reference/standard-sql/data-definition-language#table_option_list)\n to `TRUE`.\n\n The following operations add rows to the `CHANGES` change history:\n - [`CREATE TABLE` DDL statement](/bigquery/docs/reference/standard-sql/data-definition-language#create_table_statement)\n - [`INSERT` DML statement](/bigquery/docs/reference/standard-sql/dml-syntax#insert_statement)\n - [Data appended or changed as part of a `MERGE` DML statement](/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement)\n - [`UPDATE` DML statement](/bigquery/docs/reference/standard-sql/dml-syntax#update_statement)\n - [`DELETE` DML statement](/bigquery/docs/reference/standard-sql/dml-syntax#delete_statement)\n - [Loading data](/bigquery/docs/loading-data) into BigQuery\n - [Streaming ingestion](/bigquery/docs/write-api)\n - [`TRUNCATE TABLE` DML statement](/bigquery/docs/reference/standard-sql/dml-syntax#truncate_table_statement)\n - [Jobs](/bigquery/docs/reference/rest/v2/Job) configured with a `writeDisposition` of `WRITE_TRUNCATE`\n - Individual [table partition deletions](/bigquery/docs/managing-partitioned-tables#delete_a_partition)\n\nPricing and costs\n-----------------\n\nCalling change history functions\nincurs [BigQuery compute costs](/bigquery/pricing#analysis_pricing_models).\nBoth the `APPENDS` and `CHANGES` functions require processing all data written\nto the table within the specified time range. This processing applies to all\nwrites, including both append and mutation operations.\nSetting a table's [`enable_change_history` option](/bigquery/docs/reference/standard-sql/data-definition-language#table_option_list) to `FALSE` does not reduce the data processed by `APPENDS`.\n\nWhen you set the\n[`enable_change_history` option](/bigquery/docs/reference/standard-sql/data-definition-language#table_option_list)\non a table to `TRUE` in order to use the `CHANGES` function,\nBigQuery stores table change metadata. This stored metadata\nincurs additional [BigQuery storage costs](/bigquery/pricing#storage)\nand [BigQuery compute costs](/bigquery/pricing#analysis_pricing_models).\nThe amount billed depends on the number and type of changes made to the table,\nand is typically small. Tables that have many change operations, especially\nlarge deletions, are the most likely to incur noticeable costs."]]