PHP has a environmental variable PHP_FCGI_MAX_REQUESTS that limits the number of requests PHP uses-- it defaults to 500. Apache mod_fcgid has a option called FcgidMaxRequestsPerProcess that defaults to unlimited. When the mod_fcgid option is bigger than the PHP option, a HTTP 500 error is returned after PHP exits.
This environmental variable is documented at this location:
The code that uses the environmental variable is here:
Additional details on the environmental variable can be found in Apache's mod_fcgid documentation, under the Special Considerations section
By default, PHP FastCGI processes exit after handling 500 requests, and they may exit after this module has already connected to the application and sent the next request. When that occurs, an error will be logged and 500 Internal Server Error will be returned to the client. This PHP behavior can be disabled by setting PHP_FCGI_MAX_REQUESTS to 0, but that can be a problem if the PHP application leaks resources. Alternatively, PHP_FCGI_MAX_REQUESTS can be set to a much higher value than the default to reduce the frequency of this problem. FcgidMaxRequestsPerProcess can be set to a value less than or equal to PHP_FCGI_MAX_REQUESTS to resolve the problem.
Anyway, the common fix seems to be to either adjust PHP_FCGI_MAX_REQUESTS and/or adjust FcgidMaxRequestsPerProcess (defaults to 0-- unlimited) as the Apache documentation recommends.
The exact timing of the error depends on activity of site as mod_fcgid may distribute the requests over more than one PHP process. The problem can be reproduced fairly easily on an completely inactive website using ab-- a phpinfo() file is sufficient. I ran the following on a website (virtual host) with no other traffic than me testing it. The PHP process was spawned only as this test was run.
$ ab -n 500 [domain]/info.php # Basic 500 requests to show the 500 error ... Non-2xx responses: 1
$ ab -n 2000 [domain]/info.php # Try 2000 instead of just 500 ... Non-2xx responses: 4
$ ab -q -n 10000 -v 3 [domain]/info.php | grep "HTTP/1.1" | sort | uniq -c # get the specific HTTP/1.1 status codes-- for 10000 requests 9980 HTTP/1.1 200 OK 20 HTTP/1.1 500 Internal Server Error
Error in virtual host error_log that repeats for each failure
[Thu Oct 20 15:49:18 2011] [warn] [client xxx.xxx.xxx.xxx] (104)Connection reset by peer: mod_fcgid: error reading data from FastCGI server [Thu Oct 20 15:49:18 2011] [error] [client xxx.xxx.xxx.xxx] Premature end of script headers: info.php