Rate

The rate node is a bit complex with a number of flags and the following main features:

  • Turning a monotonically increasing counter into a rate (e.g. TSDB 1x and 2x metrics that mostly reported counters at a given timestamp)

  • Converting a stored rate back into a “count” over time.

  • Compute the first derivative.

  • Compute just the delta of values, ignoring time. (NOTE: We may push this into a separate node before a prod release).

Depending on the configuration of the node, the location in the execution graph should change.

Fields for the rate config include:

Name

Data Type

Required

Description

Default

Example

interval

String

Optional

A TSDB style duration to use when computing the rate. Defaults to per second.

1s

1m

counter

boolean

Optional

Whether or not the underlying series is a monotonically increasing counter and we should expect to handle resets.

false

true

dropResets

Boolean

Optional

Whether or not to drop values when resets occur and reset them to zero.

false

true

counterMax

Integer

Optional

The value at which we expect the counter to reset. The default is a 64 bit signed maximum integer value.

Long.MAX_VALUE

32000

resetValue

Integer

Optional

A value that, when exceeded, we reset to 0.

0

42

dataInterval

String

Optional

A TSDB style duration defining the expected reporting interval of the underlying data, used when converting a rate to a count via the rateToCount flag.

null

10s

rateToCount

Boolean

Optional

Whether or not to convert the rate to a count over the interval. For the best results, also set dataInterval.

false

true

deltaOnly

Boolean

Optional

Whether or not to compute only the delta between values instead of the derivative.

false

true

Counter To Rate

Some systems, such as network gear or previous OpenTSDB instances, report monotonically increasing counters over time. E.g. at T0, a metric may have a value of 5. At T1, it may become 10. At T2 it may stay at 10. The value will always stay the same or increase unless a reset occurs due to integer roll-over or a restart.

For this use case, the rate node should immediately follow the data source node so that other functions can work on the rate data. Also make sure to set the counter flag to true.

As an input example take:

Series

T0

T + 10s

T + 20s

T + 30s

TS1

1

3

3

6

TS2

1

2

N/A

4

The results with a configuration of interval=1s would be:

Series

T0

T + 10s

T + 20s

T + 30s

TS1

NaN

0.2

0

0.3

TS2

NaN

0.1

N/A

0.1

Note that the first value may be NaN’d if no previous value was found for the given query time span. The storage engine should try to pad and return an extra value before the first in order to calculate a proper rate but this may not always happen.

TODO - more docs on the counter flags from the old TSD docs.

{
    "start": "1h-ago",
    "executionGraph": [{
                    "id": "m1",
                    "type": "TimeSeriesDataSource",
                    "metric": {
                            "type": "MetricLiteral",
                            "metric": "sys.if.in"
                    }
            },
            {
                    "id": "rate1",
                    "type": "rate",
                    "interval": "1s",
                    "counter": true,
                    "dropResets": true,
                    "sources": ["m1"]
            },
            {
                    "id": "ds1",
                    "type": "downsample",
                    "aggregator": "sum",
                    "interval": "1m",
                    "runAll": false,
                    "fill": true,
                    "interpolatorConfigs": [{
                            "dataType": "numeric",
                            "fillPolicy": "NAN",
                            "realFillPolicy": "NONE"
                    }],
                    "sources": ["rate1"]
            }
    ]
}

Rate to Count

Similar to the counter to rate, the rate to count node should be the first node after the data source. This setting will take the recorded value and multiply it by a reporting interval to compute the “count” or number of operations per interval, converting a recorded rate back to a counter (albeit just the count for the interval, not a monotonically increasing count.)

The two important settings are the interval that reflects the interval of the rate stored and the dataInterval wherein you should set it to the reporting interval of the data source. E.g. if the source reports every 10 seconds, set the dataInterval to 10s or if the source comes in every minute, set it to 1m. If you leave the dataInterval empty and the time series has missing values, you may see artifically inflated counts as the TSD will compute the time delta from the preivous existing value to the current value and multiple bny the interval to compute the count.

As an example, assume the following values.

Series

T0

T + 10s

T + 20s

T + 30s

TS1

1

3

2

1

TS2

1

2

N/A

2

Lets assume interval=1s and dataInterval=10s. The results would be:

Series

T0

T + 10s

T + 20s

T + 30s

TS1

10

30

20

10

TS2

10

20

N/A

20

If dataInterval was not set, TS2 would have the following values:

Series

T0

T + 10s

T + 20s

T + 30s

TS2

10

20

N/A

40

The value at T + 30s would subtract the time from T + 10s to get a value of 20s then multiply that by the interval of 1s.

{
      "start": "1h-ago",
      "executionGraph": [{
                      "id": "m1",
                      "type": "TimeSeriesDataSource",
                      "metric": {
                              "type": "MetricLiteral",
                              "metric": "sys.if.in"
                      }
              },
              {
                      "id": "rate1",
                      "type": "rate",
                      "interval": "1s",
                      "counter": true,
                      "dropResets": true,
                      "sources": ["m1"]
              },
              {
                      "id": "ds1",
                      "type": "downsample",
                      "aggregator": "sum",
                      "interval": "1m",
                      "runAll": false,
                      "fill": true,
                      "interpolatorConfigs": [{
                              "dataType": "numeric",
                              "fillPolicy": "NAN",
                              "realFillPolicy": "NONE"
                      }],
                      "sources": ["rate1"]
              }
      ]
  }

First Derivative or Rate

If you aren’t dealing with a monotonically increasing counter and just want to view the rate of change of any metric, then the rate node can be used in any locating in the execution graph. Just leave out the counter and other flags.

For example with an interval=1s and an input of:

Series

T0

T + 10s

T + 20s

T + 30s

TS1

1

3

2

1

TS2

1

2

N/A

2

The results would be:

Series

T0

T + 10s

T + 20s

T + 30s

TS1

NaN

0.2

-0.1

-0.1

TS2

NaN

0.1

N/A

0

{
      "start": "1h-ago",
      "executionGraph": [{
                      "id": "m1",
                      "type": "TimeSeriesDataSource",
                      "metric": {
                              "type": "MetricLiteral",
                              "metric": "sys.if.in"
                      }
              },
              {
                      "id": "ds1",
                      "type": "downsample",
                      "aggregator": "sum",
                      "interval": "1m",
                      "runAll": false,
                      "fill": true,
                      "interpolatorConfigs": [{
                              "dataType": "numeric",
                              "fillPolicy": "NAN",
                              "realFillPolicy": "NONE"
                      }],
                      "sources": ["m1"]
              },
              {
                      "id": "rate1",
                      "type": "rate",
                      "interval": "10s",
                      "sources": ["ds1"]
              }
      ]
  }

Delta

For cases where you just want the difference between values, set the the deltaOnly flag to true nad all other flags to false. The interval can be ignored. For an example input:

Series

T0

T + 10s

T + 20s

T + 30s

TS1

1

3

2

1

TS2

1

2

N/A

2

The results would be:

Series

T0

T + 10s

T + 20s

T + 30s

TS1

NaN

2

-1

-1

TS2

NaN

1

N/A

0

{
      "start": "1h-ago",
      "executionGraph": [{
                      "id": "m1",
                      "type": "TimeSeriesDataSource",
                      "metric": {
                              "type": "MetricLiteral",
                              "metric": "sys.if.in"
                      }
              },
              {
                      "id": "ds1",
                      "type": "downsample",
                      "aggregator": "sum",
                      "interval": "1m",
                      "runAll": false,
                      "fill": true,
                      "interpolatorConfigs": [{
                              "dataType": "numeric",
                              "fillPolicy": "NAN",
                              "realFillPolicy": "NONE"
                      }],
                      "sources": ["m1"]
              },
              {
                      "id": "rate1",
                      "type": "rate",
                      "interval": "1s",
                      "deltaOnly": true,
                      "sources": ["ds1"]
              }
      ]
  }