_R_R_D_G_R_A_P_H___R_P_N(1)                      rrdtool                     _R_R_D_G_R_A_P_H___R_P_N(1)

NNAAMMEE
     rrdgraph_rpn - About RPN Math in rrdtool graph

SSYYNNOOPPSSIISS
     _R_P_N _e_x_p_r_e_s_s_i_o_n:=_v_n_a_m_e|_o_p_e_r_a_t_o_r|_v_a_l_u_e[,_R_P_N _e_x_p_r_e_s_s_i_o_n]

DDEESSCCRRIIPPTTIIOONN
     If you have ever used a traditional HP calculator you already know RRPPNN (Re‐
     verse  Polish  Notation).  The idea behind RRPPNN is that you have a stack and
     push your data onto this stack. Whenever you execute an operation, it takes
     as many elements from the stack as needed. Pushing is done  implicitly,  so
     whenever  you specify a number or a variable, it gets pushed onto the stack
     automatically.

     At the end of the calculation there should be one and only one  value  left
     on  the stack.  This is the outcome of the function and this is what is put
     into the _v_n_a_m_e.  For CCDDEEFF instructions, the stack  is  processed  for  each
     data  point  on  the graph. VVDDEEFF instructions work on an entire data set in
     one run. Note, that currently VVDDEEFF instructions only support a limited list
     of functions.

     Example: "VDEF:maximum=mydata,MAXIMUM"

     This will set variable "maximum" which you now can use in the rest of  your
     RRD script.

     Example: "CDEF:mydatabits=mydata,8,*"

     This  means:  push variable _m_y_d_a_t_a, push the number 8, execute the operator
     _*. The operator needs two elements and uses  those  to  return  one  value.
     This value is then stored in _m_y_d_a_t_a_b_i_t_s.  As you may have guessed, this in‐
     struction  means nothing more than _m_y_d_a_t_a_b_i_t_s _= _m_y_d_a_t_a _* _8.  The real power
     of RRPPNN lies in the fact that it is always clear in which order  to  process
     the  input.   For  expressions  like "a = b + 3 * 5" you need to multiply 3
     with 5 first before you add _b to get _a. However, with parentheses you could
     change this order: "a = (b + 3) * 5". In RRPPNN, you would do "a = b, 3, +, 5,
     *" without the need for parentheses.

OOPPEERRAATTOORRSS
     Boolean operators
         LLTT,, LLEE,, GGTT,, GGEE,, EEQQ,, NNEE

         Less than, Less or equal, Greater than, Greater or  equal,  Equal,  Not
         equal  all  pop  two  elements from the stack, compare them for the se‐
         lected condition and return 1 for true or 0 for false. Comparing an _u_n_‐
         _k_n_o_w_n or an _i_n_f_i_n_i_t_e value will result in _u_n_k_n_o_w_n  returned  ...  which
         will also be treated as false by the IIFF call.

         UUNN,, IISSIINNFF

         Pop one element from the stack, compare this to _u_n_k_n_o_w_n respectively to
         _p_o_s_i_t_i_v_e _o_r _n_e_g_a_t_i_v_e _i_n_f_i_n_i_t_y. Returns 1 for true or 0 for false.

         _c_o_n_d_i_t_i_o_n,_t_h_e_n,_e_l_s_e,IIFF

         Pops  three  elements  from the stack.  If the element popped last is 0
         (false), the value popped first is pushed back onto the  stack,  other‐
         wise  the  value  popped second is pushed back. This does, indeed, mean
         that any value other than 0 is considered to be true.

         Example: "A,B,C,IF" should be read as "if (A) then (B) else (C)"



     Comparing values
         MMIINN,, MMAAXX

         Pops two elements from the stack and returns the smaller or larger, re‐
         spectively.  Note that _i_n_f_i_n_i_t_e is larger than anything else.   If  one
         of  the  input numbers is _u_n_k_n_o_w_n then the result of the operation will
         be _u_n_k_n_o_w_n too.

         MMIINNNNAANN,, MMAAXXNNAANN

         NAN-safe version of MIN and MAX. If one of the input numbers is _u_n_k_n_o_w_n
         then the result of the operation will be the other one. If both are _u_n_‐
         _k_n_o_w_n, then the result of the operation is _u_n_k_n_o_w_n.

         _l_o_w_e_r_-_l_i_m_i_t,_u_p_p_e_r_-_l_i_m_i_t,LLIIMMIITT

         Pops two elements from the stack and uses them to define a range.  Then
         it pops another element and if it falls inside the range, it is  pushed
         back. If not, an _u_n_k_n_o_w_n is pushed.

         The  range  defined  includes the two boundaries (so: a number equal to
         one of the boundaries will be pushed back). If any of the three numbers
         involved is either _u_n_k_n_o_w_n or _i_n_f_i_n_i_t_e this function will always return
         an _u_n_k_n_o_w_n

         Example: "CDEF:a=alpha,0,100,LIMIT" will return  _u_n_k_n_o_w_n  if  alpha  is
         lower than 0 or if it is higher than 100.



     Arithmetics
         ++,, --,, **,, //,, %%

         Add, subtract, multiply, divide, modulo

         AADDDDNNAANN

         NAN-safe  addition. If one parameter is NAN/UNKNOWN it'll be treated as
         zero. If both parameters are NAN/UNKNOWN, NAN/UNKNOWN will be returned.

         _v_a_l_u_e,_p_o_w_e_r,PPOOWW

         Raise _v_a_l_u_e to the power of _p_o_w_e_r.

         SSIINN,, CCOOSS,, LLOOGG,, EEXXPP,, SSQQRRTT

         Sine and cosine (input in radians), log and  exp  (natural  logarithm),
         square root.

         AATTAANN

         Arctangent (output in radians).

         AATTAANN22

         Arctangent  of  y,x components (output in radians).  This pops one ele‐
         ment from the stack, the x (cosine) component, and then a second, which
         is the y (sine) component.  It then pushes the arctangent of their  ra‐
         tio, resolving the ambiguity between quadrants.

         Example:  "CDEF:angle=Y,X,ATAN2,RAD2DEG"  will convert "X,Y" components
         into an angle in degrees.

         FFLLOOOORR,, CCEEIILL

         Round down or up to the nearest integer.

         RROOUUNNDD

         Round to the nearest integer.

         DDEEGG22RRAADD,, RRAADD22DDEEGG

         Convert angle in degrees to radians, or radians to degrees.

         AABBSS

         Take the absolute value.

     Set Operations
         _c_o_u_n_t,SSOORRTT

         Pop one element from the stack.  This is  the  _c_o_u_n_t  of  items  to  be
         sorted.   The  top _c_o_u_n_t of the remaining elements are then sorted from
         the smallest to the largest, in place on the stack.

            4,3,22.1,1,4,SORT -> 1,3,4,22.1

         _c_o_u_n_t,RREEVV

         Reverse the number

         Example: "CDEF:x=v1,v2,v3,v4,v5,v6,6,SORT,POP,5,REV,POP,+,+,+,4,/" will
         compute the average of the values v1 to v6 after removing the  smallest
         and largest.

         _c_o_u_n_t,AAVVGG

         Pop  one  element  (_c_o_u_n_t)  from  the stack. Now pop _c_o_u_n_t elements and
         build the average, ignoring all UNKNOWN values in the process.

         Example: "CDEF:x=a,b,c,d,4,AVG"

         _c_o_u_n_t,SSMMIINN and _c_o_u_n_t,SSMMAAXX

         Pop one element (_c_o_u_n_t) from the stack. Now pop _c_o_u_n_t elements and push
         the minimum/maximum back onto the stack.

         Example: "CDEF:x=a,b,c,d,4,SMIN"

         _c_o_u_n_t,MMEEDDIIAANN

         pop one element (_c_o_u_n_t) from the stack. Now pop _c_o_u_n_t elements and find
         the median, ignoring all UNKNOWN values in the process. If there are an
         even number of non-UNKNOWN values, the average of the middle  two  will
         be pushed on the stack.

         Example: "CDEF:x=a,b,c,d,4,MEDIAN"

         _c_o_u_n_t,SSTTDDEEVV

         pop one element (_c_o_u_n_t) from the stack. Now pop _c_o_u_n_t elements and cal‐
         culate  the standard deviation over these values (ignoring any NAN val‐
         ues). Push the result back on to the stack.

         Example: "CDEF:x=a,b,c,d,4,STDEV"

         _p_e_r_c_e_n_t,_c_o_u_n_t,PPEERRCCEENNTT

         pop two elements (_c_o_u_n_t,_p_e_r_c_e_n_t) from the stack. Now pop _c_o_u_n_t element,
         order them by size (while the smallest elements are -INF,  the  largest
         are  INF  and  NaN  is larger than -INF but smaller than anything else.
         Pick the element from the ordered list where _p_e_r_c_e_n_t  of  the  elements
         are equal to the one picked. Push the result back on to the stack.

         Example: "CDEF:x=a,b,c,d,95,4,PERCENT"

         _c_o_u_n_t,TTRREENNDD,, TTRREENNDDNNAANN

         Create a "sliding window" average of another data series.

         Usage: CDEF:smoothed=x,1800,TREND

         This will create a half-hour (1800 second) sliding window average of x.
         The average is essentially computed as shown here:

                          +---!---!---!---!---!---!---!---!--->
                                                              now
                                delay     t0
                          <--------------->
                                  delay       t1
                              <--------------->
                                       delay      t2
                                  <--------------->


              Value at sample (t0) will be the average between (t0-delay) and (t0)
              Value at sample (t1) will be the average between (t1-delay) and (t1)
              Value at sample (t2) will be the average between (t2-delay) and (t2)

         TRENDNAN is - in contrast to TREND - NAN-safe. If you use TREND and one
         source value is NAN the complete sliding window is affected. The TREND‐
         NAN  operation  ignores all NAN-values in a sliding window and computes
         the average of the remaining values.

         PPRREEDDIICCTT,, PPRREEDDIICCTTSSIIGGMMAA,, PPRREEDDIICCTTPPEERRCC

         Create a "sliding window" average/sigma/percentil of another  data  se‐
         ries, that also shifts the data series by given amounts of time as well

         Usage  -  explicit  stating  shifts: "CDEF:predict=<shift n>,...,<shift
         1>,n,<window>,x,PREDICT"  "CDEF:sigma=<shift  n>,...,<shift  1>,n,<win‐
         dow>,x,PREDICTSIGMA"    "CDEF:perc=<shift    n>,...,<shift   1>,n,<win‐
         dow>,<percentil>,x,PREDICTPERC"

         Usage - shifts defined as a base shift and a number of time this is ap‐
         plied      "CDEF:predict=<shift      multiplier>,-n,<window>,x,PREDICT"
         "CDEF:sigma=<shift              multiplier>,-n,<window>,x,PREDICTSIGMA"
         "CDEF:sigma=<shift multiplier>,-n,<window>,<percentil>,x,PREDICTPERC"

         Example: CDEF:predict=172800,86400,2,1800,x,PREDICT

         This will create a half-hour (1800 second) sliding window average/sigma
         of x, that average is essentially computed as shown here:

          +---!---!---!---!---!---!---!---!---!---!---!---!---!---!---!---!---!--->
                                                                              now
                                                           shift 1        t0
                                                  <----------------------->
                                        window
                                  <--------------->
                                                shift 2
                          <----------------------------------------------->
                window
          <--------------->
                                                               shift 1        t1
                                                      <----------------------->
                                            window
                                      <--------------->
                                                     shift 2
                              <----------------------------------------------->
                    window
              <--------------->

          Value at sample (t0) will be the average between (t0-shift1-window) and (t0-shift1)
                                               and between (t0-shift2-window) and (t0-shift2)
          Value at sample (t1) will be the average between (t1-shift1-window) and (t1-shift1)
                                               and between (t1-shift2-window) and (t1-shift2)

         The function is by design NAN-safe.  This also allows for extrapolation
         into the future (say a few days) - you may need to define the data  se‐
         ries with the optional start= parameter, so that the source data series
         has  enough  data  to  provide  prediction  also  at the beginning of a
         graph...

         The percentile can be between [-100:+100].   The  positive  percentiles
         interpolates between values while the negative will take the closest.

         Example:  you run 7 shifts with a window of 1800 seconds. Assuming that
         the rrd-file has a step size of 300 seconds this means we  have  to  do
         the  percentile  calculation based on a max of 42 distinct values (less
         if you got NAN). that means that in the best case you get a  step  rate
         between  values of 2.4 percent.  so if you ask for the 99th percentile,
         then you would need to look at the 41.59th value. As we only have inte‐
         gers, either the 41st or the 42nd value.

         With the positive percentile a linear interpolation between the 2  val‐
         ues is done to get the effective value.

         The  negative returns the closest value distance wise - so in the above
         case 42nd value, which is effectively returning  the  Percentile100  or
         the max of the previous 7 days in the window.

         Here  an  example,  that will create a 10 day graph that also shows the
         prediction 3 days into the future with its uncertainty  value  (as  de‐
         fined by avg+-4*sigma) This also shows if the prediction is exceeded at
         a certain point.

             rrdtool graph image.png --imgformat=PNG \
             --start=-7days --end=+3days --width=1000 --height=200 --alt-autoscale-max \
             DEF:value=value.rrd:value:AVERAGE:start=-14days \
             LINE1:value#ff0000:value \
             CDEF:predict=86400,-7,1800,value,PREDICT \
             CDEF:sigma=86400,-7,1800,value,PREDICTSIGMA \
             CDEF:upper=predict,sigma,3,*,+ \
             CDEF:lower=predict,sigma,3,*,- \
             LINE1:predict#00ff00:prediction \
             LINE1:upper#0000ff:upper\ certainty\ limit \
             LINE1:lower#0000ff:lower\ certainty\ limit \
             CDEF:exceeds=value,UN,0,value,lower,upper,LIMIT,UN,IF \
             TICK:exceeds#aa000080:1 \
             CDEF:perc95=86400,-7,1800,95,value,PREDICTPERC \
             LINE1:perc95#ffff00:95th_percentile

         Note: Experience has shown that a factor between 3 and 5 to scale sigma
         is a good discriminator to detect abnormal behavior. This obviously de‐
         pends also on the type of data and how "noisy" the data series is.

         Also Note the explicit use of start= in the CDEF - this is necessary to
         load all the necessary data (even if it is not displayed)

         This  prediction can only be used for short term extrapolations - say a
         few days into the future.

     Special values
         UUNNKKNN

         Pushes an unknown value on the stack

         IINNFF,, NNEEGGIINNFF

         Pushes a positive or negative infinite value on the stack. When such  a
         value is graphed, it appears at the top or bottom of the graph, no mat‐
         ter what the actual value on the y-axis is.

         PPRREEVV

         Pushes  an  _u_n_k_n_o_w_n  value  if this is the first value of a data set or
         otherwise the result of this CCDDEEFF at the previous time step.  This  al‐
         lows  you  to do calculations across the data.  This function cannot be
         used in VVDDEEFF instructions.

         PPRREEVV((vvnnaammee))

         Pushes an _u_n_k_n_o_w_n value if this is the first value of  a  data  set  or
         otherwise  the  result of the vname variable at the previous time step.
         This allows you to do calculations across the data. This function  can‐
         not be used in VVDDEEFF instructions.

         CCOOUUNNTT

         Pushes  the  number  1  if this is the first value of the data set, the
         number 2 if it is the second, and so on. This special value allows  you
         to make calculations based on the position of the value within the data
         set. This function cannot be used in VVDDEEFF instructions.

     TimeTime  inside  RRDtool is measured in seconds since the epoch. The epoch
         is defined to be "Thu Jan  1 00:00:00 UTC 1970".

         NNOOWW

         Pushes the current time on the stack.

         SSTTEEPPWWIIDDTTHH

         The width of the current step in seconds. You can use this to  go  back
         from rate based presentations to absolute numbers

           CDEF:abs=rate,STEPWIDTH,*,PREV,ADDNAN

         NNEEWWDDAAYY,NNEEWWWWEEEEKK,NNEEWWMMOONNTTHH,NNEEWWYYEEAARR

         These  three  operators will return 1.0 whenever a step is the first of
         the given period. The periods are determined  according  to  the  local
         timezone AND the "LC_TIME" settings.

           CDEF:mtotal=rate,STEPWIDTH,*,NEWMONTH,0,PREV,IF,ADDNAN

         TTIIMMEE

         Pushes  the  time  the  currently processed value was taken at onto the
         stack.

         LLTTIIMMEE

         Takes the time as defined by TTIIMMEE, applies the time zone  offset  valid
         at that time including daylight saving time if your OS supports it, and
         pushes  the  result on the stack.  There is an elaborate example in the
         examples section below on how to use this.

     Processing the stack directly
         DDUUPP,, PPOOPP,, EEXXCC

         Duplicate the top element, remove the top element, exchange the two top
         elements.

         DDEEPPTTHH

         pushes the current depth of the stack onto the stack

          a,b,DEPTH -> a,b,2

         n,CCOOPPYY

         push a copy of the top n elements onto the stack

          a,b,c,d,2,COPY => a,b,c,d,c,d

         n,IINNDDEEXX

         push the nth element onto the stack.

          a,b,c,d,3,INDEX -> a,b,c,d,b

         n,m,RROOLLLL

         rotate the top n elements of the stack by m

          a,b,c,d,3,1,ROLL => a,d,b,c
          a,b,c,d,3,-1,ROLL => a,c,d,b



VVAARRIIAABBLLEESS
     These operators work only on VVDDEEFF  statements.  Note  that  currently  ONLY
     these work for VVDDEEFF.

     MAXIMUM, MINIMUM, AVERAGE
         Return  the  corresponding  value,  MAXIMUM and MINIMUM also return the
         first occurrence of that value in the time component.

         Example: "VDEF:avg=mydata,AVERAGE"

     STDEV
         Returns the standard deviation of the values.

         Example: "VDEF:stdev=mydata,STDEV"

     LAST, FIRST
         Return the last/first non-nan or infinite value for the  selected  data
         stream, including its timestamp.

         Example: "VDEF:first=mydata,FIRST"

     TOTAL
         Returns  the  rate from each defined time slot multiplied with the step
         size.  This can, for instance, return total bytes transferred when  you
         have  logged bytes per second. The time component returns the number of
         seconds.

         Example: "VDEF:total=mydata,TOTAL"

     PERCENT, PERCENTNAN
         This should follow a DDEEFF or CCDDEEFF _v_n_a_m_e. The _v_n_a_m_e  is  popped,  another
         number  is  popped which is a certain percentage (0..100). The data set
         is then sorted and the value returned is chosen  such  that  _p_e_r_c_e_n_t_a_g_e
         percent  of the values is lower or equal than the result.  For PERCENT‐
         NAN _U_n_k_n_o_w_n values are ignored, but for PERCENT _U_n_k_n_o_w_n values are con‐
         sidered lower than any finite number for this purpose so if this opera‐
         tor returns an _u_n_k_n_o_w_n you have quite a lot of them in your data.   IInn‐‐
         ffinite numbers are lesser, or more, than the finite numbers and are al‐
         ways more than the _U_n_k_n_o_w_n numbers.  (NaN < -INF < finite values < INF)

         Example: "VDEF:perc95=mydata,95,PERCENT"
                  "VDEF:percnan95=mydata,95,PERCENTNAN"

     LSLSLOPE, LSLINT, LSLCORREL
         Return  the  parameters  for a LLeast SSquares LLine _(_y _= _m_x _+_b_) which ap‐
         proximate the provided dataset.  LSLSLOPE is the slope _(_m_) of the  line
         related  to  the COUNT position of the data.  LSLINT is the y-intercept
         _(_b_), which happens also to be  the  first  data  point  on  the  graph.
         LSLCORREL  is the Correlation Coefficient (also know as Pearson's Prod‐
         uct Moment Correlation Coefficient).  It will range from 0 to +/-1  and
         represents the quality of fit for the approximation.

         Example: "VDEF:slope=mydata,LSLSLOPE"

SSEEEE AALLSSOO
     rrdgraph  gives  an overview of how rrrrddttooooll ggrraapphh works.  rrdgraph_data de‐
     scribes DDEEFF,CCDDEEFF and VVDDEEFF in detail.  rrdgraph_rpn describes the  RRPPNN  lan‐
     guage  used  in  the ??DDEEFF statements.  rrdgraph_graph page describes all of
     the graph and print functions.

     Make sure to read rrdgraph_examples for tips&tricks.

AAUUTTHHOORR
     Program by Tobias Oetiker <tobi@oetiker.ch>

     This manual page by Alex van  den  Bogaerdt  <alex@vandenbogaerdt.nl>  with
     corrections and/or additions by several people

1.10.0                             2026-05-23                    _R_R_D_G_R_A_P_H___R_P_N(1)
