diff --git a/Readme.md b/Readme.md
--- a/Readme.md
+++ b/Readme.md
@@ -1,4 +1,34 @@
-* This tunnel should be used inside an encrypted tunnel
+Protocol
+========
+
+    payload
+    
+    -> 
+
+    n | padding | m | payload
+
+* n (word32be): the number of bytes of padding
+* padding: n bytes of noise
+* m (word32be): the number of bytes of the original payload
+* payload: the original packet
+
+Implementation
+==============
+
+* `n` is randomly generated for each packet.
+* `n` is bounded by a maximum `r`, configurable by the `--randomness` argument.
+* To reduce overhead, `n` is set to 0 whenever `m` is greater then a 
+  threshold `b`, configurable by the `--bound` argument.
+
+Usage
+=====
+* local:
+
+        need-obfs --localHost TEXT --localPort INTEGER --remoteHost TEXT --remotePort INTEGER
+* remote: 
+
+        neko-obfs --remote --remoteHost TEXT --remotePort INTEGER --forwardHost TEXT --forwardPort INTEGER
+* This tunnel should be used inside an encrypted tunnel.
 * For example:
 
         ss-local (rc4)
@@ -11,4 +41,9 @@
 
         -> ss-server (rc4)
 * Note it's the `ss-tunnel` layer that protects the obfuscation, otherwise
-  data and noise length are clearly visable.
+  data and noise length are clearly visible.
+
+Performance
+===========
+
+* No noticeable slow down yet (Jul 24, 2017)
diff --git a/neko-obfs.cabal b/neko-obfs.cabal
--- a/neko-obfs.cabal
+++ b/neko-obfs.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                neko-obfs
-version:             0.1.0.0
+version:             0.1.0.1
 synopsis:            a TCP tunnel with packet length obfuscation
 description:         Just another tool that helps accessing the internet
 license:             Apache-2.0
@@ -26,7 +26,7 @@
                      , Type
                      , Unsafe
   -- other-extensions:    
-  build-depends:       base >=4.9 && <4.10
+  build-depends:       base >=4.9 && <4.11
                      , async
                      , attoparsec
                      , binary
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -44,22 +44,24 @@
         then pure 0
         else liftIO - randomIO <&> (`mod` fromIntegral randomness)
 
-    yield - view strict - Builder.toLazyByteString - Builder.word32BE randomLen
-    replicateM_ (fromIntegral randomLen) - yield - BC.singleton 'a'
-
-    yield - view strict - Builder.toLazyByteString - Builder.word32BE payloadLen
-    yield x
+    yield - view strict - Builder.toLazyByteString -
+      Builder.word32BE randomLen
+      <> Builder.byteString (BC.replicate (fromIntegral randomLen) - 'a')
+      <> Builder.word32BE payloadLen
+      <> Builder.byteString x
 
 
 obfsDecode :: (MonadIO m) => Producer ByteString m a -> (ByteString -> m ()) -> m ()
-obfsDecode pull sink = do
-  (r, next) <- runStateT (PA.parse obfsParser) pull
-  case r of
-    Just (Right result@(_,_,_,payload)) -> do
-      -- log - view packed - show result
-      sink payload
-      obfsDecode next sink
-    _ -> pure ()
+obfsDecode pull sink = loop pull
+  where
+    loop x = do
+      (r, next) <- runStateT (PA.parse obfsParser) x
+      case r of
+        Just (Right result@(_,_,_,payload)) -> do
+          -- log - view packed - show result
+          sink payload
+          loop next
+        _ -> pure ()
 
 main :: IO ()
 main = do
@@ -82,9 +84,11 @@
   localThread <- pure -
     runSafeT . runEffect - serve (Host _localHost) _localPort - \(localSock, localSockAddr) -> do
       log - "local accepted: " <> view packed (show localSockAddr)
+      NS.setSocketOption localSock NS.NoDelay 1
 
       runSafeT . runEffect -
         connect _remoteHost _remotePort - \(remoteSock, remoteSockAddr) -> do
+          liftIO - NS.setSocketOption remoteSock NS.NoDelay 1
 
           let
               localPull = _fromSocket localSock mtu
@@ -109,12 +113,14 @@
   remoteThread <- pure -
     runSafeT . runEffect - serve (Host _remoteHost) _remotePort - \(remoteSock, remoteSockAddr) -> do
       log - "remote accepted: " <> view packed (show remoteSockAddr)
+      NS.setSocketOption remoteSock NS.NoDelay 1
 
       let _forwardHost = config ^. forwardHost . re packed
           _forwardPort = show - config ^. forwardPort
 
       runSafeT . runEffect -
         connect _forwardHost _forwardPort - \(forwardSock, forwardSockAddr) -> do
+          liftIO - NS.setSocketOption forwardSock NS.NoDelay 1
 
           let
               remotePull = _fromSocket remoteSock mtu
