# ownCloud 8.0 Server Administration Manual

# Server Tuning & Performance Tips

There are a number of options to tune the ownCloud installation and enable a higher level of performance. This chapter gives a few hands-on tips on configuring your database, and LAMP stack to improve performance. This chapter is community-maintained and unsupported; test these tips carefully before deploying them on production servers.

If you wish to add tips to this page, please put them in the relevant section. If there isn’t an appropriate section then start a new one.

## PHP Version and Information

You will need to know your PHP version and configurations. To do this, create a plain-text file named phpinfo.php and place it in your Web root, for example `/var/www/html/phpinfo.php`. (Your Web root may be in a different location; your Linux distribution documentation will tell you where.) This file contains just this line:

    <?php phpinfo(); ?>

Open this file in a Web browser by pointing your browser to `localhost/phpinfo.php`:

Your PHP version is at the top, and the rest of the page contains abundant system information such as active modules, active .ini files, and much more. When you are finished reviewing your information you must delete `phpinfo.php`, or move it outside of your Web directory, because it is a security risk to expose such sensitive data.

## ownCloud Server Tuning

### Serving static files via web server

See Serving Static Files for Better Performance for a description and the benefits.

### Using cron to perform background jobs

See Defining Background Jobs for a description and the benefits.

### Enable JavaScript and CSS Asset Management

See JavaScript and CSS Asset Management for a description and the benefits.

## Webserver Tips

### PHP safe mode

PHP safe mode has to be turned off. It is deprecated and has been removed in newer PHP versions. Verify its status with `phpinfo`, and look for `safe_mode on/off`. If it is on, then add this line to `php.ini` to turn it off:

    safe_mode = Off

## Raise max_file_uploads of PHP

The PHP setting `max_file_uploads` within the `php.ini` defaults to `20` on most environments which allows that number of simultaneous uploads. Currently the ownCloud sync client is doing `3` parallel uploads which means that at least `6` clients can upload files simultaneously. Depending on your server usage it is recommended to raise this number to a higher value.

### Enable the SPDY / http_v2 protocol

Your webserver can be configured to use the SPDY / http_v2 protocol which could improve the overall performance of ownCloud. Please have a look at the documentation of your webservers module for more information:

Webserver | Module Name / Link
--- | ---
Apache | mod-spdy
nginx (<1.9.5) | ngx_http_spdy_module
nginx (+1.9.5) | ngx_http_http2_module

Note

If you want to enable SPDY for Apache please note the Known Issues of this module to avoid problems after enabling it.

Note

If you want to use http_v2 for nginx you have to check two things:

1.) be aware that this module is not built in by default due to a dependency to the openssl version used on your system. It will be enabled with the `--with-http_v2_module` configuration parameter during compilation. The dependency should be checked automatically. You can check the presence of http_v2 with `nginx -V 2>&1 | grep http_v2 -o`. An example how to compile nginx can be found in section “Configure Nginx with the `nginx-cache-purge` module” below.

2.) When you have used SPDY before, the nginx config has to be changed from `listen 443 ssl spdy;` to `listen 443 ssl http2;`

## Apache Tuning

### Maximum number of Apache processes

An Apache process uses around 12MB of RAM. Apache should be configured so that the maximum number of HTTPD processes times 12MB is lower than the amount of RAM. Otherwise the system begins to swap and the performance goes down.

### KeepAlive should be configured with sensible defaults

The KeepAlive directive enables persistent HTTP connections, allowing multiple requests to be sent over the same TCP connection. This reduces latency by as much as 50%. Especially in combination with the periodic checks of the sync client the following settings are recommended:

    KeepAlive On
    KeepAliveTimeout 100
    MaxKeepAliveRequests 200

### mod_gzip

`mod_gzip` should be used because it speeds up the transfer of data and helps to free server memory, and HTTP connections are closed faster.

### MPM

Apache prefork has to be used. Don’t use threaded `mpm` with `mod_php` because PHP is currently not thread safe.

### Hostname Lookups

    # cat /etc/httpd/conf/httpd.conf
    ...
    HostnameLookups off

### Log files

Log files should be switched off for maximum performance.

Comment out the `CustomLog` directive. Keep `ErrorLog` to be able to track down errors.

## Nginx: caching ownCloud gallery thumbnails

One of the optimizations for ownCloud when using Nginx as the webserver is to combine FastCGI caching with “Cache Purge”, a 3rdparty Nginx module that adds the ability to purge content from FastCGI, proxy, SCGI and uWSGI caches. This mechanism speeds up thumbnail presentation as it shifts requests to Nginx and minimizes php invocations which otherwise would take place for every thumbnail presented every time.

The following procedure is based on an Ubuntu 14.04 system. You may need to adapt it according your OS type and release.

Note

Unlike Apache, Nginx does not dynamically load modules. All modules needed must be compiled into Nginx. This is one of the reasons for Nginx´s performance. It is expected to have an already running Nginx installation with a working configuration set up as described in the ownCloud documentation.

### Nginx module check

As a first step, it is necessary to check if your Nginx installation has the `nginx cache purge` module compiled in:

    nginx -V 2>&1 | grep ngx_cache_purge -o

If your output contains `ngx_cache_purge`, you can continue with the configuration, otherwise you need to manually compile Nginx with the module needed.

### Compile Nginx with the `nginx-cache-purge` module

1. Preparation:

    cd /opt
    wget http://nginx.org/keys/nginx_signing.key
    sudo apt-key add nginx_signing.key
    sudo vi /etc/apt/sources.list.d/nginx.list

Add the following lines (if different, replace `{trusty}` by your distribution name):

    deb http://nginx.org/packages/mainline/ubuntu/ trusty nginx
    deb -src http://nginx.org/packages/mainline/ubuntu/ trusty nginx

Then run `sudo apt-get update`

Note

If you’re not overly cautious and wish to install the latest and greatest Nginx packages and features, you may have to install Nginx from its mainline repository. From the Nginx homepage: “In general, you should deploy Nginx from its mainline branch at all times.” If you would like to use standard Nginx from the latest mainline branch but without compiling in any additional modules, just run `sudo apt-get install nginx`.

2. Download the Nginx source from the ppa repository

    cd /opt
    sudo apt-get build-dep nginx
    sudo apt-get source nginx

3. Download module(s) to be compiled in and configure compiler arguments

    ls -la

Please replace `{release}` with the release downloaded:

    cd /opt/nginx-{release}/debian

If folder “modules” is not present, do:

    sudo mkdir modules
    cd modules
    sudo git clone https://github.com/FRiCKLE/ngx_cache_purge.git
    sudo vi /opt/nginx-{release}/debian/rules

If not present, add the following line at the top under:

    #export DH_VERBOSE=1:
    MODULESDIR = $(CURDIR)/debian/modules

And at the end of every `configure` command add:

    --add-module=$(MODULESDIR)/ngx_cache_purge

Don’t forget to escape preceeding lines with a backslash `\`. The parameters may now look like:

    $(WITH_SPDY) \
    --with-cc-opt="$(CFLAGS)" \
    --with-ld-opt="$(LDFLAGS)" \
    --with-ipv6 \
    --add-module=$(MODULESDIR)/ngx_cache_purge

4. Compile and install Nginx

    cd /opt/nginx-{release}
    sudo dpkg-buildpackage -uc -b
    ls -la /opt
    sudo dpkg --install /opt/nginx_{release}~{distribution}_amd64.deb

5. Check if the compilation and installation of the ngx_cache_purge module was successful

    nginx -V 2>&1 | grep ngx_cache_purge -o

It should now show: `ngx_cache_purge`

Show Nginx version including all features compiled and installed:

    nginx -V 2>&1 | sed s/" --"/"\n\t--"/g

6. Mark Nginx to be blocked from further updates via apt-get

    sudo dpkg --get-selections | grep nginx

For every nginx component listed run `sudo apt-mark hold <component>`

7. Regular checks for nginx updates

Do a regular visit on the Nginx news page and proceed in case of updates with items 2 to 5.

### Configure Nginx with the `nginx-cache-purge` module

1. Preparation Create a directory where Nginx will save the cached thumbnails. Use any path that fits to your environment. Replace `{path}` in this example with your path created:

    sudo mkdir -p /usr/local/tmp/cache

2. Configuration

    sudo vi /etc/nginx/sites-enabled/{your-ownCloud-nginx-config-file}

Add at the beginning, but outside the `server{}` block:

    # cache_purge
    fastcgi_cache_path {path} levels=1:2 keys_zone=OWNCLOUD:100m inactive=60m;
    map $request_uri $skip_cache {
         default 1;
         ~*/thumbnail.php 0;
         ~*/apps/galleryplus/ 0;
         ~*/apps/gallery/ 0;
    }

Note

Please adopt or delete any regex line in the `map` block according your needs and the ownCloud version used.

Note

As an alternative to mapping, you can use as many `if` statements in your server block as necessary:

    set $skip_cache 1;
    if ($request_uri ~* "thumbnail.php")      { set $skip_cache 0; }
    if ($request_uri ~* "/apps/galleryplus/") { set $skip_cache 0; }
    if ($request_uri ~* "/apps/gallery/")     { set $skip_cache 0; }

Add inside the `server{}` block, as an example of a configuration:

    # cache_purge (with $http_cookies we have unique keys for the user)
    fastcgi_cache_key $http_cookie$request_method$host$request_uri;
    fastcgi_cache_use_stale error timeout invalid_header http_500;
    fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

    location ~ \.php(?:$/) {
          fastcgi_split_path_info ^(.+\.php)(/.+)$;

          include fastcgi_params;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          fastcgi_param PATH_INFO $fastcgi_path_info;
          fastcgi_param HTTPS on;
          fastcgi_pass php-handler;

          # cache_purge
          fastcgi_cache_bypass $skip_cache;
          fastcgi_no_cache $skip_cache;
          fastcgi_cache OWNCLOUD;
          fastcgi_cache_valid  60m;
          fastcgi_cache_methods GET HEAD;
          }

Note

Note regarding the `fastcgi_pass` parameter: Use whatever fits your configuration. In the example above, an `upstream` was defined in an Nginx global configuration file. This may look like:

    upstream php-handler {
        server unix:/var/run/php5-fpm.sock;
        # or
        # server 127.0.0.1:9000;
      }

3. Test the configuration

    sudo nginx -s reload

- Open your browser and clear your cache.
- Logon to your ownCloud instance, open the gallery app, move thru your folders and watch while the thumbnails are generated for the first time.
- You may also watch with eg. `htop` your system load while the thumbnails are processed.
- Go to another app or logout and relogon.
- Open the gallery app again and browse to the folders you accessed before. Your thumbnails should appear more or less immediately.
- `htop` will not show up additional load while processing, compared to the high load before.

### Database Best Practice

Currently ownCloud supports the following relational database management systems:

- MySQL
- MariaDB
- PostgreSQL
- SQLite
- Oracle

SQLite is not supported in the Enterprise edition, and is not recommended except for systems with very light workloads, and for testing ownCloud.

We are using the doctrine database abstraction layer and schema evolution with a MDB2 Schema based table description in XML.

### Using MariaDB/MySQL instead of SQLite

MySQL or MariaDB are preferred because of the performance limitations of SQLite with highly concurrent applications, like ownCloud.

On large instances you could consider running MySQLTuner to optimize the database.

See the section Database Configuration for how to configure ownCloud for MySQL or MariaDB. If your installation is already running on SQLite then it is possible to convert to MySQL or MariaDB using the steps provided in Converting Database Type.

### Improve slow performance with MySQL on Windows

On Windows hosts running MySQL on the same system changing the parameter `dbhost` in your `config/config.php` from `localhost` to `127.0.0.1` could improve the page loading time.

See also this forum thread.

### Other performance improvements

Mysql: compare https://tools.percona.com/wizard to your current settings MariaDB: https://mariadb.com/kb/en/optimization-and-tuning/

### Postgresql

Alternative to MariaDB/MySQL. Used in production by a few core developers.

Requires at least Postgresql 9.0

## Other performance improvements

See http://wiki.postgresql.org/wiki/Performance_Optimization

### Oracle Database

Usage scenario: Existing enterprise installations. Only core apps are supported and tested. Not recommended because it involves compiling the oci8

## Other performance improvements

http://de.slideshare.net/cjorcl/best-practices-php-and-the-oracle-database and ask your DBA.

## Problems

When ORA-56600 occurs (Oracle Bug 8467564) set this php.ini setting: oci8.statement_cache_size=1000, see oracle forum discussion

## SSL / Encryption App

SSL (HTTPS) and file encryption/decryption can be offloaded to a processor’s AES-NI extension. This can both speed up these operations while lowering processing overhead. This requires a processor with the AES-NI instruction set.

Here are some examples how to check if your CPU / environment supports the AES-NI extension:

- For each CPU core present: `grep flags /proc/cpuinfo` or as a summary for all cores: `grep -m 1 ^flags /proc/cpuinfo` If the result contains any `aes`, the extension is present.

- Search eg. on the Intel web if the processor used supports the extension Intel Processor Feature Filter You may set a filter by `"AES New Instructions"` to get a reduced result set.
- For versions of openssl >= 1.0.1, AES-NI does not work via an engine and will not show up in the `openssl engine` command. It is active by default on the supported hardware. You can check the openssl version via `openssl version -a`
- If your processor supports AES-NI but it does not show up eg via grep or coreinfo, it is maybe disabled in the BIOS.
- If your environment runs virtualized, check the virtualization vendor for support.