It used to be recommended back with Nextcloud 11 that you mount your php session as a tempfs in ram to speed things up. Does anyone know if this is still recommended for Nextcloud 16? If you have Redis installed doesn’t that already sort of take care of caching the session in RAM?
I’d start with tuning of your caching via redis and database. Especially the database can make huge difference compared to standard setups. In the temp-folder, I think during the partial upload some files snippets are stored there. But before you put everything on RAMdisk, I’d do a few large uploads and check the system performance with iotop. Mostly it is the database which creates too much i/o-load which can be reduced with redis and proper caching settings.
I’m familiar with tuning the innodb_buffer_file_size as well as the opcache and apc.shm_size for APCu. Other than running redis over a socket I’m not sure of any other tuning I can do.
When you monitor with iotop are you mostly just checking to make sure nothing is going into swap?
What you did already covers all I wound recommend: APCu + Redis + MariaDB cache tuning.
Not sure what you initially meant by running the session in RAM:
- Webserver and PHP are already running in RAM, the environment and sockets etc. The only thing that could be additionally done is moving the tmp PHP upload dir to RAM, if not yet the case, however that can fill RAM based on the size of uploaded files
and I am not even sure if/how this is used by Nextcloud, at least I could never monitor any writes to the tmp upload dir when uploading files via web UI, but to the Nextcloud data dir directly instead.(EDIT: At least when uploading via desktop client, each uploaded file is indeed temporarily created in
upload_tmp_dir, which defaults to
- The database itself should not be moved to RAM (and e.g. synced to disk as shutdown task) to avoid loss of data (calendar, file tags/meta data/index, …) in case of server crash. Instead keep it on a fast drive, e.g. SSD.
Thanks for explaining all that. I feel like I understand a bit more.
The PHP Session I was referring to is the one referenced here, not the database itself:
Ah I guess you’re referring to the
session.save_path, which indeed defaults to
/tmp, which is a tmpfs by default on Debian. Since the default systemd unit for Apache and PHP-FPM used
private-tmp=true, you’ll find the actual dir in some
/tmp/apache-<random_string> sub dir.
In my Ubuntu I can find
/etc/php/7.2/apache2/php.ini I find
session.save_path = "/var/lib/php/sessions"
So shouldn’t it be defaulting to
You are right, I did not have a close enough look at this. Indeed in my case as well I see session files being created in that dir. This is strange since due to PHP docs,
/tmp is default:
And in my case all settings are commented, so the default should apply
2019-08-08 12:40:04 root@micha:/var/lib/php/sessions# grep -r 'session.save_path' /etc/php/ /etc/php/7.3/apache2/php.ini:; session.save_path = "N;/path" /etc/php/7.3/apache2/php.ini:; session.save_path = "N;MODE;/path" /etc/php/7.3/apache2/php.ini:;session.save_path = "/var/lib/php/sessions" /etc/php/7.3/apache2/php.ini:; (see session.save_path above), then garbage collection does *not* /etc/php/7.3/cli/php.ini:; session.save_path = "N;/path" /etc/php/7.3/cli/php.ini:; session.save_path = "N;MODE;/path" /etc/php/7.3/cli/php.ini:;session.save_path = "/var/lib/php/sessions" /etc/php/7.3/cli/php.ini:; (see session.save_path above), then garbage collection does *not*
Reading a bid it seems that it is by distro not moved to
/tmp by default, since this can be a security issue when other processes are able to read those. However since Apache has provate-tmp, this is not an issue, so
session.save_path=/tmp is something that can and should be set. I just do on my system and verify behaviour.
EDIT: Jep as it should, session files are created in
/tmp/systemd-private-<random_string>-apache2.service-<random_string>/tmp now. Confused why this is not default. But to be true these session files are small (single line) and neither performance nor disk I/O should significantly enhance by this.
Thank you for spending the time to clarify all that @MichaIng
I think I found the same info about the
session.save_path locations here:
So since it doesn’t really impact performance I guess there is no reason to recommend setting it to
/tmp in the Nextcloud Admin Manual.
On the other hand many guides about PHP tuning mention that these should be set to a tmpfs or handled via Redis for larger multi system environments. I guess it depends on how heavy the server is in use, thus how many files are actually created between the 30 minutes when the phpsessionclean systemd timer cleans them. And as it does not hurt, at least with private-tmp it definitely makes sense and has no downside.
I’m going to summarize everything here in case anyone else is wondering about this. Maybe something should be added to the Nextcloud Admin Manual on this.
PHP Session Files
PHP Sessions allow web pages to be treated as a group, allowing variables to be shared between different pages.
Session files offer a secure alternative to cookies and even work when the user has disabled the browser’s cookie support.
Many performance/tuning guides recommend storing session files in a RAM file or using redis as a session handler.
Recommendations for Nextcloud:
Single-server Deployment: Store sessions in files on a tmpfs so they reside in RAM.
Multi-server Deployment: Use redis as it offers both a RAM cache and persistence on disk. In a multi-server environment redis allows the same session data to be available regardless of which application server serves an individual request.
PHP session files on tmpfs
Linux distros can have various default locations for the
session.save_path found in the
If php is compiled from source the default location will be
In some distros
/tmp is mounted as as a
tmpfs in RAM.
if this is the case you can just set the
/tmp in your
To check for tmpfs mounts:
mount | grep -i tmp
Note: storing session files in
/tmp can be a security concern if other users can access those files.
Apache’s default systemd unit sets
This setting keeps these files private.
/tmp is not mounted as a
tmpfs (as in the case of Ubuntu 18.04) then one solution is to find the current
session.save_path and mount it as
To find the default
session.save_path you can create a
phpinfo() file in your webroot directory or use the following command:
grep -R 'session.save_path' /etc/php*
In the output look for the
apache2/php.ini file if using apache.
session.save_path will likely be commented out with a
; but this is still the default location.
Under Ubuntu 18.04 this will be
Add the following to your
/etc/fstab and then reboot the system:
tmpfs /var/lib/php/sessions tmpfs defaults,noatime,mode=1777 0 0
To check that correct permissions were set after reboot:
stat -c "%a %n" /var/lib/php/sessions
PHP session handled by redis socket
If you are connecting multiple servers to your redis server you will not be using a socket. This site might help: https://www.digitalocean.com/community/tutorials/how-to-set-up-a-redis-server-as-a-session-handler-for-php-on-ubuntu-16-04
To set up with a socket, add the following to
Make sure to replace
your-password with the values from your system.
session.save_handler = redis session.save_path = "unix:///var/run/redis/redis.sock?auth=your-password&persistent=1&weight=1&database=0"
Restart apache and redis.
Btw about the last part: You don’t need to edit both,
redis.ini since the latter just overrides the first. Add those lines to redis.ini only, to have is enabled/disabled together with the required module and leave php.ini untouched. Or use an own drop-in config or mod to manage custom settings and leave all default files untouched.
Thanks. I made that change.
I found a reason why PHP session files in
/tmp does not work well on most systems:
- The Apache and PHP-FPM systemd units (services) contain
- This protects their tmp files from other services and prevents double uses, but it means that no other process sees the same files when looking in
phpsessionclean.servicenow has no chance to find and clean PHP session files. It has
PrivateTmp=trueitself, hence PHP handler and
phpsessioncleanboth need to have this removed, which then again breaks the security and isolation benefit…
So the only chance I see then is to use another or own tmpfs instead and either mount it or chown a subdir with root:root 1733 to only allow root full access and www-data write access only (like default