diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java
index feafa5a9cdd316d2b9f4e984ab53f27a9e092cba..757d9d2535902c1abc3126d359c78c91934185d5 100644
--- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java
+++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java
@@ -59,6 +59,110 @@ public class ConnectionOptions extends I2PSocketOptionsImpl {
     
     static final int MIN_WINDOW_SIZE = 1;
     
+    /**
+     *  OK, here is the calculation on the message size to fit in a single
+     *  tunnel message without fragmentation.
+     *  This is based on documentation, the code, and logging, however there are still
+     *  some parts that could use more research.
+     *
+     *  1024 Tunnel Message
+     *  - 21 Header (see router/tunnel/BatchedPreprocessor.java)
+     * -----
+     *  1003 Tunnel Payload
+     *  - 39 Unfragmented instructions (see router/tunnel/TrivialPreprocessor.java)
+     * -----
+     *   964 Unfragmented I2NP Message
+     *  - 20 ??
+     * -----
+     *   944 Garlic Message padded to 16 bytes
+     *  -  0 Pad to 16 bytes (why?)
+     * -----
+     *   944 Garlic Message (assumes no bundled leaseSet or keys)
+     *  - 71 Garlic overhead
+     * -----
+     *   873 Tunnel Data Message
+     *  - 84 ??
+     * -----
+     *   789 Gzipped I2NP message
+     *  - 23 Gzip 10 byte header, 5 byte block header, 8 byte trailer (yes we always use gzip, but it
+     *       probably isn't really compressing, just adding the headers and trailer, since
+     *       HTTP Server already compresses, and most P2P files aren't compressible.
+     *       (see client/I2PSessionImpl2.java, util/ReusableGZipOutputStream.java, and the gzip and deflate specs)
+     * -----
+     *   766
+     *  - 28 Streaming header (24 min, but leave room for a nack or other optional things) (See Packet.java)
+     * -----
+     *   738 Streaming message size
+     *
+     *
+     * FOR TWO TUNNEL MESSAGES:
+     *
+     *  2048 2 Tunnel Messages
+     *  - 42 2 Headers
+     * -----
+     *  2006 Tunnel Payload
+     *  - 50 Fragmented instructions (43 for first + 7 for second)
+     * -----
+     *  1956 Unfragmented I2NP Message
+     *  - 20 ??
+     * -----
+     *  1936 Garlic Message padded to 16 bytes
+     *  1936
+     *  -  0 Pad to 16 bytes
+     * -----
+     *  1936 Garlic Message
+     *  - 71 Garlic overhead
+     * -----
+     *  1865 Tunnel Data Message
+     *  - 84 ??
+     * -----
+     *  1781 Gzipped I2NP message
+     *  - 23 Gzip header
+     * -----
+     *  1758
+     *  - 28 Streaming header
+     * -----
+     *  1730 Streaming message size to fit in 2 tunnel messages
+     *
+     *
+     * Similarly:
+     *   3 msgs: 2722
+     *   4 msgs: 3714
+     *
+     *
+     * Before release 0.6.1.14 this was 4096.
+     * From release 0.6.1.14 through release 0.6.4, this was 960.
+     * It was claimed in the comment that this fit in
+     * a single tunnel message (and the checkin comment says the goal was to
+     * increase reliability at the expense of throughput),
+     * clearly from the math above that was not correct.
+     * (Before 0.6.2, the reply leaseSet was bundled with every message, so it didn't even
+     * fit in TWO tunnel messages - more like 2 1/3)
+     *
+     * Now, it's not clear how often we will get the ideal situation (no reply leaseSet bundling,
+     * no key bundling, and especially not having a small message ahead of you, which will then cause
+     * fragmentation for all subsequent messages until the queue is emptied - BatchedPreprocessor
+     * doesn't do reordering, and it isn't clear to me if it could). In particular the initial
+     * messages in a new stream are much larger due to the leaseSet and key bundling.
+     * But for long-lived streams (like with i2psnark) this should pay dividends.
+     * The tunnel.batch* stats should provide some data for test comparisons.
+     *
+     * As MTU and MRU are identical and are negotiated to the lowest value
+     * for the two ends, you can't do widespread testing of a higher value.
+     * Unless we change to allow MTU and MRU to be different,
+     * which would be a pain because it would mess up our buffer scheme.
+     * Both 738 and 1730 have been tested to verify that the math above is correct.
+     * So let's try 1730 for release 0.6.5. This will allow for 738 testing as well,
+     * with i2p.streaming.maxMessageSize=738 (in configadvanced.jsp, or in i2ptunnel, or
+     * i2psnark, for example).
+     *
+     * Not that an isolated single packet is very common, but
+     * in this case, 960 was 113.3% total overhead.
+     * Compared to 738 (38.8% overhead) and 1730 (18.4%).
+     *
+     */
+    public static final int DEFAULT_MAX_MESSAGE_SIZE = 1730;
+
     public ConnectionOptions() {
         super();
     }
@@ -102,7 +206,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl {
         setMaxWindowSize(getInt(opts, PROP_MAX_WINDOW_SIZE, Connection.MAX_WINDOW_SIZE));
         setConnectDelay(getInt(opts, PROP_CONNECT_DELAY, -1));
         setProfile(getInt(opts, PROP_PROFILE, PROFILE_BULK));
-        setMaxMessageSize(getInt(opts, PROP_MAX_MESSAGE_SIZE, 960)); // 960 fits inside a single tunnel message
+        setMaxMessageSize(getInt(opts, PROP_MAX_MESSAGE_SIZE, DEFAULT_MAX_MESSAGE_SIZE));
         setRTT(getInt(opts, PROP_INITIAL_RTT, 10*1000));
         setReceiveWindow(getInt(opts, PROP_INITIAL_RECEIVE_WINDOW, 1));
         setResendDelay(getInt(opts, PROP_INITIAL_RESEND_DELAY, 1000));