Nextcloud Performance Tuning: PHP, Redis, and Database Optimization

Just a quick guide on how I install Nextcloud. This covers Nextcloud 25.0.1 with PHP 8.1 on Debian Bullseye, optimized with Redis, APCu, and MariaDB.

I am a fan of the repositories at https://deb.sury.org/, hence I’ll install those repos first. Please check that site for Debian—you’ll find a README.txt which contains all the required commands.

Next, make sure your system is up-to-date using:

apt-get update
apt-get upgrade

1. PHP and FPM Optimization

The core of Nextcloud performance relies on a highly tuned PHP-FPM environment.

Required Modules and Installation

Install the required (and some optional) PHP modules. You may want to add ldap, ftp, or smbclient based on the official documentation.

apt install php8.1-{ctype,curl,dom,gd,xml,zip,bz2,intl,exif,apcu,redis,imagick,mbstring,bcmath,gmp,opcache,mysql,igbinary,fpm}
apt install ffmpeg imagemagick

PHP Core Settings (/etc/php/8.1/fpm/php.ini

We adjust the core resource settings for better handling of large files and long operations.

SettingValueRationale
memory_limit1GHigher memory limit for file operations.
max_execution_time3600Extended timeout for large file uploads/downloads.
max_input_time3600Extended input time.
post_max_size1GRealistic limit for file uploads.
upload_max_filesize1GRealistic limit for file uploads.
date.timezoneEurope/BerlinCorrect regional setting.
memory_limit = 512M
# a much lower execution time should work, too
max_execution_time = 3600
max_input_time = 3600
output_buffering = Off
post_max_size = 10G
upload_max_filesize = 10G
allow_url_fopen = On
date.timezone = Europe/Berlin

Advanced PHP Module Tuning

We tune the key caching modules in /etc/php/8.1/mods-available/ to ensure maximum performance. Ensure these are symlinked from /etc/php/8.1/fpm/conf.d/.

opcache.ini (Code Caching)

# check defaults / explanation at:
# https://www.php.net/manual/de/opcache.configuration.php
opcache.enable = 1
opcache.enable_cli = 1
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 524521
opcache.memory_consumption = 256M

apcu.ini (Local Cache)

# check defaults / explanation at:
# https://www.php.net/manual/de/apcu.configuration.php
apc.enable_cli = 1

igbinary.ini (Serialization)

# check defaults / explanation at:
# https://github.com/igbinary/igbinary
session.serialize_handler = igbinary
apc.serializer = igbinary

redis.ini (Session Handling)

# check defaults / explanation at:
# https://github.com/phpredis/phpredis
session.save_handler = redis
session.save_path = "unix:///var/run/redis/redis-server.sock"
redis.session.locking_enabled = 1
redis.session.lock_retries = -1
redis.session.lock_wait_time = 10000

PHP-FPM Pool Settings (/etc/php/8.1/fpm/pool.d/www.conf)

Fine-tune the FPM process pool for concurrent connections. Use the FPM calculator and adjust for your needs.

pm.max_children = 12
pm.start_servers = 3
pm.min_spare_servers = 3
pm.max_spare_servers = 9
pm.max_requests = 500

2. Webserver Configuration (Apache)

While NGINX is often faster, Apache is simpler to configure. I focus on optimizing its modules for Nextcloud’s requirements.

apt install apache2

Module and Site Configuration

We enable essential modules and the PHP handler:

a2enmod proxy
a2enmod proxy_fcgi
a2enconf php8.1-fpm

# if behind a loadbalancer
a2enmod remoteip

# Disabled to avoid issues with large file uploads
# behind a loadbalancer)
a2dismod reqtimeout

For large file uploads, you may want to ensure the ProxyTimeout is sufficiently long:

ProxyTimeout 3600 (in /etc/apache2/mods-enabled/proxy.conf)

You may want to enable SSL if not using a Loadbalancer; but even then you might want to:

# enable SSL - if your loadbalancer already does
# you may not need this
a2enmod ssl

Create the nextcloud.conf in /etc/apache2/sites-available with contents:

<VirtualHost *:80>
  DocumentRoot /var/www/nextcloud/
  ServerName  yournext.clouddomain.tld

  <Directory /var/www/nextcloud/>
    Require all granted
    AllowOverride All
    Options FollowSymLinks MultiViews

    <IfModule mod_dav.c>
      Dav off
    </IfModule>
  </Directory>
</VirtualHost>

Letsencrypt / TLS:

apt-get install certbot python3-certbot-apache

Certbot will add Rewrite Rules to the nextcloud.conf and it will create nextcloud-le-ssl.conf.

certbot --apache -d yournext.clouddomain.tld

If you’re using SSL please check the Mozilla TLS Generator with your Apache Version and OpenSSL version. Create a ssl.conf in /etc/apache2/conf-available with the configuration outside of the VirtualHosts from the generator. E.g.:

SSLProtocol             all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite          ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder     off
SSLSessionTickets       off

SSLUseStapling On
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"

Then enable that using:

a2enconf ssl

You may also add the Strict-Transport-Security header by adding it to the nextcloud-le-ssl.conf. If you add the Protocols line you’ll also need to enable http2. So add:

# enable HTTP/2, if available
Protocols h2 http/1.1

# HTTP Strict Transport Security (mod_headers is required) (6307200)
Header always set Strict-Transport-Security "max-age=63072000"

to the nextcloud-le.conf and then enable HTTP2. If your System is behind an NGINX loadbalancer, enabling HTTP2 will likely not help you. In that case I would not enable http2 in Apache. Anyway:

a2enmod http2

The VM I’m using is only there for nextcloud. So I’m disabling the default web:

a2dissite 000-default.conf
a2dissite default-ssl.conf

3. Data Systems: Redis (Caching & Locking) and MariaDB (Storage)

Redis (Local Socket)

We disable Redis TCP listening and enable the Unix socket for local communication, which is faster and safer than TCP over localhost.

apt-get install redis
port 0
unixsocket /var/run/redis/redis-server.sock
unixsocketperm 770

Then add the web server user to the redis group:

usermod -a -G redis www-data

MariaDB (Performance Tuning)

Note: Check out my Nextcloud migrate to PostgreSQL article. I got better results with PostgreSQL instead of MariaDB due to a constant bug.

apt-get install mariadb-server
mysql_secure_installation

Enter current password for root (enter for none):
Switch to unix_socket authentication [Y/n] n
Change the root password? [Y/n] n
Remove anonymous users? [Y/n]
Disallow root login remotely? [Y/n]
Remove test database and access to it? [Y/n]
Reload privilege tables now? [Y/n]
mysql -u root 

CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';
CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
GRANT ALL PRIVILEGES on nextcloud.* to 'username'@'localhost';
FLUSH privileges;

We fine-tune the database for Nextcloud’s specific requirements (e.g., large prefix support and isolation levels) in /etc/mysql/conf.d/nextcloud.cnf.

[server]
skip_name_resolve = 1

[mysqld]
transaction_isolation = READ-COMMITTED
binlog_format = ROW
innodb_file_per_table = 1
innodb_large_prefix = on

[client]
default-character-set = utf8mb4

4. Final Nextcloud Configuration

Download and unpack the core files:

cd /usr/src
wget https://download.nextcloud.com/server/releases/latest.tar.bz2
tar -xjvf latest.tar.bz2
mv nextcloud /var/www/
chown www-data:www-data -R /var/www/

After running the web installer, configure the in-memory caching in /var/www/nextcloud/config/config.php:

  'memcache.local' => '\OC\Memcache\APCu',
  'memcache.distributed' => '\OC\Memcache\Redis',
  'memcache.locking' => '\OC\Memcache\Redis',
  'redis' => [
     'host' => '/var/run/redis/redis-server.sock',
     'port' => 0,
     'timeout' => 0.0,
  ],
  'default_language' => 'de',
  'default_locale' => 'de_DE',
  'default_phone_region' => 'DE',
  'filelocking.enabled' => true,

See Also

  • Nextcloud Documentation. Server performance tuning. https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html
  • Nextcloud Documentation. Recommended Redis setup for Nextcloud. https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/caching_configuration.html#recommended-setup
  • PHP Documentation. Runtime Configuration (Opcache). https://www.php.net/manual/en/opcache.configuration.php
  • MariaDB Documentation. Optimizing the MariaDB server for Nextcloud. https://mariadb.com/kb/en/optimizing-mariadb-server-for-nextcloud/

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.