HTTP is an application-based protocol, which uses TCP as the transport layer. In TCP, data is transferred in the form of blocks known as TCP packets. NGINX provides directives to alter the behavior of the underlying TCP stack. These parameters alter flags for an individual socket connection.
TCP/IP networks have the "small packet" problem, where single-character messages can cause network congestion on a highly loaded network. Such packets are 41 bytes in size, where 40 bytes are for the TCP header and 1 byte has useful information. These small packets have a huge overhead of around 4000 percent and can saturate a network.
John Nagle solved the problem (Nagle's algorithm) by not sending the small packets immediately. All such packets are collected for a certain amount of time and then sent in one go as a single packet. This results in the improved efficiency of the underlying network. Thus, a typical TCP/IP stack waits for up to 200 milliseconds before sending the data packages to the client.
It is important to note that the problem exists with applications such as Telnet, where each keystroke is sent over wire. The problem is not relevant to a web server, which severs static files. The files will mostly form full TCP packets, which can be sent immediately instead of waiting for 200 milliseconds.
The TCP_NODELAY
option can be used while opening a socket to disable Nagle's buffering algorithm and send the data as soon as it is available. NGINX provides the tcp_nodelay
directive to enable this option. The directive is available under the http
, server
, and location
sections of an NGINX configuration:
http{ tcp_nodelay on; }
The directive is enabled by default.
As an alternative to Nagle's algorithm, Linux provides the TCP_CORK
option. The option tells the TCP stack to append packets and send them when they are full or when the application instructs to send the packet by explicitly removing TCP_CORK
. This results in an optimal amount of data packets being sent and, thus, improves the efficiency of the network. The TCP_CORK
option is available as the TCP_NOPUSH
flag on FreeBSD and Mac OS.
NGINX provides the tcp_nopush
directive to enable TCP_CORK
over the connection socket. The directive is available under the http
, server
, and location
sections of an NGINX configuration:
http{ tcp_nopush on; }
The directive is disabled by default.
The two directives discussed previously do mutually exclusive things; the former makes sure that the network latency is reduced, while the latter tries to optimize the data packets sent. An application should set both of these options to get efficient data transfer.
Enabling tcp_nopush
along with sendfile
makes sure that while transferring a file, the kernel creates the maximum amount of full TCP packets before sending them over wire. The last packet(s) can be partial TCP packets, which could end up waiting with TCP_CORK
being enabled. NGINX makes sure it removes TCP_CORK
to send these packets. Since tcp_nodelay
is also set at this point, these packets are immediately sent over the network without any delay.
3.15.29.119