title: Optimal buffer size with boost::asio in Windows
body: <p>I'm using boost::asio for a client (Windows 10, Visual C++) which needs to receive variable length messages from a server.
  The messages are very frequent (more than 10 messages per second) and each message is about 40-100 bytes.</p>
  
  <p>I'm using <code>streambuf</code> with <code>async_read_some</code> in this way:</p>
  
  <pre><code>void Client::readStart(void)
  {
      boost::asio::streambuf::mutable_buffers_type buf = _inbox.prepare(std::max((size_t)1024, _socket-&gt;available()));
  
      // Start an asynchronous read and call readHandler when it completes or fails
      _socket-&gt;async_read_some(buf,
          boost::bind(&amp;Client::readHandler,
          this,
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred));
  }
  </code></pre>
  
  <p>i.e. I'm trying to adjust the buffer size dynamically with <code>_inbox.prepare(std::max((size_t)1024, _socket-&gt;available()))</code> to use a larger buffer when many messages have accumulated because the client is still processing previous messages.</p>
  
  <p>I found that I can't simply always use a larger buffer like <code>_inbox.prepare(262144)</code> because <code>readHandler</code> gets called with large chunks of data, instead of more frequently.</p>
  
  <p>Even with this attempt to dynamic buffer allocation, I experience strange delays and accumulation of data.</p>
  
  <p>This is my log:</p>
  
  <pre><code>  2017-05-09 09:02:25 &lt;debug&gt; Received 1024 bytes
    2017-05-09 09:02:25 &lt;debug&gt; Received 372 bytes
    2017-05-09 09:02:25 &lt;debug&gt; Received 844 bytes
    2017-05-09 09:02:25 &lt;debug&gt; Received 169 bytes
    2017-05-09 09:02:25 &lt;debug&gt; Received 1024 bytes
    2017-05-09 09:02:25 &lt;debug&gt; Received 379 bytes
    2017-05-09 09:02:25 &lt;debug&gt; Received 1385 bytes
    2017-05-09 09:02:25 &lt;debug&gt; Received 1421 bytes
    2017-05-09 09:02:25 &lt;debug&gt; Received 108 bytes
    2017-05-09 09:02:25 &lt;debug&gt; Received 1024 bytes
    2017-05-09 09:02:25 &lt;debug&gt; Received 1768 bytes
    2017-05-09 09:02:27 &lt;debug&gt; Received 65536 bytes
    2017-05-09 09:02:33 &lt;debug&gt; Received 65536 bytes
    2017-05-09 09:02:40 &lt;debug&gt; Received 65536 bytes
    2017-05-09 09:02:47 &lt;debug&gt; Received 65536 bytes
    2017-05-09 09:02:55 &lt;debug&gt; Received 65536 bytes
    2017-05-09 09:03:01 &lt;debug&gt; Received 65536 bytes
    2017-05-09 09:03:07 &lt;debug&gt; Received 65536 bytes
    2017-05-09 09:03:15 &lt;debug&gt; Received 65536 bytes
    2017-05-09 09:03:35 &lt;debug&gt; Received 65536 bytes
    2017-05-09 09:03:41 &lt;debug&gt; Received 65536 bytes
    2017-05-09 09:03:46 &lt;debug&gt; Received 65536 bytes
    2017-05-09 09:03:50 &lt;debug&gt; Received 65536 bytes
    2017-05-09 09:03:58 &lt;debug&gt; Received 65536 bytes
    2017-05-09 09:04:02 &lt;debug&gt; Received 65536 bytes
    2017-05-09 09:04:11 &lt;info&gt; Disconnected by remote host
  </code></pre>
  
  <p>As you can see, until 09:02:25 everything is ok, then data starts to accumulate and <code>readHandler</code> gets called infrequently (7-8 seconds between each call) with a large chunk of data (65536 bytes).</p>
  
  <p>In the end, the remote host drops the connection. The disconnection is due to TCP ZeroWindow Probes sent by the server to my client (traced with Wireshark), i.e. my TCP buffers are full.</p>
  
  <p>I can't really understand why <code>readHandler</code> is called so unfrequently and with so much data <s>(I'm sure it's NOT a problem of 100% CPU on client's side: the client is fast to process the messages and the CPU load is small)</s>.</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>I'm disabling Nagle's algorithm on the socket with this code:</p>
  
  <pre><code>boost::system::error_code error;
  _socket-&gt;set_option(tcp::no_delay(true), error);
  </code></pre>
  
  <p>in the attempt to prevent the TCP/IP stack from grouping the packets, but it doesn't help.</p>
  
  <p><strong>EDIT 2:</strong></p>
  
  <p>It seems that there is a bottleneck somewhere in my processing code, so I'm not actually receiving data quickly enough and the server's Nagle algo produces the problem described by R. Joiny below.</p>