The tier recommendations in the guide for Running Matomo in High-Traffic Environments, provide starting values for PHP, PHP-FPM, MySQL/MariaDB and archiving. Example configuration files can be useful as implementation starting points, but they should be reviewed and adapted for your operating system, PHP version, database version, traffic profile and hosting environment.

Nginx

This configuration handles HTTP-to-HTTPS redirection, static asset caching, path restrictions, and PHP-FPM proxying. Adjust the fastcgi_pass socket path to match your PHP version.

server {
    listen 80;
    server_name matomo.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name matomo.example.com;

    root /var/www/matomo;
    index index.php;

    ssl_certificate     /etc/ssl/certs/matomo.crt;
    ssl_certificate_key /etc/ssl/private/matomo.key;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    # Serve static assets directly
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
        expires 30d;
        add_header Cache-Control "public, no-transform";
        try_files $uri =404;
    }

    # Block access to sensitive paths
    location ~ ^/(config|tmp|core|lang)/ {
        deny all;
        return 403;
    }

    location ~ /\. { deny all; }

    # PHP processing
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_read_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 8 128k;
    }

    location / {
        try_files $uri $uri/ =404;
    }
}

PHP (php.ini / PHP-FPM pool)

Set these in your php.ini or in your PHP-FPM pool configuration file (typically /etc/php/8.x/fpm/pool.d/www.conf). The archiving CLI process is the most memory-intensive component, if you run a dedicated archiving server, raise memory_limit and max_execution_time there independently.

; === PHP core ===
memory_limit = 512M
max_execution_time = 180
max_input_time = 120
post_max_size = 32M
upload_max_filesize = 32M
; Dedicated archiving server: increase to 1024M / 600

; === OPcache ===
opcache.enable = 1
opcache.enable_cli = 1          ; Required for CLI archiving
opcache.memory_consumption = 256
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 10000
opcache.revalidate_freq = 60
opcache.save_comments = 1
opcache.fast_shutdown = 1

; === Session handling (Redis) ===
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"
session.gc_maxlifetime = 1440

; === PHP-FPM pool (www.conf) ===
[www]
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500

MariaDB / MySQL (my.cnf)

Values below target a dedicated database server with 32 GB RAM. The innodb_buffer_pool_size is the most impactful single setting, keeping frequently accessed index and data pages in memory reduces physical I/O substantially. Review the slow query log weekly; Matomo archiving queries are the most common source of performance problems.

[mysqld]
# InnoDB buffer pool — 60-80% of RAM on a dedicated DB server
innodb_buffer_pool_size = 20G
innodb_buffer_pool_instances = 8

# InnoDB logging
innodb_log_file_size = 1G
innodb_log_buffer_size = 64M
innodb_flush_log_at_trx_commit = 2   # ~1s data-loss risk on crash; fine for analytics
innodb_flush_method = O_DIRECT

# Connections
max_connections = 300
thread_cache_size = 50

# Query cache — disable on high-write analytics workloads
query_cache_type = 0
query_cache_size = 0

# Temp tables (archiving generates large sorts)
tmp_table_size = 256M
max_heap_table_size = 256M

# Slow query log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
log_queries_not_using_indexes = 1

# Binary log (required for replica setups)
log_bin = /var/log/mysql/mysql-bin.log
expire_logs_days = 7
binlog_format = ROW

# File limits
open_files_limit = 65535
innodb_open_files = 4000
Previous FAQ: Running Matomo in High-Traffic Environments