diff --git a/apps/routerconsole/java/src/net/i2p/router/web/StatSummarizer.java b/apps/routerconsole/java/src/net/i2p/router/web/StatSummarizer.java
index 7ee8b069d4852dfff4d98fc2f6524354ef516c47..7f39f04f8aa2f315bb10b1454bb81ead2b53b959 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/StatSummarizer.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/StatSummarizer.java
@@ -264,9 +264,8 @@ public class StatSummarizer implements Runnable {
             height = GraphHelper.MAX_Y;
         else if (height <= 0)
             height = GraphHelper.DEFAULT_Y;
-        if (periodCount <= 0) periodCount = SummaryListener.PERIODS;
-        if (periodCount > SummaryListener.PERIODS)
-            periodCount = SummaryListener.PERIODS;
+        if (periodCount <= 0 || periodCount > txLsnr.getRows())
+            periodCount = txLsnr.getRows();
         long period = 60*1000;
         long start = end - period*periodCount;
         //long begin = System.currentTimeMillis();
@@ -284,16 +283,16 @@ public class StatSummarizer implements Runnable {
                 def.vrule(started / 1000, Color.BLACK, null, 4.0f);  // no room for legend
             String sendName = SummaryListener.createName(_context, "bw.sendRate.60000");
             String recvName = SummaryListener.createName(_context, "bw.recvRate.60000");
-            def.datasource(sendName, txLsnr.getData().getPath(), sendName, "AVERAGE", txLsnr.getBackendName());
-            def.datasource(recvName, rxLsnr.getData().getPath(), recvName, "AVERAGE", rxLsnr.getBackendName());
+            def.datasource(sendName, txLsnr.getData().getPath(), sendName, SummaryListener.CF, txLsnr.getBackendName());
+            def.datasource(recvName, rxLsnr.getData().getPath(), recvName, SummaryListener.CF, rxLsnr.getBackendName());
             def.area(sendName, Color.BLUE, _("Outbound Bytes/sec"));
             //def.line(sendName, Color.BLUE, "Outbound bytes/sec", 3);
             def.line(recvName, Color.RED, _("Inbound Bytes/sec") + "\\r", 3);
             //def.area(recvName, Color.RED, "Inbound bytes/sec@r");
             if (!hideLegend) {
-                def.gprint(sendName, "AVERAGE", _("Out average") + ": %.2f %s" + _("Bps"));
+                def.gprint(sendName, SummaryListener.CF, _("Out average") + ": %.2f %s" + _("Bps"));
                 def.gprint(sendName, "MAX", ' ' + _("max") + ": %.2f %S" + _("Bps") + "\\r");
-                def.gprint(recvName, "AVERAGE", _("In average") + ": %.2f %S" + _("Bps"));
+                def.gprint(recvName, SummaryListener.CF, _("In average") + ": %.2f %S" + _("Bps"));
                 def.gprint(recvName, "MAX", ' ' + _("max") + ": %.2f %S" + _("Bps") + "\\r");
             }
             if (!showCredit)
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryListener.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryListener.java
index f338e684811d51997fb563bb1fd5c8c6f160a059..c66c2fbccfdafcad11bc8e9c7b08ab664fa33b98 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryListener.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryListener.java
@@ -13,6 +13,7 @@ import net.i2p.util.Log;
 import net.i2p.util.SecureFile;
 import net.i2p.util.SecureFileOutputStream;
 
+import org.jrobin.core.Archive;
 import org.jrobin.core.RrdBackendFactory;
 import org.jrobin.core.RrdDb;
 import org.jrobin.core.RrdDef;
@@ -36,6 +37,9 @@ class SummaryListener implements RateSummaryListener {
     private static final String RRD_DIR = "rrd";
     private static final String RRD_PREFIX = "rrd-";
     private static final String RRD_SUFFIX = ".jrb";
+    static final String CF = "AVERAGE";
+    private static final double XFF = 0.9d;
+    private static final int STEPS = 1;
 
     private final I2PAppContext _context;
     private final Log _log;
@@ -47,8 +51,12 @@ class SummaryListener implements RateSummaryListener {
     private Sample _sample;
     private RrdMemoryBackendFactory _factory;
     private SummaryRenderer _renderer;
+    private int _rows;
     
-    static final int PERIODS = 1440;
+    static final int PERIODS = 60 * 24;  // 1440
+    private static final int MIN_ROWS = PERIODS;
+    private static final int MAX_ROWS = 91 * MIN_ROWS;
+    private static final long THREE_MONTHS = 91l * 24 * 60 * 60 * 1000;
     
     public SummaryListener(Rate r) {
         _context = I2PAppContext.getGlobalContext();
@@ -112,8 +120,12 @@ class SummaryListener implements RateSummaryListener {
                 rrdDefName = rrdFile.getAbsolutePath();
                 if (rrdFile.exists()) {
                     _db = new RrdDb(rrdDefName, factory);
+                    Archive arch = _db.getArchive(CF, STEPS);
+                    if (arch == null)
+                        throw new IOException("No average CF in " + rrdDefName);
+                    _rows = arch.getRows();
                     if (_log.shouldLog(Log.INFO))
-                        _log.info("Existing RRD " + baseName + " (" + rrdDefName + ") consuming " + _db.getRrdBackend().getLength() + " bytes");
+                        _log.info("Existing RRD " + baseName + " (" + rrdDefName + ") with " + _rows + " rows consuming " + _db.getRrdBackend().getLength() + " bytes");
                 } else {
                     rrdDir.mkdir();
                 }
@@ -128,15 +140,18 @@ class SummaryListener implements RateSummaryListener {
                 long heartbeat = period*10/1000;
                 def.addDatasource(_name, "GAUGE", heartbeat, Double.NaN, Double.NaN);
                 def.addDatasource(_eventName, "GAUGE", heartbeat, 0, Double.NaN);
-                double xff = 0.9;
                 int steps = 1;
-                int rows = PERIODS;
-                def.addArchive("AVERAGE", xff, steps, rows);
+                if (_isPersistent) {
+                    _rows = (int) Math.max(MIN_ROWS, Math.min(MAX_ROWS, THREE_MONTHS / period));
+                } else {
+                    _rows = MIN_ROWS;
+                }
+                def.addArchive(CF, XFF, STEPS, _rows);
                 _db = new RrdDb(def, factory);
                 if (_isPersistent)
                     SecureFileOutputStream.setPerms(new File(rrdDefName));
                 if (_log.shouldLog(Log.INFO))
-                    _log.info("New RRD " + baseName + " (" + rrdDefName + ") consuming " + _db.getRrdBackend().getLength() + " bytes");
+                    _log.info("New RRD " + baseName + " (" + rrdDefName + ") with " + _rows + " rows consuming " + _db.getRrdBackend().getLength() + " bytes");
             }
             _sample = _db.createSample();
             _renderer = new SummaryRenderer(_context, this);
@@ -184,6 +199,11 @@ class SummaryListener implements RateSummaryListener {
         return _isPersistent ? RrdNioBackendFactory.NAME : RrdMemoryBackendFactory.NAME;
     }
 
+    /** @since 0.8.6 */
+    int getRows() {
+        return _rows;
+    }
+
     @Override
     public boolean equals(Object obj) {
         return ((obj instanceof SummaryListener) && ((SummaryListener)obj)._rate.equals(_rate));
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryRenderer.java
index 37d41719e936f25a3ffb96503d905f3df61b6cf9..46bd66292030081a2759cfcecebc1c1c3d7a18b6 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryRenderer.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryRenderer.java
@@ -85,9 +85,8 @@ class SummaryRenderer {
 
     public void render(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, boolean showCredit) throws IOException {
         long end = _listener.now() - 60*1000;
-        if (periodCount <= 0) periodCount = SummaryListener.PERIODS;
-        if (periodCount > SummaryListener.PERIODS)
-            periodCount = SummaryListener.PERIODS;
+        if (periodCount <= 0 || periodCount > _listener.getRows())
+            periodCount = _listener.getRows();
         long start = end - _listener.getRate().getPeriod()*periodCount;
         //long begin = System.currentTimeMillis();
         try {
@@ -134,10 +133,10 @@ class SummaryRenderer {
             long started = ((RouterContext)_context).router().getWhenStarted();
             if (started > start && started < end)
                 def.vrule(started / 1000, Color.BLACK, _("Restart"), 4.0f);
-            def.datasource(plotName, path, plotName, "AVERAGE", _listener.getBackendName());
+            def.datasource(plotName, path, plotName, SummaryListener.CF, _listener.getBackendName());
             def.area(plotName, Color.BLUE, descr + "\\r");
             if (!hideLegend) {
-                def.gprint(plotName, "AVERAGE", _("avg") + ": %.2f %s");
+                def.gprint(plotName, SummaryListener.CF, _("avg") + ": %.2f %s");
                 def.gprint(plotName, "MAX", ' ' + _("max") + ": %.2f %S");
                 def.gprint(plotName, "LAST", ' ' + _("now") + ": %.2f %S\\r");
             }