Pihole & Nextcloud: Reducing CPU load

Hello!

I’m currently running Nextcloud on a Raspberry Pi 4. I’m aware that a Pi isn’t the strongest computer, and I notice that cpu load goes up very fast if I’m trying to download big files (600+ mb). Peak load was about 7. This goes so far that I can’t access any other websites if the load is too high (I assume it’s because I’m running Pihole and Unbound on the same Pi, and no DNS request gets through). After a while, the download starts as expected and fast. I assume this is because nextcloud has to prepare the file to be downloaded somehow, which drains ressources.

Is there a way to reduce the load on the Pi while downloading big files? I tried limiting download speed, but it didn’t help. The data is stored on an external HDD with its own power source. I wouldn’t mind if it took longer to download, I just don’t want it to influence the Pihole/Unbound (if that’s the source of the error). Or is there a way to dedicate one core to Pihole/Unbound, so that that one does not get used by other programs?

Nextcloud is a web app, so it runs with lighttpd, mariadb/mysql and php. You could check with htop which process consumes the most process time while you copy large files and them just lower the process priotity in dietpi-services.
But keeps in mind, this also effects other services and applications which depend on lighttpd, mysql or php.

Or on the other hand ,you could just icnrease the process priority of unbound and PiHole and see if this already helps.

I tried loading a ~900mb video file while watching htop.

Most of the time, it looked like the attached “htop1”, with occasional spikes (about 1 frame, rarely 2 or 3) from php-fpm and lighttpd (htop2 and htop3). You can also see that the short-term load is >4.

While doing this, the connection to nextcloud crashed (timeout) (this usually happens when loading big files) and the other (probably related?) problem with connecting to websites appeared. After a while, the download picked up again.



It might be I/O related. You could use iostat and/or iotop to watch how it is behaving while downloading larger files.

To install

apt install sysstat iotop

To check

iotop -o
iostat -x 1

https://www.baeldung.com/linux/monitor-disk-io

iotop showed nothing unexpected, but iostat (I’m only pasting one part of the output)

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz     f/s f_await  aqu-sz  %util
mmcblk0          0.00      0.00     0.00   0.00    0.00     0.00   15.00   5160.00     0.00   0.00 2670.60   344.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00    0.00   40.06  96.80
sda              0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00    0.00    0.00   0.00


avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.00    0.00    0.75   74.19    0.00   25.06

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz     f/s f_await  aqu-sz  %util
mmcblk0          0.00      0.00     0.00   0.00    0.00     0.00    9.00   3096.00     0.00   0.00 3623.33   344.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00    0.00   32.61  74.80
sda              0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00    0.00    0.00   0.00


avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.25    0.00    0.25   74.62    0.00   24.87

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz     f/s f_await  aqu-sz  %util
mmcblk0          0.00      0.00     0.00   0.00    0.00     0.00    1.00    512.00    46.00  97.87 4861.00   512.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00    0.00    4.86  92.40
sda              0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00    0.00    0.00   0.00


avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.00    0.00    0.50   74.50    0.00   25.00

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz     f/s f_await  aqu-sz  %util
mmcblk0          0.00      0.00     0.00   0.00    0.00     0.00    4.00   1544.00     0.00   0.00 5519.25   386.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00    0.00   22.08  53.60
sda              0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00    0.00    0.00   0.00


avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.25    0.00    0.50   74.25    0.00   25.00

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz     f/s f_await  aqu-sz  %util
mmcblk0          0.00      0.00     0.00   0.00    0.00     0.00    1.00      8.00     0.00   0.00 6950.00     8.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00    0.00    6.95 130.00
sda              0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00    0.00    0.00   0.00


avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.25    0.00    0.50   74.25    0.00   25.00

%iowait is near 100% sometimes, and %util for mmcblk0 is >100% sometimes. Is that the internal MicroSD? Would switching to a faster one help here?

I guess data are copied from HDD to some cache located on SD card to prepare the download. A faster SD card might reduce the effect but I guess it will still take the resources, even if it might be shorter. Another option is to have the entire system located on a USB drive. It should be faster compare to SD card. For testing, you could clone your SD card into a USB3 pen stick and boot from it. It might give some performance increase.

As another alternative, you could ask on the Nextcloud forum if there is a way to avoid these caching within the web browser/php stack.

Pi-hole has a higher priority assigned already, but Unbound not. You could try to set the nice level to e.g. -10 for Unbound via dietpi-services so that it has higher CPU and I/O priority than webserver, database and PHP.

Pi-hole and Unbound btw both require nearly no system resources. So it is really (as can be seen in htop) PHP and the database while the Nextcloud web interface is accessed, which peak so high. This can be also adjusted, e.g. by assigning only 3 of the 4 CPU cores to the php7.4-fpm service (CPU affinity) so that one core is always free for Pi-hole and Unbound. For I/O, apart of nice level, there are other options as well, but I don’t think that this is the major issue here.

I set unbounds nice level to -10, and assigned cores 1-3 to php7.4-fpm. Using the same ~900mb file as before, the load goes up to ~5.5 in the beginning, later it goes up to ~7, and visiting websites still crashes. The download itself runs smoother though, no crashes in the nextcloud client. The behaviour of htop is the same as in my other post (except core 0 is not spiking with the others). Overall, it seems to run smoother already, thank you!

what could further help would be to move the temp upload folder of the web server to your HDD. Might be improving I/O.

Would that be “tempdirectory” in /var/www/nextcloud/config/config.php ? It’s not in there yet, but the nextcloud docs say that it’s the parameter to “Override where Nextcloud stores temporary files.”

I’d just add

'tempdirectory => '/mnt/hdd/tmp',

and then it should take my external hdd as the temp file location? (/mnt/hdd is the mount point for my hdd)

I did some reading and it looks like this will not really solve anything. https://github.com/nextcloud/server/issues/19682

At least on my test, uploads are stored in chunks inside /mnt/dietpi_userdata/nextcloud_data/admin/uploads

root@DietPi3:~# ls -latr /mnt/dietpi_userdata/nextcloud_data/admin/uploads/web-file-upload-2c01c5374f030cfb937fa89d31ba2a99-1650278500775
total 296968
drwxr-xr-x 3 www-data www-data     4096 Apr 18 12:41 ..
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:48 713031680
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:48 723517440
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:48 734003200
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:48 744488960
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:48 754974720
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:48 765460480
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:48 775946240
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:48 786432000
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:48 796917760
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:48 807403520
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:48 817889280
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:48 828375040
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:48 838860800
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:49 849346560
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:49 859832320
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:49 870318080
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:49 880803840
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:49 891289600
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:49 901775360
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:49 912261120
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:49 922746880
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:49 933232640
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:49 943718400
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:50 954204160
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:50 964689920
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:50 975175680
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:50 985661440
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:50 996147200
-rw-r--r-- 1 www-data www-data 10485760 Apr 18 12:51 1006632960
drwxr-xr-x 2 www-data www-data     4096 Apr 18 12:51 .
root@DietPi3:~#

How much memory does your RPi has?

There is a tmp upload directory for PHP, used (AFAIK) when uploading files via web interface (not when done via Nextcloud clients). That is set to /tmp tmpfs, so moving that to disk should worsen things and has no effect when just browsing the Nextcloud interface.

EDIT: Ah whoops, you found that Nextcloud internal upload dir already. I wasn’t sure whether this is used by Nextcloud as override for the PHP tmp upload dir, and it seems so. I wanted to find this in the docs but found part_file_in_storage which defaults to true and states again differently: https://docs.nextcloud.com/server/stable/admin_manual/configuration_server/config_sample_php_parameters.html
Confusing :thinking:.

Sounds like the php temp path needs to be changed?

It’s a Pi 4, htop lists it at 3.75G. Even when loading huge files, the whole memory isn’t used.

hmm at least for me uploads are done to /mnt/dietpi_userdata/nextcloud_data/admin/uploads where they are stored until upload is complete. Afterwards they got assembled into the target file on target location.


Let me link myself as I’m to lazy to type thinks twice. This is basically similar to the other topic

https://dietpi.com/forum/t/nextcloud-slow-upload-and-freezing-when-uploading-big-files/6518/12

Copying my edit from above:

EDIT: Ah whoops, you found that Nextcloud internal upload dir already. I wasn’t sure whether this is used by Nextcloud as override for the PHP tmp upload dir, and it seems so. I wanted to find this in the docs but found part_file_in_storage which defaults to true and states again differently: https://docs.nextcloud.com/server/stable/admin_manual/configuration_server/config_sample_php_parameters.html
Confusing :thinking:.

It’s a Pi 4, htop lists it at 3.75G. Even when loading huge files, the whole memory isn’t used.

What is the largest file you are trying to upload? And is it a single user who is uploading large files? Or are their multiple user who will do this? Because an idea would be to move the upload folder into memory. Bu there you are limited due to the physical ram size. It might be an option if files you upload will not be bigger than 2GB.

On 32-bit images, the max upload size is limited to 2 GiB anyway. Although with the now chunked uploads I’m not 100% sure if this is still true. See the Nextcloud docs about this: https://docs.nextcloud.com/server/stable/admin_manual/configuration_files/big_file_upload_configuration.html

In the info box it says that chunks are used by the Nextcloud client, not including web interface uploads :thinking:.

Just to be clear, Uploading is no problem, just Downloading.

To be sure, I tried uploading a 3.46 GB file via the nextcloud desktop app for windows (I moved the file into a folder and waited). lighttpd and php-fpm shoot up from time to time, but internet still works fine, and the download goes smoothly, too. Load stays <3.00.

Downloading, I right-click the file in the folder and choose “Always keep on this device”. Doing this on a ~900mb file leads to the behaviour described in this thread. This happens on several devices, even if there are no other uploads/downloads at the same time.

Do you use a reverse proxy?