diff --git a/core/java/src/net/i2p/util/LogManager.java b/core/java/src/net/i2p/util/LogManager.java
index 871037b65d5b5f72ce7f95c818b1e54f6509811d..85d948c5375f3d2b5a169a217689cd7ebda0479c 100644
--- a/core/java/src/net/i2p/util/LogManager.java
+++ b/core/java/src/net/i2p/util/LogManager.java
@@ -61,6 +61,8 @@ public class LogManager {
     private static final String PROP_DROP = "logger.dropOnOverflow";
     /** @since 0.9.3 */
     private static final String PROP_DUP = "logger.dropDuplicates";
+    /** @since 0.9.18 */
+    private static final String PROP_FLUSH = "logger.flushInterval";
     public final static String PROP_RECORD_PREFIX = "logger.record.";
 
     public final static String DEFAULT_FORMAT = DATE + " " + PRIORITY + " [" + THREAD + "] " + CLASS + ": " + MESSAGE;
@@ -125,6 +127,8 @@ public class LogManager {
     private boolean _dropOnOverflow;
     private boolean _dropDuplicates;
     private final AtomicLong _droppedRecords = new AtomicLong();
+    // in seconds
+    private int _flushInterval = (int) (LogWriter.FLUSH_INTERVAL / 1000);
     
     private boolean _alreadyNoticedMissingConfig;
 
@@ -160,6 +164,7 @@ public class LogManager {
         if (_writer != null)
             return;
         _writer = new LogWriter(this);
+        _writer.setFlushInterval(_flushInterval * 1000);
         // if you enable logging in I2PThread again, you MUST change this back to Thread
         Thread t = new I2PThread(_writer, "LogWriter");
         t.setDaemon(true);
@@ -269,6 +274,10 @@ public class LogManager {
             try {
                 _records.put(record);
             } catch (InterruptedException ie) {}
+        } else if (_flushInterval <= 0) {
+            synchronized (_writer) {
+                _writer.notifyAll();
+            }
         }
     }
     
@@ -384,6 +393,17 @@ public class LogManager {
                 _logBufferSize = Integer.parseInt(str);
         } catch (NumberFormatException nfe) {}
 
+        try {
+            String str = config.getProperty(PROP_FLUSH);
+            if (str != null) {
+                _flushInterval = Integer.parseInt(str);
+                synchronized(this) {
+                    if (_writer != null)
+                        _writer.setFlushInterval(_flushInterval * 1000);
+                }
+            }
+        } catch (NumberFormatException nfe) {}
+
         _dropOnOverflow = Boolean.parseBoolean(config.getProperty(PROP_DROP));
         String str = config.getProperty(PROP_DUP);
         _dropDuplicates = str == null || Boolean.parseBoolean(str);
@@ -647,6 +667,7 @@ public class LogManager {
         rv.setProperty(PROP_DEFAULTLEVEL, Log.toLevelString(_defaultLimit));
         rv.setProperty(PROP_DISPLAYONSCREENLEVEL, Log.toLevelString(_onScreenLimit));
         rv.setProperty(PROP_CONSOLEBUFFERSIZE, Integer.toString(_consoleBufferSize));
+        rv.setProperty(PROP_FLUSH, Integer.toString(_flushInterval));
 
         for (LogLimit lim : _limits) {
             rv.setProperty(PROP_RECORD_PREFIX + lim.getRootName(), Log.toLevelString(lim.getLimit()));
diff --git a/core/java/src/net/i2p/util/LogWriter.java b/core/java/src/net/i2p/util/LogWriter.java
index 8f47b0d0e8ff6fab803433c6fb2059d329459248..1d24e34ef45138de296eb4be2df26400698c9688 100644
--- a/core/java/src/net/i2p/util/LogWriter.java
+++ b/core/java/src/net/i2p/util/LogWriter.java
@@ -25,7 +25,9 @@ import java.util.Queue;
 class LogWriter implements Runnable {
     /** every 10 seconds? why? Just have the gui force a reread after a change?? */
     private final static long CONFIG_READ_INTERVAL = 50 * 1000;
-    private final static long FLUSH_INTERVAL = 29 * 1000;
+    final static long FLUSH_INTERVAL = 29 * 1000;
+    private final static long MIN_FLUSH_INTERVAL = 2*1000;
+    private final static long MAX_FLUSH_INTERVAL = 5*60*1000;
     private long _lastReadConfig;
     private long _numBytesInCurrentFile;
     // volatile as it changes on log file rotation
@@ -38,6 +40,8 @@ class LogWriter implements Runnable {
     private static final int MAX_DISKFULL_MESSAGES = 8;
     private int _diskFullMessageCount;
     private LogRecord _last;
+    // ms
+    private volatile long _flushInterval = FLUSH_INTERVAL;
     
     public LogWriter(LogManager manager) {
         _manager = manager;
@@ -47,6 +51,14 @@ class LogWriter implements Runnable {
     public void stopWriting() {
         _write = false;
     }
+
+    /**
+     *  @param ms
+     *  @since 0.9.18
+     */
+    public void setFlushInterval(long interval) {
+        _flushInterval = Math.min(MAX_FLUSH_INTERVAL, Math.max(MIN_FLUSH_INTERVAL, interval));
+    }
     
     public void run() {
         _write = true;
@@ -109,7 +121,7 @@ class LogWriter implements Runnable {
             if (shouldWait) {
                 try { 
                     synchronized (this) {
-                        this.wait(FLUSH_INTERVAL); 
+                        this.wait(_flushInterval); 
                     }
                 } catch (InterruptedException ie) { // nop
                 }