I have an application which regularly creates a new TCP connection, makes a request, and then gets a just under ~300KB response before closing down the connection. Assuming that I can't redesign this workload, and that the latency between my side and the other side of the connection is ~5ms, how can I optimize for performance?
From a packet capture, I can see:
- SYN-SYNACK-ACK handshake (~15ms)
- I send a small request (<1KB), they ACK it (~10ms)
- They begin sending the 300KB response
- They fill the TCP Window with ~30K bytes (~5 ms for first byte, but then only 0.05ms for me to get all 30K bytes)
- They pause while they're waiting for my ACKs to reach them, then fill the new window (now ~50K as I'm advertising in my ACK)
- They fill that window and pause...
- ...
So to solve this situation, I'm considering updating net.ipv4.tcp_rmem
from the defaults:
net.ipv4.tcp_rmem = 4096 87380 6291456
to something like:
net.ipv4.tcp_rmem = 307200 307200 6291456
But I'm not really sure of the implications this would have on the system. Assume that I have many Gigs of ram free in steady state. What are the downsides to a change like this? If I understand the memory usage of TCP, this will cause me to advertise a 300KB window on my very first ack, and assuming the other side is ready to send 300KB at once, they will.