GRAV "Gateway Timeout" Issues
About a year ago we begin switching our various websites to use content management systems (CMS) that did not require SQL databases, or any database for that matter. We looked at GRAV and Hugo. The latter is highly portable and very fast, but for our more dynamic websites we decided to use GRAV.
In general we have been quite happy with GRAV, but recently we encountered a problem in which users began to see "Gateway Timeout" errors.
We dug into the issue - and found a solution.
GRAV uses a hierarchy of Markdown files that are managed by two programming tools, Twig and PHP. Twig is used mainly for in-page templating while PHP is used to hold the whole system together.
Part of GRAV are facilities to try to optimize a website. These include CSS and Javascript compression, minimization, and pipelining. Compression and minimization are fairly self explanatory. Pipelining consists of joining all the various CSS or Javascript files into a single grand CSS or Javascript that can be transferred in a single HTTP/HTTPS transaction, which can considerably reduce the overhead of TCP and SSL/TLS connection establishment overhead required to load a web page.
All of our web servers run on Linux. All use the Apache web server. Some use PHP 5.6.x and others use PHP 7.1.x.
We ran into problems with servers using PHP 7.1.x. This happened on some machines but not on others even though they were running the same versions of the operating system, GRAV, Apache, and PHP.
The problem was that web page fetches would error-out with a "gateway timeout" error.
We anecdotally observed that server machines with more processing cores seemed more susceptible to the problem than machines with fewer processing cores.
We dug around on the web and found that the Apache - PHP 7.1 combination uses an external PHP server process (or several processes) via a FastCGI (mod_fcgid) path involving php-fpm. The problem is that requests over that path were timing out.
We tried various suggested cures - we tried various Apache RequestReadTimeout directive settings and various PHP configuration directives to increase the timeouts. Those definitely made a difference but did not reliably eliminate the problem.
We selectively tried turning off the various GRAV optimizations - compression, minimization, and pipelining. What we found was that if we turned off GRAV's CSS and Javascript pipelining (while leaving compression and minimization enabled) that the problem disappeared.