Tuning the NGINX

how to make your Website faster

TYPO3 Developer Days 2022

Frank Berger

A bit about me

  • Frank Berger
  • Head of Engineering at code711.de, a label of B-Factor GmbH, Sudhaus7 and 12bis3.de
  • Started as an Unix Systemadministrator who also develops in 1996
  • Does TYPO3 since 2005



Shiny new website

Not optimised yet... it is still on the todo list, promise!

Then the URL gets posted here

and our 16 core Server just vanished

Whats on the Server?

  • Debian Linux
  • PHP 7.4 (opcache enabled)
  • MariaDB 10.3 (not tuned)
  • Nginx 1.14
  • TYPO3
  • Shiny new Website, with lots of uncached USER_INT - because the Editor can’t wait to see the changes online (and we have lots of user input)

Lets test the server

Testing with siege

100 or more concurrent requests for 30 seconds on a list of random urls

What can we do to improve?

worker_processes 3;
worker_rlimit_nofile 40000;
pcre_jit on;

events {
    use epoll;
    worker_connections 1024;
    multiaccept on;

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
server {
    open_file_cache max=10000 inactive=30s;
    open_file_cache_valid 2m;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;

Better, but not good enough, what else?

http {
    fastcgi_cache_path /var/run/nginx-fastcgi-cache levels=1:2 keys_zone=TYPO3:10m inactive=2m;
    fastcgi_cache_key "$scheme$request_method$host$uri$args";
    fastcgi_cache_use_stale error timeout invalid_header http_500;
    fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
location ~ [^/]\.php(/|$) {
    set $skip_cache 0;
    if ($request_method = POST) {
        set $skip_cache 1;
    if ($request_uri ~* "/typo3/|/index.php?") {
        set $skip_cache 1;
    if ($http_cookie ~* "be_typo_user|fe_typo_user") {
        set $skip_cache 1;
    fastcgi_cache_bypass $skip_cache;
    fastcgi_no_cache $skip_cache;
    fastcgi_cache TYPO3;
    fastcgi_cache_valid 200 10s;
    add_header X-FastCGI-Cache $upstream_cache_status;

Great! But we have cache warmup problems..

http {
    fastcgi_cache_use_stale updating error timeout invalid_header http_500;
    fastcgi_cache_background_update on;
    fastcgi_cache_lock on;

The problem with this kind of caching..

  • Everything gets cached for the specified time, even uncached content
  • Cache-Control Headers are ignored
  • There is no easy way to purge the cache for a specific page (it got better in the newer nginx versions)

If we could just compartmentalise different parts of the Webpage based on their lifetime

Enter SSI

<!—#include virtual="" —>

(or how webpages were made dynamic in the early 1990’s)

Extension for TYPO3

config.sendCacheHeaders = 1
composer require ichhabrecht/intcache

Replaces USER_INT with <!—#include virtual="" —> and uses a pageType call to render the uncached content in a separate call

Supports as well ESI (Varnish and Cloud flare) and AJAX

Lets try

http {
    fastcgi_ignore_headers  Set-Cookie;
location ~ [^/]\.php(/|$) {
    ssi on;
    set $cachekey "$scheme$host$request_uri";
    if ($args ~* "tx_intcache") {
        set $cachekey "$scheme$host$uri$args";
    fastcgi_cache_key $cachekey;


  • Cache-Control Headers are recognised and honoured by nginx
  • Uncached Content will be delivered directly, but the surrounding page will stay cached
  • Extensions can send their own Cache-Control headers based on their needs
  • Extensions can make better use of the Typo3 Cache
  • Multiple uncached extensions in a single Page can be handled separately

Other cool stuff

  1. The NGINX Cache could be stored in a Redis cache
enabling Failover Servers or Multiple Frontend Servers using the same cached content
  2. using the proxy_ variations of the configuration commands can be used to set up a distributed cloud system
  3. or using a docker-based backend, with the same advantages as shown in this talk
  4. The SSI technology can be used as well to include Widgets from other frameworks or even technologies.

Questions and Discussions


Thank you

Twitter: @FoppelFB