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 f71a19d424fd2cdbedc9dedbfe8ea2ef4b236f47..95eef4687a81f862b87a6faaab32c753c21fd09c 100644
--- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java
+++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java
@@ -100,6 +100,8 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
     private static final boolean DEFAULT_ANSWER_PINGS = true;
     private static final int DEFAULT_INACTIVITY_TIMEOUT = 90*1000;
     private static final int DEFAULT_INACTIVITY_ACTION = INACTIVITY_ACTION_SEND;
+    private static final int DEFAULT_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR = 1;
+    private static final int DEFAULT_SLOW_START_GROWTH_RATE_FACTOR = 1;
 
 
     /**
@@ -327,8 +329,10 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
         setInactivityTimeout(getInt(opts, PROP_INACTIVITY_TIMEOUT, DEFAULT_INACTIVITY_TIMEOUT));
         setInactivityAction(getInt(opts, PROP_INACTIVITY_ACTION, DEFAULT_INACTIVITY_ACTION));
         setInboundBufferSize(getMaxMessageSize() * (Connection.MAX_WINDOW_SIZE + 2));
-        setCongestionAvoidanceGrowthRateFactor(getInt(opts, PROP_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR, 1));
-        setSlowStartGrowthRateFactor(getInt(opts, PROP_SLOW_START_GROWTH_RATE_FACTOR, 1));
+        setCongestionAvoidanceGrowthRateFactor(getInt(opts, PROP_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR,
+                                                      DEFAULT_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR));
+        setSlowStartGrowthRateFactor(getInt(opts, PROP_SLOW_START_GROWTH_RATE_FACTOR,
+                                            DEFAULT_SLOW_START_GROWTH_RATE_FACTOR));
         // overrides default in super()
         setConnectTimeout(getInt(opts, PROP_CONNECT_TIMEOUT, Connection.DISCONNECT_TIMEOUT));
         setAnswerPings(getBool(opts, PROP_ANSWER_PINGS, DEFAULT_ANSWER_PINGS));
@@ -378,9 +382,11 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
             setInactivityAction(getInt(opts, PROP_INACTIVITY_ACTION, DEFAULT_INACTIVITY_ACTION));
         setInboundBufferSize(getMaxMessageSize() * (Connection.MAX_WINDOW_SIZE + 2));
         if (opts.contains(PROP_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR))
-            setCongestionAvoidanceGrowthRateFactor(getInt(opts, PROP_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR, 2));
+            setCongestionAvoidanceGrowthRateFactor(getInt(opts, PROP_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR,
+                                                          DEFAULT_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR));
         if (opts.contains(PROP_SLOW_START_GROWTH_RATE_FACTOR))
-            setSlowStartGrowthRateFactor(getInt(opts, PROP_SLOW_START_GROWTH_RATE_FACTOR, 2));
+            setSlowStartGrowthRateFactor(getInt(opts, PROP_SLOW_START_GROWTH_RATE_FACTOR,
+                                                DEFAULT_SLOW_START_GROWTH_RATE_FACTOR));
         if (opts.containsKey(PROP_CONNECT_TIMEOUT))
             // wow 5 minutes!!! FIXME!!
             // overrides default in super()
diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java
index 250dae808b256443e7a7574b03e77a3c06ff27c7..9d353075cb0c1fb79e5bb4225094b176edc95d1e 100644
--- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java
+++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java
@@ -23,6 +23,8 @@ import net.i2p.util.SimpleTimer;
 class ConnectionPacketHandler {
     private final I2PAppContext _context;
     private final Log _log;
+
+    public static final int MAX_SLOW_START_WINDOW = 24;
     
     public ConnectionPacketHandler(I2PAppContext context) {
         _context = context;
@@ -367,9 +369,16 @@ class ConnectionPacketHandler {
                     // grow acked/N times (where N = the slow start factor)
                     // always grow at least 1
                     int factor = con.getOptions().getSlowStartGrowthRateFactor();
-                    if (factor <= 1)
-                        newWindowSize += acked;
-                    else if (acked < factor)
+                    if (factor <= 1) {
+                        // above a certain point, don't grow exponentially
+                        // as it often leads to a big packet loss (30-50) all at once that
+                        // takes quite a while (a minute or more) to recover from,
+                        // especially if crypto tags are lost
+                        if (newWindowSize >= MAX_SLOW_START_WINDOW)
+                            newWindowSize++;
+                        else
+                            newWindowSize = Math.min(MAX_SLOW_START_WINDOW, newWindowSize + acked);
+                    } else if (acked < factor)
                         newWindowSize++;
                     else
                         newWindowSize += acked / factor;
diff --git a/apps/streaming/java/src/net/i2p/client/streaming/TCBShare.java b/apps/streaming/java/src/net/i2p/client/streaming/TCBShare.java
index 15b8e937e727dfd02ffa9c73e79d494b2001ae21..d412aa36a16e6bf9245578fc664e31481aea3c10 100644
--- a/apps/streaming/java/src/net/i2p/client/streaming/TCBShare.java
+++ b/apps/streaming/java/src/net/i2p/client/streaming/TCBShare.java
@@ -31,7 +31,7 @@ class TCBShare {
     private static final double RTT_DAMPENING = 0.75;
     private static final double WDW_DAMPENING = 0.75;
     private static final int MAX_RTT = ((int) Connection.MAX_RESEND_DELAY) / 2;
-    private static final int MAX_WINDOW_SIZE = Connection.MAX_WINDOW_SIZE / 4;
+    private static final int MAX_WINDOW_SIZE = ConnectionPacketHandler.MAX_SLOW_START_WINDOW;
     
     public TCBShare(I2PAppContext ctx, SimpleTimer2 timer) {
         _context = ctx;
@@ -45,6 +45,7 @@ class TCBShare {
         _cleaner.cancel();
     }
 
+    /** retrieve from cache */
     public void updateOptsFromShare(Connection con) {
         Destination dest = con.getRemotePeer();
         if (dest == null)
@@ -65,6 +66,7 @@ class TCBShare {
         opts.setWindowSize(e.getWindowSize());
     }
 
+    /** store to cache */
     public void updateShareOpts(Connection con) {
         Destination dest = con.getRemotePeer();
         if (dest == null)