FastCGI to improve TTFB when Using NGINX to reverse proxy?
I'm trying to improve time to first byte. HTTP2 helped a lot, but TTFB is still between 500-700ms. I'd like to bring it down to around 200.
I saw some suggestions to use FastCGI. I have a bit of a tricky setup so I'm trying to understand where/how I would set it up:
I have a wordpress app on Apache server, listening on port 8090. This is simply to have a wordpress dashboard, expose API endpoints and to serve media. My second NextJS app is on nodejs listening on port 8000. This consumes the wordpress API and actually renders the site.
Nginx is in front of both of these apps to do https/www redirects, and proxy requests to the respective ports.
As far as I can see at least all assets and pages are served by nginx. e.g.: curl -I -L https://www.example.com/wordpress/wp-content/uploads/2015/05/image.jpg
- response headers tell me it's nginx serving them.
But I'm still confused as to whether setting up FastCGI on Nginx makes sense. I'm still guessing that it's actually Apache handling the PHP execution because I originally set up working wordpress with the default apache droplet, and put Nginx in front of that later. Am I wrong? What's my path to improving the TTFB in this case? Perhaps I should even be looking at my Node app, but I'm just not sure how to identify where the delay is coming from.
FYI Here's my /etc/nginx/sites-available/example.com:
server {
listen 80;
server_name example.com www.example.com;
rewrite ^/(.*) https://www.example.com/$1 permanent;
}
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
root /var/www/html;
index index.php index.js index.html index.htm index.nginx-debian.html;
server_name example.com;
return 301 https://www.example.com$request_uri;
ssl_certificate /home/ssl/example.com.chained.crt;
ssl_certificate_key /home/ssl/example.com.key;
location / {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /wordpress {
proxy_pass http://localhost:8090;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
root /var/www/html;
index index.php index.js index.html index.htm index.nginx-debian.html;
server_name www.example.com;
ssl_certificate /home/ssl/example.com.chained.crt;
ssl_certificate_key /home/ssl/example.com.key;
location / {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /wordpress {
proxy_pass http://localhost:8090;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Solution 1:
I recently moved a wordpress site from an apache server which ran it well enough I dont know the TTFB but I decided to change to NGINX for the new server and it works fantastically.
My setup for the Fastcgi for the fastcgi_pass this should change to whatever version of php fpm you install.
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
include fastcgi_params;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_read_timeout 300;
}
by adding the above I now have a TTFB of 200ms ish and this works through a Haproxy load balancer on the front as well. So yeah I think changing to fastcgi and nginx will be an improvement of some description.
- EDIT *
recent changes and information has led me to changing to this slightly.
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php8.0-fpm.sock;
include snippets/fastcgi-php.conf;
fastcgi_read_timeout 600;
}
This is changed by including the snippets which auto includes the path and script params and the params.