How do I choose from all of those protocols?

Speed

httpd: SCGI faster than FastCGI, FastCGI way faster than HTTP

These are initial results testing the three protocols with:

  • httpd with default event MPM settings
  • TCP sockets used with each protocol
  • simple hello.py WSGI application
  • uWSGI config files shown on earlier slides
  • requests per second taken from ab -n 1000 -c 50
SCGI
19K to 20K requests/second
FastCGI
15K to 16K requests/second
HTTP
10K requests/second

I need to re-run the HTTP tests because I was using http = sockaddr instead of http-socket = sockaddr in my uWSGI configs at the time. Sometimes I really suck!

There are any number of reasons why this isn't a suitable benchmark of the protocols themselves or of how they will work with your particular application, but the spreads are large enough that they're likely to make a difference in some of the simpler requests handled by a real world application.

nginx: SCGI, FastCGI, HTTP pretty close at 11K to 12K requests/second:

  • a bit faster than HTTP with httpd

    (See the HTTP-specific warning above. I need to re-run these tests.)

  • much slower than FastCGI or SCGI with httpd

Again, I wouldn't use this as anything definitive other than to say, for a contrived test of an unrealistic application, it seems that

  • either of the protocols with nginx, or HTTP with httpd, are in the same ballpark
  • FastCGI and SCGI with httpd are much faster

After settling on a particular web server and a couple of communication mechanisms, it is worth spending further time to optimize the configuration using real world application requests.

Weakness of particular implementations

on either the web server side or the application side

I found a FastCGI problem in uWSGI when developing this material. Refer to this page for more information.

HTTP implementations are generally more tested and optimized. But HTTP is relatively complex compared with FastCGI and SCGI, and so there's a lot of extra, unnecessary surface area with potential bugs.

HTTP implementations used only in particular types of deployment, like that in uWSGI or language-specific libraries, are nowhere near as well tested and proven as general purpose HTTP implementations like httpd and nginx. Do not expose these implementations on the Internet. Instead, bind them to infrastructure-only IP addresses (possibly localhost).

And of course, do not expose SCGI and FastCGI ports on the Internet either.

Client support for backend

As long as you're using HTTP over TCP, client support for connecting directly to your backend (e.g., for debugging) is ubiquitous.

Client endpoint characteristics

FastCGI sees what the web server sees in the mapping of the web server request to FastCGI parameters, instead of having it mapped in a meaningful way to a different HTTP endpoint. One protocol or another may ease configuration of a particular application because of this.

Consider the REQUEST_URI variable sent over for FastCGI or SCGI. This is the request URI as the web server received it, and some extra configuration may be required to map that into the application's view. HTTP proxy, on the other hand, has a more natural way to specify the request URI, and the web server can perform the desired mapping by adjusting the proxy configuration slightly.

FastCGI and SCGI, on the other hand, have more information available by default, as all the standard CGI variables are passed over. Some of this information (e.g., information about the client SSL/TLS connection) requires extra configuration to pass over to the application when HTTP proxy is used.

Protocol features

FastCGI provides an error channel for integrating application error logging with the web server log.

SCGI allows the application to tell the web server to send a file to the client in a very direct manner.

Protocol-specific mismatches that may have to be configured around

If connections are retained (e.g., with HTTP keepalive), are there spurious errors when timeouts don't match?

Tool support (e.g., protocol analysis tools)

As an example, Wireshark can analyze these protocols supported by uWSGI:

  • HTTP
  • FastCGI

Encryption

If encryption is required between the web server and the application, HTTP is the only choice.