Opened 7 years ago

Last modified 4 years ago

#443 new enhancement

95th percentile graphs

Reported by: anarcat Owned by: janl
Priority: high Milestone: Munin 3.0.0
Component: design Version:
Severity: normal Keywords:
Cc: anarcat@…


It would be nice to have a line that would calculate the "95th percentile" which is often used in billing. A good explanation and the original MRTG patch is now unavailable except in the web archive:

The idea is to cut off 5% of the peaks and compute the average traffic based on that. It is a more faithful way of billing than just charging the average.

A more recent patch to MRTG is here:

Is this possible in Munin? Asking for 1.6...

Attachments (1)

go.patch (1.4 KB) - added by insom 4 years ago.
Patch against 1.4.3 to add 95th

Download all attachments as: .zip

Change History (12)

comment:1 Changed 7 years ago by janl

  • Severity changed from major to normal
  • Version 1.2.4 deleted

Shouldn't this be in rrd instead? To put it in munin would mean collecting the numbers into the rrd file and then writing a new rrd dataset from that --- and then graph the modified set?


comment:2 Changed 7 years ago by janl

Looks sort of simple

  1. tune the origin rrd file to save 5 minute samples for 30 days
  2. run the 95 script to generate a new rrd file to plot from

There are some reservations about how well this will work at

comment:3 Changed 7 years ago by janl

  • Milestone changed from Munin 1.6 to Munin 1.4
  • Owner changed from nobody to janl
  • Priority changed from normal to high

comment:4 in reply to: ↑ description Changed 6 years ago by mozai

For what it's worth, this Perl code will give you the N-th percentile for the sum of the fields in rrd file X. AFAIK, rrdtool doesn't calculate this number automatically; it's just a very popular feature of the many tools that use rrdtool for graphing.

use RRDs;

sub percentile($;$$) {
  my ($rrdfile,$duration,$n_th) = @_;
  # duration should be 1day, 1week, 1month or 1year.
  $duration ||= "1week";
  $n_th ||= 95; # can't have 0th percentile
  my ($start,$step,$names,$data) = RRDs::fetch($rrdfile,"MAX","-s","-$duration");
  my @sums = ();
  my $timestamp = $start;
  ROWLOOP: foreach my $row (@$data) {
    my $sum = 0;
    $timestamp += $step;
    foreach my $field (@$row) {
      next ROWLOOP if (! defined $field); # skip rows that have NaN
      $sum += $field;
  my $which = int(scalar(@sums)*($n_th)/100);
  @sums = sort{$a<=>$b}(@sums);  # sort defaults to alpha sorting of int? wtf?
  #debug# for (my $i=0; $i<=$#sums; $i++) {print"$sums[$i]".($i==$which?'<--':'')."\n"; }
  return $sums[$which];

# -- main()

my $nth = 95;
$rrdfile = '/var/www/html/cacti/rra/access_switch_c2950243_traffic_in_404.rrd';

print $nth."th percentile: ".&percentile($rrdfile,"1week",$nth) ."\n";
print "Consulting the last week's traffic on c2950-24-3\n";
print "(using rrd file $rrdfile)\n";

comment:5 Changed 5 years ago by TTimo


is this still being worked on?

comment:6 Changed 5 years ago by TTimo

The script provided on the ticket very likely works, I believe it's only approximate unless there is a RRA with 5 minute data and the script is modified to hit exactly only that data for the percentile computation. It is good enough for most cases.

However there is nothing setup for a plugin writer to request nth percentile on any of the data and have it drawn on the graph?

comment:7 Changed 5 years ago by janl

Looks like making such a line is supported in rrd as examplified some way down in As my munins are down due to me moving house I need to generate some rrd files to experiment with

comment:8 Changed 4 years ago by janl

  • Milestone changed from Munin 1.4 to Munin 1.5

This will not make it into 1.4

comment:9 Changed 4 years ago by janl

And we need to rewrite munin-graph before attempting this. 1.5 or 1.6.

comment:10 Changed 4 years ago by janl

  • Milestone changed from Munin 1.5 to Munin 1.6

Changed 4 years ago by insom

Patch against 1.4.3 to add 95th

comment:11 Changed 4 years ago by insom

I've attached a patch which uses VDEFs in rrdtool 1.2 to put a 95th marker on graphs. It's rough- it applies to the positive side of any single value graph. This is kind of useful, but more options and a graceful way to handle VDEFs would be better. This suits our needs, I thought I would share.

Note: See TracTickets for help on using tickets.