Search code examples
pythonsocketsunix

Considerations when picking a socket recv buffsize


What are the benefits and drawbacks of choosing a buffsize that is larger (or smaller) than needed when working with sockets?

Consider my specific case as an example, I am using UNIX stream sockets in python to implement basic IPC for an app I am working on. There is one "server" process, and many "client" processes. The client processes connect to the server process's socket and send it commands. The server process receives those commands and executes them. The protocol they use is very simple, and the only notable rule is that each command must end with a semicolon.

The clients can send as many or as few commands as they'd like in each message (even a partial command, where the rest of the command and the accompanying semicolon are included in a future message). The server processes and stores messages in a queue until it receives a semicolon, then it saves the completed command to a queue.

The point of describing my simple example is to illustrate that in terms of information transfer, the buffsize argument passed to socket.recv() is completely irrelevant. i.e. I can call socket.recv(1) or socket.recv(1024) and the program's behavior doesn't change.

In situations like this, where the buffsize has no role in the overall execution of the underlying application, what is a good way to choose this value? What are some important things to consider when making this decision?


Solution

  • Assuming you are asking about the byte-count argument you pass to each recv() call (and not the size of the kernel's internal receive-buffer that is associated with the socket, and optionally changed via setsockopt(SO_RCVBUF)), then it is largely a matter of taste.

    The advantage of passing a larger value to recv() is that you may be able to receive more bytes of data at once, and therefore you may need to call recv() a smaller number of times in order to collect the same amount of data. This can improve CPU-efficiency somewhat by reducing the per-byte overhead of the data transfer.

    The advantage of passing a smaller value to recv() is that you can reduce the worst-case amount of RAM required by the recv() call, since the argument limits the number of bytes of storage that recv() might need to return in a single array.

    Modern computers have powerful enough CPUs and enough RAM that in most cases it's unlikely to make a measurable difference what value you choose. In those few remaining cases where maximizing performance is important, choosing a larger recv-size is likely to perform better, although passing a size-value larger than the size of the socket's SO_RCVBUF buffer is unlikely to make any difference, since the kernel won't be able to hand you more bytes than it can store at once anyway.