python / cpython

The Python programming language
https://www.python.org
Other
63.38k stars 30.35k forks source link

Set TCP_NODELAY for `http.server` #108736

Open Stevenjin8 opened 1 year ago

Stevenjin8 commented 1 year ago

Feature or enhancement

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

Proposal:

Python's default http.server should set the TCP_NODELAY flag to accepted connections.

The default python HTTP server (running python -m http.server) will write to the socket twice, once for the header https://github.com/python/cpython/blob/d48760b2f1e28dd3c1a35721939f400a8ab619b8/Lib/http/server.py#L771C13-L771C29

and once for the body

https://github.com/python/cpython/blob/d48760b2f1e28dd3c1a35721939f400a8ab619b8/Lib/http/server.py#L679

This causes HTTP transactions on long-lived connections to have a 40 ms delay due to how Delayed Acks and Nagle's Algorithm interact (and they are both enabled by default).

I tested this using fortio on a Ubuntu 20.04 VM.

python -m http.server -p http/1.1
# in another session
fortio load -qps -1 -c 1 http://localhost:8000/some-file

Another option would be to expose a top-level flag to disable Nagle's with the TCP_NODELAY. Curl does this.

Exposing a TCP flag on the top level API is kinda weird, but disabling it is pretty common behaviour. For example, Golang will disable it https://news.ycombinator.com/item?id=34179426

ericvsmith commented 1 year ago

Does anyone use http.server in an environment where this makes a difference? It is, after all, not recommended for production use.

Stevenjin8 commented 1 year ago

Does anyone use http.server in an environment where this makes a difference? It is, after all, not recommended for production use.

Sorry just saw this. I hope nobody is using this this for anything performance critical. That said, I've used it in my dev environment. Setting nodelay only saves around 50ms per request, but I figured that 50ms times however many times people use this could add up.