The AI.FORECAST function
This document describes the AI.FORECAST function, which lets you forecast time
series by using the TimesFM model that's built
into BigQuery ML. You can use this function to perform univariate or
multivariate forecasting:
- Univariate forecasting: predicts future values of a single time series based only on its own past values.
- Multivariate forecasting: predicts future values based on the time series' past values and additional variables (covariates) that might influence the forecast.
For example, imagine you have a table containing sales data for a product. You could run a query similar to the following to forecast sales for the next 30 data points:
SELECT *
FROM AI.FORECAST(
TABLE `mydataset.input_table`,
data_col => 'units_sold',
timestamp_col => 'sales_date',
horizon => 30);
Syntax
The syntax for AI.FORECAST depends on if you're performing univariate or
multivariate forecasting.
Univariate
SELECT
*
FROM
AI.FORECAST(
{ TABLE TABLE | (QUERY_STATEMENT) },
data_col => 'DATA_COL',
timestamp_col => 'TIMESTAMP_COL'
[, model => 'MODEL']
[, id_cols => ID_COLS]
[, horizon => HORIZON]
[, forecast_end_timestamp => FORECAST_END_TIMESTAMP]
[, confidence_level => CONFIDENCE_LEVEL]
[, output_historical_time_series => OUTPUT_HISTORICAL_TIME_SERIES]
[, context_window => CONTEXT_WINDOW]
)
Arguments
AI.FORECAST takes the following arguments for univariate forecasting:
TABLE: the name of the table that contains the data that you want to forecast. For example,`mydataset.mytable`.If the table is in a different project, then you must prepend the project ID to the table name in the following format, including backticks:
`PROJECT_ID.DATASET.TABLE`For example,
`myproject.mydataset.mytable`.To prevent query errors, we recommend providing the fully qualified table name, including backticks. This is especially important if the project name contains characters other than letters, numbers, and underscores.
QUERY_STATEMENT: the GoogleSQL query that generates the data that you want to forecast. See the GoogleSQL query syntax page for the supported SQL syntax of theQUERY_STATEMENTclause.DATA_COL: aSTRINGvalue that specifies the name of the data column. The data column contains the data to forecast. The data column must use one of the following data types:INT64NUMERICBIGNUMERICFLOAT64
TIMESTAMP_COL: aSTRINGvalue that specifies the name of the timestamp column. The timestamp column must use one of the following data types:TIMESTAMPDATEDATETIME
MODEL: aSTRINGvalue that specifies the name of the model to use. Supported models includeTimesFM 2.0,TimesFM 2.5, andTimesFM 3.0(Preview). The default value isTimesFM 2.5.ID_COLS: anARRAY<STRING>value that specifies the names of one or more ID columns. Each unique combination of IDs identifies a unique time series to forecast. Specify one or more values for this argument in order to forecast multiple time series using a single query. The columns that you specify must use one of the following data types:STRINGINT64ARRAY<STRING>ARRAY<INT64>
HORIZON: anINT64value that specifies the number of time series data points to forecast. The default value is10. The valid input range for theTimesFM 2.0andTimesFM 2.5models is[1, 10,000]. The valid input range for theTimesFM 3.0model is[1, 1024]. This argument can't be used with theforecast_end_timestampargument.FORECAST_END_TIMESTAMP: a timestamp literal value that specifies the end timestamp for the forecasted values. The horizon is calculated based on the end timestamp and the frequency provided from the input table for each time series. If the calculated horizon is out of the valid range[1, 10,000], the query returns an error. You can then adjust theforecast_end_timestampvalue so that the calculated horizon is within the valid range. This argument can't be used with thehorizonargument.CONFIDENCE_LEVEL: aFLOAT64value that specifies the percentage of the future values that fall in the prediction interval. The default value is0.95. The valid input range is[0, 1).OUTPUT_HISTORICAL_TIME_SERIES: aBOOLvalue that determines whether the input data is returned along with the forecasted data. Set this argument toTRUEto return input data. The default value isFALSE.Returning the input data along with the forecasted data lets you compare the historical value of the data column with the forecasted value of the data column, or chart the change in the data column values over time.
CONTEXT_WINDOW: anINT64value that specifies the context window length used by BigQuery ML's built-in TimesFM model. The context window length determines how many of the most recent data points from the input time series are used by the model. For example, if your time series date range is March 1 to April 15, data points are selected starting at April 15 and working backwards. Valid values for models are as follows:Model name Supported context window length TimesFM 2.064, 128, 256, 512, 1024, 2048 TimesFM 2.564, 128, 256, 512, 1024, 2048, 4096, 8192, 15360 TimesFM 3.0n * 32wherenis an integer in the range[2, 64]If you don't specify a
CONTEXT_WINDOWvalue with theTimesFM 2.0orTimesFM 2.5models, theAI.FORECASTfunction automatically chooses the smallest possible context window length to use that is still large enough to cover the number of time series data points in your input data. If you don't specify aCONTEXT_WINDOWvalue when you use theTimesFM 3.0model, theAI.FORECASTfunction defaults to the maximum supported size,2048. The following table shows the relationships between the number of time series data points in the input data, the selected context window length and the corresponding supported TimesFM model name:Number of time series data points Context window length Supported model names (1, 64]64 TimesFM 2.0,TimesFM 2.5,TimesFM 3.0(65, 128]128 TimesFM 2.0,TimesFM 2.5,TimesFM 3.0(129, 256]256 TimesFM 2.0,TimesFM 2.5,TimesFM 3.0(257, 512]512 TimesFM 2.0,TimesFM 2.5,TimesFM 3.0(513, 1024]1,024 TimesFM 2.0,TimesFM 2.5,TimesFM 3.0(1025, 2048]2,048 TimesFM 2.0,TimesFM 2.5,TimesFM 3.0(2049, 4096]4,096 TimesFM 2.5(4097, 8192]8,192 TimesFM 2.5(8193, 15360]15,360 TimesFM 2.51536015,360 TimesFM 2.5For the
TimesFM 2.0andTimesFM 3.0models, 2,048 is the maximum number of time series data points that are passed to the model. For theTimesFM 2.5model, 15,360 is the maximum number of time series data points that are passed to the model. Any additional time series data points in the input data are ignored.
Multivariate
SELECT *
FROM AI.FORECAST(
{ TABLE TABLE | (QUERY_STATEMENT) },
target_cols => [TARGET_COLS],
timestamp_col => 'TIMESTAMP_COL',
model => 'MODEL'
[, id_cols => [ID_COLS]]
[, horizon => HORIZON]
[, confidence_level => CONFIDENCE_LEVEL]
[, context_window => CONTEXT_WINDOW]
[, past_covariate_cols => [PAST_COVARIATE_COLS]]
[, future_covariate_cols => [FUTURE_COVARIATE_COLS]]
[, output_historical_time_series => OUTPUT_HISTORICAL_TIME_SERIES]
);
Arguments
AI.FORECAST takes the following arguments for multivariate forecasting:
TABLE: the name of the table that contains the data that you want to forecast. For example,`mydataset.mytable`.If the table is in a different project, then you must prepend the project ID to the table name in the following format, including backticks:
`PROJECT_ID.DATASET.TABLE`For example,
`myproject.mydataset.mytable`.To prevent query errors, we recommend providing the fully qualified table name, including backticks. This is especially important if the project name contains characters other than letters, numbers, and underscores.
QUERY_STATEMENT: the GoogleSQL query that generates the data that you want to forecast. See the GoogleSQL query syntax page for the supported SQL syntax of theQUERY_STATEMENTclause.TARGET_COLS: anARRAY<STRING>value that specifies the names of the data columns. The data columns contain the data to forecast. The data columns must use one of the following data types:INT64NUMERICBIGNUMERICFLOAT64
TIMESTAMP_COL: aSTRINGvalue that specifies the name of the timestamp column. The timestamp column must use one of the following data types:TIMESTAMPDATEDATETIME
MODEL: aSTRINGvalue that specifies the name of the model to use. You must use theTimesFM 3.0model (Preview) for multivariate forecasting.PAST_COVARIATE_COLS: an
ARRAY<STRING>value that specifies the names of columns that could influence the target columns and that are only known historically. For example, if you're forecasting daily sales at a store's location, then a past covariate column could be the number of customers who visited the store each day. Customer counts are known historically and can influence sales, but they aren't known for the future. The columns that you specify must use one of the following data types:INT64FLOAT64NUMERICBIGNUMERIC
FUTURE_COVARIATE_COLS: an
ARRAY<STRING>value that specifies the names of columns that could influence the target columns and are known for both the past and the future. For example, if you're forecasting daily sales at a store's location, then a future covariate column could be whether or not the day is a weekend. This data is known in advance for both the past and the future. The columns that you specify must use one of the following data types:INT64FLOAT64NUMERICBIGNUMERIC
HORIZON: anINT64value that specifies the number of time series data points to forecast. The default value is10. The valid input range for theTimesFM 3.0model is[1, 1024]. This argument can't be used with theforecast_end_timestampargument.ID_COLS: anARRAY<STRING>value that specifies the names of one or more ID columns. Each unique combination of IDs identifies a unique time series to forecast. Specify one or more values for this argument in order to forecast multiple time series using a single query. The columns that you specify must use one of the following data types:STRINGINT64ARRAY<STRING>ARRAY<INT64>
CONFIDENCE_LEVEL: aFLOAT64value that specifies the percentage of the future values that fall in the prediction interval. The default value is0.95. The valid input range is[0, 1).CONTEXT_WINDOW: anINT64value that specifies the context window length used by the TimesFM model. The context window length determines how many of the most recent data points from the input time series are used by the model. For example, if your time series date range is March 1 to April 15, data points are selected starting at April 15 and working backwards. Valid values for theTimesFM 3.0model are as follows:Model name Supported context window length TimesFM 3.0n * 32wherenis an integer in the range[2, 64]If you don't specify a
CONTEXT_WINDOWvalue when you use theTimesFM 3.0model, theAI.FORECASTfunction defaults to the maximum supported size,2048.For the
TimesFM 3.0model, 2,048 is the maximum number of time series data points that are passed to the model. Any additional time series data points in the input data are ignored.OUTPUT_HISTORICAL_TIME_SERIES: aBOOLvalue that determines whether the input data is returned along with the forecasted data. Set this argument toTRUEto return input data. The default value isFALSE.Returning the input data along with the forecasted data lets you compare the historical value of the data column with the forecasted value of the data column, or chart the change in the data column values over time.
Output
The output schema of AI.FORECAST depends on if you're performing univariate or
multivariate forecasting.
Univariate
The output schema of AI.FORECAST depends on the value of the
output_historical_time_series argument. The following columns are always part
of the output:
id_cols: one or more values that contain the identifiers of a time series.id_colscan be anINT64,STRING,ARRAY<INT64>, orARRAY<STRING>value. The column names and types are inherited from theID_COLSargument value specified in the function input.confidence_level: aFLOAT64value that contains theconfidence_levelvalue that you specified in the function input, or0.95if you didn't specify aconfidence_levelvalue. This value is the same across all rows.prediction_interval_lower_bound: aFLOAT64value that contains the lower bound of the prediction interval for each forecasted point. For historical points, the value isNULL.prediction_interval_upper_bound: aFLOAT64value that contains the upper bound of the prediction interval for each forecasted point. For historical points, the value isNULL.ai_forecast_status: aSTRINGvalue that contains the forecast status. This value is empty if the operation was successful. If the operation wasn't successful, the value is the error string. A common error isThe time series data is too short.This error indicates that there wasn't enough historical data in the time series to generate a forecast. A minimum of 3 data points is required.
If you set output_historical_time_series to FALSE, then the output rows
only include forecasted data and the output columns are the following:
forecast_timestamp: aTIMESTAMPvalue that contains the timestamps of the time series.forecast_value: aFLOAT64value that contains the 50% quantile value for the forecasting output from the model. The 50% quantile value represents the median value of the forecasted data.
If you set output_historical_time_series to TRUE, then the output rows
include all data, and the output columns are the following:
time_series_type: aSTRINGvalue that contains a value of eitherhistoryorforecast. Rows that have a value ofhistorycontain data from the input table or query. Rows that have a value offorecastcontain forecasted data.time_series_timestamp: aTIMESTAMPvalue that contains the timestamps of the time series.time_series_data: aFLOAT64value that represents the historical input if thetime_series_typeishistory. Otherwise, if thetime_series_typeisforecastthis number represents the 50% quantile of the forecast.
Multivariate
If you perform a multivariate forecast, the output schema is restructured to support multiple targets:
id_cols: one or more values that contain the identifiers of a time series.id_colscan be anINT64,STRING,ARRAY<INT64>, orARRAY<STRING>value. The column names and types are inherited from theID_COLSargument value specified in the function input.timestamp_col: aTIMESTAMPvalue that contains the timestamp of the data point. Unlike univariate, this column preserves the name of the timestamp column from your input table—for example,date.target_cols: for each target column specified inTARGET_COLSinput argument, the output contains aSTRUCTtype with the following fields:value: aFLOAT64value that contains the 50% quantile value for the forecasting output from the model. The 50% quantile value represents the median value of the forecasted data.prediction_interval_lower_bound: aFLOAT64value that contains the lower bound of the prediction interval for each forecasted point. For historical points, the value isNULL.prediction_interval_upper_bound: aFLOAT64value that contains the upper bound of the prediction interval for each forecasted point. For historical points, the value isNULL.
time_series_type: aSTRINGvalue that contains a value of eitherhistoryorforecast. Rows that have a value ofhistorycontain data from the input table or query. Rows that have a value offorecastcontain forecasted data.confidence_level: aFLOAT64value that contains theconfidence_levelvalue that you specified in the function input, or0.95if you didn't specify aconfidence_levelvalue. This value is the same across all rows.ai_forecast_status: aSTRINGvalue that contains the forecast status. This value is empty if the operation was successful. If the operation failed, the value is the error string. A common error isThe time series data is too short.This error indicates that there wasn't enough historical data in the time series to generate a forecast. A minimum of 3 data points is required.
Examples
The following examples show how to perform univariate and multivariate forecasting.
Univariate forecasting
The following example performs univariate forecasting to predict the daily number of bike trips for each different user type for the next 30 days:
WITH
citibike_trips AS (
SELECT EXTRACT(DATE FROM starttime) AS date, usertype, COUNT(*) AS num_trips
FROM `bigquery-public-data.new_york.citibike_trips`
GROUP BY date, usertype
)
SELECT *
FROM
AI.FORECAST(
TABLE citibike_trips,
data_col => 'num_trips',
timestamp_col => 'date',
id_cols => ['usertype'],
horizon => 30);
The result is similar to the following:
+------------+-------------------------+----------------+------------------+---------------------------------+---------------------------------+--------------------+
| usertype | forecast_timestamp | forecast_value | confidence_level | prediction_interval_lower_bound | prediction_interval_upper_bound | ai_forecast_status |
+------------+-------------------------+----------------+------------------+---------------------------------+---------------------------------+--------------------+
| Subscriber | 2016-10-01 00:00:00 UTC | 21225.859375 | 0.95 | -3706.6855220930775 | 46158.404272093074 | |
| Subscriber | 2016-10-02 00:00:00 UTC | 25503.98046875 | 0.95 | 1723.3565528871222 | 49284.604384612874 | |
| ... | ... | ... | ... | ... | ... | ... |
+------------+-------------------------+----------------+------------------+---------------------------------+---------------------------------+--------------------+
Univariate forecasting with historical data output
The following example performs univariate forecasting to predict the daily
number of bike trips for each
different user type, the output_historical_time_series argument is set to
TRUE, so the output includes historical and forecasted data.
WITH
citibike_trips AS (
SELECT EXTRACT(DATE FROM starttime) AS date, usertype, COUNT(*) AS num_trips
FROM `bigquery-public-data.new_york.citibike_trips`
GROUP BY date, usertype
)
SELECT *
FROM
AI.FORECAST(
TABLE citibike_trips,
data_col => 'num_trips',
timestamp_col => 'date',
id_cols => ['usertype'],
horizon => 30,
output_historical_time_series => true);
The result is similar to the following:
+----------+------------------+-------------------------+------------------+------------------+---------------------------------+---------------------------------+--------------------+
| usertype | time_series_type | time_series_timestamp | time_series_data | confidence_level | prediction_interval_lower_bound | prediction_interval_upper_bound | ai_forecast_status |
+----------+------------------+-------------------------+------------------+------------------+---------------------------------+---------------------------------+--------------------+
| Customer | history | 2013-07-01 00:00:00 UTC | 2734.0 | null | null | null | null |
| Customer | history | 2013-07-02 00:00:00 UTC | 4070.0 | null | null | null | null |
| Customer | history | 2013-07-03 00:00:00 UTC | 4152.0 | null | null | null | null |
| Customer | history | 2013-07-04 00:00:00 UTC | 10773.0 | null | null | null | null |
| ... | ... | ... | ... | ... | ... | ... | ... |
| Customer | forecast | 2016-10-21 00:00:00 UTC | 3912.359375 | .95 | 862.76858192148256 | 6961.9501680785179 | null |
| Customer | forecast | 2016-10-22 00:00:00 UTC | 5978.39404296875 | .95 | 2670.9416601195244 | 9285.8464258179756 | null |
+----------+------------------+-------------------------+------------------+------------------+---------------------------------+---------------------------------+--------------------+
Multivariate forecasting
The following example performs multivariate forecasting to predict the daily number of bike trips and their average duration for the next 30 days:
WITH
citibike_trips AS (
SELECT EXTRACT(DATE FROM starttime) AS date, usertype, COUNT(*) AS num_trips, AVG(tripduration) AS avg_duration
FROM `bigquery-public-data.new_york.citibike_trips`
GROUP BY date, usertype
)
SELECT
FORMAT_DATE('%Y-%m-%d', date) AS date,
num_trips.value AS num_trips,
num_trips.prediction_interval_lower_bound AS trips_lb,
num_trips.prediction_interval_upper_bound AS trips_ub,
avg_duration.value AS avg_duration_forecast,
avg_duration.prediction_interval_lower_bound AS duration_lb,
avg_duration.prediction_interval_upper_bound AS duration_ub,
FROM
AI.FORECAST(
TABLE citibike_trips,
target_cols => ['num_trips', 'avg_duration'],
timestamp_col => 'date',
model => 'TimesFM 3.0',
horizon => 30);
The result is similar to the following, with values rounded for clarity. It includes the forecasted values for the next 30 days, as well as the lower and upper bounds for the prediction intervals:
+------------+-----------+----------+----------+-----------------------+-------------+-------------+
| date | num_trips | trips_lb | trips_ub | avg_duration_forecast | duration_lb | duration_ub |
+------------+-----------+----------+----------+-----------------------+-------------+-------------+
| 2016-10-01 | 17252 | 2792 | 25973 | 1243 | 1064 | 1511 |
| 2016-10-02 | 20303 | 7130 | 29752 | 1271 | 1081 | 1554 |
| ... | ... | ... | ... | ... | ... | ... |
+------------+-----------+----------+----------+-----------------------+-------------+-------------+
Multivariate forecasting with past and future covariates
The following example performs multivariate forecasting to predict daily bike trips for subscribers and unsubscribed (casual) users. The query uses the average trip duration as a past covariate because this value is not available for the future. The query uses whether the date is a weekend as a future covariate because the day of the week is known in advance.
WITH data AS (
SELECT
DATE(starttime) AS dt,
-- Set target columns to NULL for future dates to be forecasted.
IF(MIN(starttime) < '2016-06-01', COUNTIF(usertype = 'Subscriber'), NULL) AS subscriber_trips,
IF(MIN(starttime) < '2016-06-01', COUNTIF(usertype = 'Customer'), NULL) AS casual_trips,
-- Define the past covariate on historical dates and assign it to NULL for future dates.
IF(MIN(starttime) < '2016-06-01', AVG(tripduration / 60.0), NULL) AS avg_duration_min,
-- Define the future covariate on historical and future dates.
IF(EXTRACT(DAYOFWEEK FROM MIN(starttime)) IN (1, 7), 1.0, 0.0) AS is_weekend
FROM `bigquery-public-data.new_york.citibike_trips`
WHERE starttime >= '2016-01-01' AND starttime < '2016-06-08'
GROUP BY dt
)
SELECT
FORMAT_DATE('%Y-%m-%d', dt) AS trip_date,
subscriber_trips.value AS total_subscriber_trips,
casual_trips.value AS total_casual_trips
FROM
AI.FORECAST(
TABLE data,
MODEL => 'TimesFM 3.0',
TIMESTAMP_COL => 'dt',
TARGET_COLS => ['subscriber_trips', 'casual_trips'],
PAST_COVARIATE_COLS => ['avg_duration_min'],
FUTURE_COVARIATE_COLS => ['is_weekend']
);
The result is similar to the following, with values rounded for clarity. There is a significant increase in the number of forecasted casual trips on June 4 and June 5, which are weekend days.
+------------+------------------------+--------------------+
| trip_date | total_subscriber_trips | total_casual_trips |
+------------+------------------------+--------------------+
| 2016-06-01 | 44699 | 4581 |
| 2016-06-02 | 44611 | 4647 |
| 2016-06-03 | 41379 | 5341 |
| 2016-06-04 | 30164 | 9097 |
| 2016-06-05 | 26727 | 8398 |
| 2016-06-06 | 36713 | 4723 |
| 2016-06-07 | 39749 | 4180 |
+------------+------------------------+--------------------+
Locations
AI.FORECAST and the TimesFM model are available in all
supported BigQuery ML locations.
Pricing
AI.FORECAST usage is billed at the evaluation, inspection, and prediction
rate documented in the BigQuery ML on-demand pricing section
of the BigQuery ML pricing page.
During Preview, usage of TimesFM 3.0 in BigQuery is billed in
the following ways:
- If you use Enterprise or Enterprise Plus edition, then your usage is billed in slots.
- If you use on-demand pricing, then your usage is billed based on the number of bytes processed.
TimesFM 3.0 will use a token based pricing from 12/01/2026
onwards. At that time, you will be charged for tokens consumed by the
model in your query and BigQuery slots used or bytes processed
for the rest of the query.
What's next
- Learn how to forecast single or multiple time series with a TimesFM univariate model.
- Learn how to forecast single time series with a TimesFM multivariate model.
- Learn how to forecast multiple time series with a TimesFM multivariate model.
- Evaluate forecasting results from the TimesFM model using the
AI.EVALUATEfunction. - For information about forecasting in BigQuery ML, see Forecasting overview.
- For more information about supported SQL statements and functions for time series forecasting models, see End-to-end user journeys for time series forecasting models.