You should avoid using socket.SOMAXCONN

February 24, 2013

There you are, writing a socket-based server in Python, and you've decided that you should heed my advice and make its listen() backlog as large as possible. So you write the following code:

s = socket.socket(....)
s.bind(....)
s.list(socket.SOMAXCONN)

Given that SOMAXCONN is the traditional BSD sockets API name for 'the maximum value you can give listen()', this looks good and should do what you want. Sadly it does not.

The problem is that socket.SOMAXCONN is a constant. On many modern systems, the system-wide maximum listen() value is a kernel tuneable; it can be adjusted up (or down). If it's adjusted down, there is no problem with this code since the kernel will reduce the listen() backlog value down to the system setting. But if the system limit has been raised, the kernel does not adjust your listen() backlog up for you; it quietly stays at what you told the kernel. Which means that if someone has adjusted the limit up on your system, your code is not actually specifying a maximum backlog.

I can't blame Python for this one, because Unix doesn't actually expose an API for finding out the maximum socket listen() backlog that's allowed. The best that the socket module can do is set SOMAXCONN to some compile-time value, and in this case it's using the C-level API SOMAXCONN constant definition (which is usually 128).

So what should your code do? Since the kernel will quietly limit the listen() backlog to the system maximum for you, the obvious answer is to specify a large number, or a very large number, or even an absurdly large number. My tastes run to:

s.listen(max(1024, socket.SOMAXCONN))

This is a hack, of course, and you can argue that 1024 is not large enough and so on (and also that being paranoid about SOMAXCONN being larger than 1024 is pointless, so I should take the max() out). This is just what I do.

You may even feel that a large listen() backlog is pointless because in reality clients will start timing out long before you can service their requests. This is also a valid view. The whole area is complicated. But I still think you should avoid using socket.SOMAXCONN because it simply doesn't mean what people might think it means, not in real life on real systems.


Comments on this page:

From 67.180.84.60 at 2013-02-24 23:12:23:

On some platforms (apparently not Linux though), there's sysconf(_SC_SOMAXCONN) thus in python:

somaxconn = max(1024, socket.SOMAXCONN)
if "_SC_SOMAXCONN" in os.sysconf_names:
 somaxconn = max(somaxconn, os.sysconf(os.sysconf_names['_SC_SOMAXCONN']))

s.listen(somaxconn)

-- PerryLorier

Written on 24 February 2013.
« What limits the number of concurrent connections to a server
Looking at whether (some) IP addresses persist in zen.spamhaus.org »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sun Feb 24 22:54:44 2013
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.