Background 

The performance of remote file operations, such as read/write, using SMB protocol can be affected by the size of buffers allocated by servers and clients.  The buffer size determines the number of round trips needed to send a fixed amount of data.     Every time when requests and responses are sent between client and server, the amount of time taken is equal to at least the latency between both sides, which could be very significant in the case of Wide Area Network (WAN).      Therefore it is important to understand   how Windows clients and servers select buffer size while you are working on SMB performance monitoring and tuning.  

MaxBufferSize negotiation on SMB traffic 

   1) SMB servers return a maximum SERVER buffer size (MaxTransmotBufferSize) in the SMB negotiation response (SMB_COM_NEGOTIATE server response). This size is not the size of the complete network packet; it is just the SMB portion of the packet starting from SMB header.

- Smb: R; Negotiate, Dialect is NT LM 0.12 (#5), SpnegoNegTokenInit
    Protocol: SMB
    Command: Negotiate 114(0x72)
  + NTStatus: 0x0, Facility = FACILITY_SYSTEM, Severity = STATUS_SEVERITY_SUCCESS, Code = (0) STATUS_SUCCESS
  + SMBHeader: Response, TID: 0xFFFF, PID: 0xFEFF, UID: 0x0000, MID: 0x0000
  - RNegotiateDialectNTLM:
     WordCount: 17 (0x11)
     DialectIndex: 5 (0x5)
   + SecurityMode: 15 (0xF)
     MaxMpxCount: 50 (0x32)
     MaxCountVCs: 1 (0x1)
     MaxTransmitBufferSize: 16644 (0x4104)
     MaxRawSize: 65536 (0x10000)
     SessionKey: 0 (0x0)

  2)   The SMB client sends  a maximum CLIENT buffer size  to the server in  SMB Session Setup request (SMB_COM_SESSION_SETUPANDX request)  telling the sever what the maximum buffer size the client can support.

- Smb: C; Session Setup Andx, Krb5ApReq (0x100)
    Protocol: SMB
    Command: Session Setup Andx 115(0x73)
  + NTStatus: 0x0, Facility = FACILITY_SYSTEM, Severity = STATUS_SEVERITY_SUCCESS, Code = (0) STATUS_SUCCESS
  + SMBHeader: Command, TID: 0xFFFF, PID: 0xFEFF, UID: 0x0000, MID: 0x0040
  - CSessionSetupAndXNTLMESS:
     WordCount: 12 (0xC)
     ANDXCommand: No Secondary Command 255(0xFF)
     AndXReserved: 0 (0x0)
     ANDXOffset: 0 (0x0)
     MaxBufferSize: 16644 (0x4104)
     MaxMpxCount: 50 (0x32)

 

How is MaxBufferSize selected?   

The MaxBufferSize can be configured through the following registry setting:

 HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters\SizeReqBuf

Data Type:   REG_DWORD

Range:          1024 to 65535

Default Values (If the key is not present):  

 

For Windows Server versions of OS (NT server, Windows 2000, Windows 2003, Windows 2008)

     If   Physical Memory < =512M,   default is 4356.

     Else    default value is 16644.

 

For Windows client versions of OS (Windows 98, NT, 2000, XP and Vista)

     Default value is 4356.

 

Is maximum buffer size always the value of MaxBufferSize?

MaxBufferSize doesn’t ALWAYS reflect the maximum buffer allowed to transfer file between SMB servers and clients., so the answer is no.  

For normal SMB_COM_READ and SMB_COM_WRITE requests, the maximum buffer size is always equal to MaxBufferSize.

 

If CAP_LARGE_READX  or CAP_LARGE_WRITEX  capability is enabled on the SMB Negotiate Server Response,   the maximum buffer size  used  is  61440 (60K)  for large read( SMB_COM_ READ_ANDX )  and 65535 (64K) for large write (SMB_COM_WRITE_ANDX) , regardless of MaxBufferSize.   But this is only true if the SMB signing is not turned on (we will discuss this further in the next section).  

 

The data length of each Large Read and Write operation can vary based on application and APIs used, but it should never exceed the maximum buffer size determined as above.    For example,  when using Windows Explorer or cmd prompt to write a large file to a network share,  data is truncated to  chunks of 61440 (60K) for transferring, even though server can  support  a larger 64K buffer.

 

By default,  CAP_LARGE_READX and CAP_LARGE_WRITEX are always turned on by server.  But they can be turned off by the following registry keys.

 HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters\disablelargeread

HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters\ disablelargewrite

 

 

How does SMB signing affect maximum buffer size allowed?

When SMB signing is negotiated by servers and clients, servers automatically disable the Large Read and Large Write feature.   It means that maximum transmit buffer size for Large Read or Large Write  will fall  back to MaxBufferSize as described in the previous section.   For example, the default maximum buffer size is 4356 for client OS, when signing is enabled.   One caveat is that a server still turns on CAP_LARGE_READX and CAP_LARGE_WRITEX bits in Server Negotiate Response in this case, even though large read and write operation will never be performed.   This is something to be aware of when reading network packet captures of SMB traffic.

Conclusion

The maximum size of server or client transmit buffer is dependent on a combination of the type of operation (Large Read/Write), server registry setting and SMB signing state.    Understanding how maximum buffer size is determined and how it can be changed can help you achieve the best SMB I/O performance.