{
    "content": [
        {
            "type": "text",
            "text": "# rrd_pdpcalc(1) (man)\n\n**Summary:** PDP calculation explanation - PDP inner calculation logics with an example by Tianpeng Xia\n\n## Section Outline\n\n- **NAME** (2 lines)\n- **DESCRIPTION** (3 lines) — 8 subsections\n  - Refreshing some basics about PDP (1 lines)\n  - Fundamental knowledge (28 lines)\n  - Calculation logics (34 lines)\n  - Bogaerdt version (24 lines)\n  - The official version( also @oetiker version): (8 lines)\n  - A Comparison and some explanation (31 lines)\n  - An example (14 lines)\n  - Focus on single steps (39 lines)\n- **SUMMARY** (3 lines) — 1 subsections\n  - Other References (8 lines)\n\n## Full Content\n\n### NAME\n\nPDP calculation explanation - PDP inner calculation logics with an example by Tianpeng Xia\n\n### DESCRIPTION\n\nThis article explains how PDP are calculated in a detailed yet easy-to-understand way, with\nan example.\n\n#### Refreshing some basics about PDP\n\n#### Fundamental knowledge\n\nIf you have not read the tutorials or man pages either on the official site or those by\nothers, then I strongly encourage you to do so.  As said in the description, this article\nwill only explain how a PDP is calculated, but not the definition of it.  So please read the\nfollowing materials to get a basic understanding of PDP:\n\n<http://rrdtool.vandenbogaerdt.nl/process.php> - By Alex van den Bogaerdt. This article\nexplained PDP in a very detailed and clear way, however, it does not explain the\n\"normalization process\" in its \"Normalize interval\" section in the right way( as opposed to\nthe official version I confirmed with @oetiker himself). The flaw can be easily seen in the\nbar charts, discussed in the \"Calculation logics\" section.\n\n<https://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html> - This one is on the official site.\nActually it's the manual page for \"rrdcreate\", and it reveals what's under the hood with\nregard to PDP calculation in its \"The HEARTBEAT and the STEP\" section.\n\nThe text graph by Don Baarda provides a vivid explanation on how UNKOWN data are produced and\nhow heartbeat value can influence in the sampling. Unfortunately, it fails to give a clear\nmethod by which PDPs are calculated.\n\n<https://oss.oetiker.ch/rrdtool/tut/rrdtutorial.en.html> - Another detailed official tutorial\nby Alex van den Bogaerdt. Similarly, it only provides examples with data evenly and exactly\ndistributed according to the step set.\n\nIf you don't like doing experiments or care about the inner mechanics that much, you can just\nstop here and give more attention to more practical topics like graph exports or command\nmanual. But if you are the sort of people like me who just care as much about the calculation\nlogics, please read on.\n\n#### Calculation logics\n\nHere begins the core part of this article. In the following content of this section, I would\nlike to give two versions of calculation methods, one by Alex van den Bogaerdt and the other\nby @eotiker.\n\nTo provide an ASCII-friendly explanation, I will explain both versions with the char below\ninstead of a real image.\n\n|\n|    (v1)\n|                         (v4)  (v5)\n| |     |           (v3)\n| |     |        |     ||   |\n| |     |        |            ||     ||   |\n| |     |        |            ||     ||   |\n| |     |   (v2) |            ||     ||   |\n| |     ||            ||     ||   |\n--------------------------------------------->\n0 1     3        7            17     20   21\n\nThe X axis means time slots( each second denotes one slot) and the Y axis means the value.\n\nLet's make everything a little clearer:\n\n- The step is 5\n\n- each PDP gets updated only if a value arrives at or after the last slot of the PDP, for\ninstance, the last slot of the PDP from 16 to 20 is 20\n\n- The heartbeat is 20, so the samples during the entire 7-17 period is not discarded\n\n- At second 3, the first value comes in as v1, and so on\n\n- Second 0 is the origin, and it does not count as a sample\n\n#### Bogaerdt version\n\nAs can be seen on this page: <http://rrdtool.vandenbogaerdt.nl/process.php>, after all the\nprimary data are transformed to rates( except for GAUGE, of course), they have to go through\na normalization process if they are not distributed exactly according to the step or on well-\ndefined boundaries in time, in the words of the author.\n\nWhat does that mean? Basically, if all the known (as opposed to an unknown value) data make\nup at least 50% of all slots during a period, then a PDP is calculated from them.\n\nThis version seems to go well until we reach the bar chart part.\n\nAccording to the ASCII bar chart, we have the following results:\n\nFrom second 1 on, the PDP of each period( 1-5,6-10, ...) is computed by averaging all the\nvalues within it.\n\nSo: - the PDP from 1 to 5 is (v1*3+v2*2)/5\n\n- the PDP from 6 to 10 is (v2*2+v3*3)/5\n\n- the PDP from 11 to 15 is (v3*5)/5, since all the values in slots 11, 12, 13, 14 and 15 are\nthe same, which is v3\n\n- ...\n\n#### The official version( also @oetiker version):\n\nUsing the same chart, this version suggests the following:\n\n- the PDP from 1 to 5 is (v1*3+v2*2)/5\n\n- the PDPs from 6 to 10 and 11 to 15 are the SAME, which is (v2*2+v3*8)\n\n- ...\n\n#### A Comparison and some explanation\n\nSo we have seen the above two versions and their PDPs from 6 to 10 and 11 to 15 do not comply\nwith each other.\n\nWhy is that?\n\nBecause the difference between the official version and Bogaerdt version stems from the way\nthey do the calculation for PDP(6-10) and PDP(11-15).\n\nLet's discuss this in more detail using the above bar chart.\n\nBogaerdt's version,\n\nPDPs are always computed individually no matter how values arrive.\n\nFor example, the value at slot 17 comes after the last slot of PDP(11-15). Also, the\nimmediate previous value before slot 17 is at 7. All the slots from 7 to 17 are assigned v3.\nSince each PDP is computed individually, PDP(6-10) is (v2*2+v3*3)/5 while the PDP(11-15) is\n(v3*5)/5.\n\nThe official version\n\nPDPs are always computed in terms of the steps which the next update spans, be it 1 step, 2\nsteps or n steps; in other words, PDPs may be computed together.\n\nFor example, the update at slot 17 spans PDP(6-10) and PDP(11-15) because the immediate\nprevious value is at 7 and 7 is within 6 and 10 , and 17 is after 15. PDP(1-5) and PDP(16-20)\nare not included since the update at slot 7 has already triggered the calculation for\nPDP(1-5) and the update at slot 17 comes before the last slot of PDP(16-20) which is 20.\n\nThat's the reason why PDP(6-10) and PDP(11-15) have the same value, (v2*2+v3*8).\n\n#### An example\n\nIf you are still confused, don't worry, an example is here to help you.\n\nLet's get our hands dirty with some commands\n\nrrdtool create target.rrd --start 1000000000  --step 5 DS:mem:GAUGE:20:0:100 RRA:AVERAGE:0.5:1:10\nrrdtool update target.rrd 1000000003:8 1000000006:1 1000000017:6 \\\n1000000020:7 1000000021:7 1000000022:4 \\\n1000000023:3 1000000036:1 1000000037:2 \\\n1000000038:3 1000000039:3 1000000042:5\nrrdtool fetch target.rrd AVERAGE --start 1000000000 --end 1000000045\n\nBasically, the above codes contain 3 commands: create, update and fetch. First create a new\nrrd file, and then we feed in some data and last we fetch all the PDPs from the rrd.\n\n#### Focus on single steps\n\nIn order to provide a detailed explanation, each the calculation process of each PDP is\nprovided.\n\nBelow is the output of the commands above:\n\n1000000005: 5.2000000000e+00\n1000000010: 5.5000000000e+00\n1000000015: 5.5000000000e+00\n1000000020: 6.6000000000e+00\n1000000025: 1.7333333333e+00\n1000000030: 1.7333333333e+00\n1000000035: 1.7333333333e+00\n1000000040: 2.8000000000e+00\n1000000045: nan\n1000000050: nan\n\nNOTE: 1000000005 means the PDP from 1000000001 to 1000000005, and so on. For concision and\nreadability, we use only the last two digits, so 05 denotes 1000000005. We choose the type of\nthe data source as gauge because original values will be treated as rates, no additional\ntransformation is needed, see this article <http://rrdtool.vandenbogaerdt.nl/process.php> for\ndetail.\n\n05: 5.2 = (8*3+1*2)/5\n\n10: 5.5 = (1*1+6*9)/10\n\n15: the same as the previous one\n\n20: 6.6 = (6*2+7*3)/5\n\n25: 1.73333 = (7+4+3+1*12)/15\n\n...\n\n45: nan, as the last value is at 42,which does not trigger the calculation for PDP(41-45)\n\n50: nan, why this unknown PDP is shown is explained in this article\n<https://oss.oetiker.ch/rrdtool/tut/rrdtutorial.en.html>\n\n### SUMMARY\n\nAll that said, I hope you get a clear understanding of the inner calculation \"magic\" for\nPDPs.\n\n#### Other References\n\n•   A great PowerShell shell script for generating ASCII bar charts:\n<https://gallery.technet.microsoft.com/scriptcenter/Sample-Script-to-Generate-59c80d4c>\n\n•   <https://stackoverflow.com/questions/18924450/rrd-wrong-values>\n\n\n\n1.7.2                                        2022-03-17                               RRDPDPCALC(1)\n\n"
        }
    ],
    "structuredContent": {
        "command": "rrd_pdpcalc",
        "section": "1",
        "mode": "man",
        "summary": "PDP calculation explanation - PDP inner calculation logics with an example by Tianpeng Xia",
        "synopsis": null,
        "flags": [],
        "examples": [],
        "see_also": [],
        "section_outline": [
            {
                "name": "NAME",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "DESCRIPTION",
                "lines": 3,
                "subsections": [
                    {
                        "name": "Refreshing some basics about PDP",
                        "lines": 1
                    },
                    {
                        "name": "Fundamental knowledge",
                        "lines": 28
                    },
                    {
                        "name": "Calculation logics",
                        "lines": 34
                    },
                    {
                        "name": "Bogaerdt version",
                        "lines": 24
                    },
                    {
                        "name": "The official version( also @oetiker version):",
                        "lines": 8
                    },
                    {
                        "name": "A Comparison and some explanation",
                        "lines": 31
                    },
                    {
                        "name": "An example",
                        "lines": 14
                    },
                    {
                        "name": "Focus on single steps",
                        "lines": 39
                    }
                ]
            },
            {
                "name": "SUMMARY",
                "lines": 3,
                "subsections": [
                    {
                        "name": "Other References",
                        "lines": 8
                    }
                ]
            }
        ]
    }
}