Forecast analysis
Latest Dynatrace
Powered by Grail
The forecast analysis predicts future values of any time series of numeric values. The forecast analyzer is not limited to stored metric data—you can bring your own data, use a metric query, or run a data query that results in a time series of numeric values.
The analysis is agnostic to the distribution of the input data. The forecast is calculated without any assumption about specific data distribution and works for both symmetric and nonsymmetric distributions.
Analyzer input
Parameter  Description 

Time series  Input time series serving as the base for the prediction analysis. It must include at least 14 data points. If fewer than 14 data points are available, the forecast fails. 
Number of simulated paths  The number of paths (nPath) simulated by the sampling forecaster. The more paths that are simulated, the more accurate the forecast and the longer it takes to calculate. The default value is 
Forecast horizon  The number of data points to be predicted. The more data points that are predicted, the less accurate the forecast is. The default value is 
Coverage probability  The coverage probability targeted by the forecaster, which translates to the following quantiles:
where For example, if the coverage probability is The default value is 
Analysis methodology
When you trigger a forecast analysis, the time series is sent to an appropriate forecaster that produces the forecast. Then the forecast quality is evaluated, and the forecast and evaluation are returned as analysis results.
The analysis uses one of the two forecasters:
The sampling forecaster is used if the variance of the linear history timeframe is larger than the maximum value of the 0.1
and 0.001 × input time series variance
pair. The linear history timeframe is the X most recent data points, with X being in the range from 14
to 20
.
In any other case (including the case when training of the sampling forecaster fails), the linear extrapolation forecaster is used.
Sampling forecaster
The sampling forecaster provides multistep forecasts based on seasonal patterns. Its architecture is shown in the image below.
First, the path transformer is applied to the input time series, and then the forecaster is trained on it. If the resulting model is invalid, the linear extrapolation forecaster is used instead. If the model is valid, sampling paths are created by the seasonal forecaster. Those paths are then inverse transformed before applying the quantiles on each time step.
Seasonal patterns
The forecaster always looks for various seasonal patterns in the input time series. The input time series must contain enough data to detect seasonality reliably.
Seasonal pattern  Required time series duration 

1 hour  2+ hours 
1 day (24 hours)  7+ days 
1 week (7 days)  14+ days 
Day of week  7+ days 
Time of day  2+ days 
Minute of hour  2+ hours 
Apart from those natural patterns, the forecaster looks for any repetitive patterns in the time series by breaking them based on a certain time window.
Forecast stepbystep

The seasonal forecaster estimates quartiles of the time series distribution at the time stamp of the next data point.

The distribution for the value at the next time step is estimated from the quartiles. The bell curve in the image is for illustrative purposes and doesn't represent the distribution used in the sampling forecaster.

The value for the next time step is sampled from the distribution obtained in step 2.

The value obtained in step 3 is now considered a part of the time series, and the forecaster repeats steps 1 to 4 until it reaches the forecast horizon.

The predicted data points form a single sampling path (shown in red in the image below).

The forecaster repeats this process N times, creating multiple sampling paths.

The forecaster takes the soughtafter quantile at each time step, forming the prediction interval (shown in light purple in the image below).
Linear extrapolation forecaster
The linear extrapolation forecaster is an algorithm that uses simple linear regression to find the bestfitting line through the last 14 to 20 data points and extend this line into the future. The number of data points used to train the forecaster is determined as nHistory = min(20, max(14, n))
, where n
is the length of the input time series. That is, at least 14 data points of input time series are needed to train the linear forecaster.
For the sake of simplicity, we calculate the confidence interval under the assumption that the residuals are normally distributed as follows:
where t_{crit} is the 95^{th} percentile of the Student's tdistribution. The standard error is
where X̅
is the mean value of x, the sums taken over the training data, and s
is the sample standard error of the last nHistory
points of the input time series.
Forecast quality assessment
After the predictions are generated, we assess their quality to spot potential numerical problems. To assess the forecast quality, the analyzer compares the standard deviation of the prediction to the standard deviation of the input time series (SD_{input}).
The standard deviation of the predictions (SD_{prediction}) is calculated as the maximum standard deviation of the lower and upper bounds of the prediction interval as well as the standard deviation of the point prediction.
To account for acceptable trends in the predictions, the analyzer uses a scaling factor (SCF). When the length of the prediction data (N_{prediction}) is large compared to the input time series (N_{input}), we allow a larger standard deviation of the prediction than for a small prediction.
Additional input into the scale factor is the Standard deviation factor (SD_{factor}), with a default value of 100
. The scale factor is calculated as follows:
The forecast is evaluated by the following condition:
If the condition is satisfied, the forecast is assessed as valid. Otherwise, the forecast is invalid.
Start forecast analysis
You can trigger a forecast analysis from your notebook.

Navigate to the required notebook or create a new one.

If needed, create a visualization of data.

Hover over the required time series in the sidebar and select > Filter and forecast.

Davis calculates the forecast and shows it, extending your visualization.
Write DQL queries for forecasting
When using the forecast analysis in one of your notebooks, you can write any DQL query that returns time series data in either the time series record format or the single value format.
If the data does not comply with one of the above formats, the forecast analysis fails.
 Every numerical value in a data array must have at least one decimal point (for example,
1.0
).
Example queries
The example DQL queries below yield valid responses.

The
timeseries
DQL command always returns a response in the time series record format. 
You can also write queries using the
fetch
command together with thesummarize
command. Those queries will return data in the single value format. All records must have the same distance (interval) between them. This is guaranteed when using thesummarize
command, as it will aggregate and group values for the defined time bins. Every record needs to have a field namedvalue
of type double (see Single value format for more info).
DQL timeseries command
The DQL timeseries
command returns a result in the time series record format.
1timeseries avg(dt.cloud.aws.rds.cpu.usage)
1timeseries avg(dt.host.cpu.usage), interval: 1h, by: {dt.entity.host}, from: 3d
1timeseries avg(dt.host.disk.used), interval: 15m, by: {dt.entity.disk}, from: now()2d, to: now()
DQL fetch and summarize query
A DQL query using fetch
and summarize
commands returns a result in the single value format.
1fetch logs2 summarize value = count(), by: {timestamp = bin(timestamp, 1m)}
1fetch events, from: 3d2 filter event.kind == "DAVIS_PROBLEM"3 summarize count(), by:{bin(timestamp, 1h), alias: timestamp}4 fieldsRename value=`count()`
DQL data command
You can use the DQL data
command to generate a forecast for your own data. Any data can be used, as long as it conforms to one of the two formats.
The following DQL data
command returns a result in the time series record format.
1data record(2 timeframe=timeframe(from: "20230310T00:00:00.000Z", to: "20230320T00:00:00.000Z"),3 interval=duration(1, "h"),4 `dt.entity.disk`="DISKA",5 data=array(6 0.6096, 1.1460, 1.2770, 2.3939, 2.2370, 2.6167, 1.2414,7 3.0011, 2.6842, 2.2949, 1.4132, 1.7749, 1.6472, 0.5800,8 0.2937, 0.8003, 0.0277, 0.4114, 0.6020, 0.5019, 0.2261,9 0.9875, 0.9601, 1.7021, 2.7538, 3.2475, 3.4133, 3.6173,10 4.2067, 4.8679, 4.4176, 4.7181, 5.1461, 5.0898, 4.9806,11 3.7390, 3.3774, 2.4088, 2.6754, 2.7673, 1.7551, 1.9633,12 1.5918, 2.4702, 2.5765, 2.8267, 3.4773, 3.8841, 5.4904,13 5.6528, 5.6221, 7.0052, 6.7039, 8.8618, 7.2853, 7.5175,14 7.2200, 7.5092, 7.2807, 6.3166, 6.4115, 5.1241, 5.2359,15 5.6137, 4.5477, 5.2841, 4.8689, 6.1404, 4.3398, 4.7527,16 5.6016, 6.7526, 7.0054, 8.4009, 7.3848, 9.0195, 9.6028,17 10.0891, 10.3137, 9.9700, 8.9944, 9.4415, 9.4228, 8.1233,18 8.5862, 8.4357, 8.0413, 7.1731, 6.9146, 6.6773, 6.7132,19 7.0178, 7.4880, 7.1100, 9.5785, 8.6518, 9.2125, 10.2238,20 11.4487, 11.1977, 11.3190, 12.5375, 11.9569, 12.4308, 11.7920,21 12.6200, 12.0601, 10.5243, 11.3639, 9.8979, 10.9811, 10.1095,22 10.2067, 9.6794, 9.8522, 9.0232, 9.5124, 10.5887, 11.0222,23 10.8741, 12.0817, 13.3625, 13.1324, 13.5550, 13.7834, 14.1806,24 15.5751, 14.7827, 13.9171, 14.5871, 14.5652, 13.4159, 13.6262,25 12.3931, 11.9045, 12.2807, 10.9243, 12.5514, 11.0550, 12.1066,26 12.1569, 12.9026, 12.9851, 13.5527, 14.9463, 14.5251, 15.6653,27 17.1333, 17.5200, 17.4643, 17.3053, 16.9866, 16.6806, 16.4379,28 16.2866, 16.9108, 15.3212, 15.4509, 14.5511, 14.8598, 15.4171,29 14.2590, 14.5359, 14.4026, 15.5683, 14.8414, 15.5065, 15.7033,30 17.1206, 17.4528, 17.5131, 19.2782, 18.6581, 20.6962, 20.4152,31 18.5865, 19.3483, 18.8283, 18.9540, 17.4941, 17.8047, 18.7973,32 17.1900, 16.1135, 17.0345, 17.1779, 16.6910, 16.8454, 16.9357,33 17.3166, 17.9157, 18.8126, 18.8176, 19.9470, 20.5230, 21.2858,34 22.2686, 22.2769, 21.1908, 21.8713, 21.2280, 20.8140, 21.7997,35 20.5656, 20.2129, 20.1171, 19.6284, 18.9140, 18.8314, 19.1833,36 18.4992, 19.0013, 20.0113, 20.4361, 20.2264, 21.7505, 22.0324,37 22.7636, 22.3307, 24.1297, 24.1968, 24.0366, 23.8212, 24.5346,38 24.2898, 24.0449, 23.8067, 22.9443, 23.3615, 22.5078, 22.1239,39 21.9639, 21.9736, 21.8018, 21.5930, 21.5247, 21.7674, 22.7781,40 23.6532, 23.176941 )42)
Time series record format
In the time series record format, time series are defined as simple double arrays.
There can be multiple arrays per record entry and multiple separate record entries.
A valid time series response contains only time series records.
A time series record must contain:
 Exactly one field of type timeframe that contains a start and end timestamp
 Exactly one field of type duration
 One or more fields of type
array
that contain only double or long values and null All numeric arrays must have as many values as there are time steps of width duration between the start and end of the timeframe
(endstart)/duration
 All numeric arrays must have as many values as there are time steps of width duration between the start and end of the timeframe
Fields in a time series record other than the timeframe, duration, and numeric data arrays are considered to be dimensions
The following JSON describes the structure of the record format.
 The types of the record fields are specified in the
types
section.  The actual value of a field of type duration is given in nanoseconds.
1{2 "records": [3 {4 "timeframe": {5 "start": "20230101T00:00Z",6 "end": "20230101T00:05Z"7 },8 "firstTimeSeries": [1.0, 3.0, 5.0, 7.0, 9.0],9 "secondTimeSeries": [0.0, 2.0, 4.0, 6.0, 8.0],10 "interval": "60000000000",11 "dt.metricKey": "host.cpu.usage"12 }13 ],14 "types": [15 {16 "indexRange": [0, 0],17 "mappings": {18 "dt.entity.host": { "type": "string" },19 "dt.metricKey": { "type": "string" },20 "timeframe": { "type": "timeframe" },21 "interval": { "type": "duration" },22 "firstTimeSeries": {23 "type": "array",24 "types": [25 {26 "indexRange": [0, 4],27 "mappings": {28 "element": { "type": "double" }29 }30 }31 ]32 },33 "secondTimeSeries": {34 "type": "array",35 "types": [36 {37 "indexRange": [0, 4],38 "mappings": {39 "element": { "type": "double" }40 }41 }42 ]43 }44 }45 }46 ]47}
Single value format
In the single value format, each record entry specifies a single value in the time series. Exactly one numeric field is allowed per record.
A record in a valid single value format response must contain:
Interval
The smallest allowed interval (time difference between two records) is one minute.
 An interval can be specified by adding a field
interval
of type duration.  This field can be named
frequency
as well, althoughinterval
takes precedence if both are specified.  If
interval
/frequency
is set, it must have the same value in each entry.
Dimensions
Dimensions can be added as additional properties.
Additional properties can have only string values.
A series is defined based on the distinct values for each dimension. Record entries with the same dimensions (string properties) are considered to belong to the same time series.
The following JSON describes the structure of the single value format.
 The types of the record fields are specified in the
types
section.  The actual value of a field of type duration is given in nanoseconds.
1{2 "records": [3 {4 "timestamp": "20190514T08:01Z",5 "interval": "60000000000",6 "dt.metricKey": "host.cpu.usage",7 "value": 0.08 },9 {10 "timestamp": "20190514T08:02Z",11 "interval": "60000000000",12 "dt.metricKey": "host.cpu.usage",13 "value": 2.014 },15 {16 "timestamp": "20200514T08:03Z",17 "interval": "60000000000",18 "dt.metricKey": "host.cpu.usage",19 "value": 4.020 }21 ],22 "types": [23 {24 "indexRange": [0, 2],25 "typeMappings": {26 "timestamp": { "type": "timestamp" },27 "interval": { "type": "duration" },28 "dt.metricKey": { "type": "string" },29 "value": { "type": "double" }30 }31 }32 ]33}
1{2 "records": [3 {4 "timeframe": {5 "start": "20191209T12:00Z",6 "end": "20191209T13:00Z"7 },8 "interval": "3600000000000",9 "dt.metricKey": "host.cpu.usage",10 "dt.entity.host": "HOSTA",11 "value": 0.012 },13 {14 "timeframe": {15 "start": "20191209T13:00Z",16 "end": "20191209T14:00Z"17 },18 "interval": "3600000000000",19 "dt.metricKey": "host.cpu.usage",20 "dt.entity.host": "HOSTA",21 "value": 2.022 }23 ],24 "types": [25 {26 "indexRange": [0, 2],27 "typeMappings": {28 "timeframe": { "type": "timeframe" },29 "interval": { "type": "duration" },30 "dt.metricKey": { "type": "string" },31 "dt.entity.host": { "type": "string" },32 "value": { "type": "double" }33 }34 }35 ]36}
Example forecasts
The quality of the forecast depends on the quality of data you're feeding to the analyzer and the width of the timeframe you want to predict. The best results are derived for a short timeframe from data without noise and with clear seasonal patterns. Here are some examples of forecasts for various types of data.
This example shows the forecast for an available disk metric. There's no seasonal pattern in the data, and there's a downward trend. Here, the linear extrapolation forecaster is used, producing a wide forecasted interval.
This example shows the forecast for a 1.5hour timeframe. Notice that the forecasted interval is not smooth, reflecting the noise in input data.
This example shows the forecast for a 6hours timeframe. Apart from an extensive forecast timeframe, the data itself has some noise and a downward trend that affect forecast quality—the forecasted interval widens more and more as it goes into the future.