Hello,
I’ve previously opened a support therad about upload speeds being very slow and causing a lot of disk thrashing, here. I’ve previously scoured the internet trying to find a solution but couldn’t figure it out. I never really got back to resolving it until very recently. With the help of Claude I was able to figure out the problem and find a solution. The original thread has been locked due to inactivity, so I am posting this thread so others may find it helpful, and also to get any feedback from other sysadmins to see if there’s something I may have missed.
It turns out that the core issue is that I’m running mariadb on a btrfs partition with CoW and checksumming enabled. This configuration is particularly problematic, because mariadb requires frequent syncing to disk to remain ACID compliant and to guard against corruption in case of power loss, and btrfs with my configuration in particular introduces a lot of latency for each disk write commit. If I upload a lot of small files, this results in a lot of logs and database updates per file, which means probably hundreds or thousands of commits. Btrfs with this configuration is particularly slow at commiting changes to disk due to its checksumming and CoW nature. As a result, each file took several seconds to commit, which meant uploading a lot of files becomes unbearably slow. Btrfs is not the right filesystem to use with a database apparently, but it’s too late for me to reformat.
To fix this without reformatting, in the mariadb configuration, I’ve set innodb_flush_log_at_trx_commit to 2. This makes it so that mariadb would commit every second, instead of every transaction. I have a UPS, so any issue caused by power loss should be unlikely. I am also a home user, so my requirements aren’t as stringent as a business. This has made a night and day difference for me. Apart from uploads, nextcloud in general has felt much faster and responsive than before as a result and it made a big difference for me.
In my case, I’m using docker, and I’ve set things up using Marius’s guide to hosting nextcloud on Synology. So to do this, I added --innodb-flush-log-at-trx-commit=2 at the end of the command: line in my docker compose file.
Of course the real fix is to put the database somewhere else, something not btrfs based. Or maybe to put it on an SSD. But this should do for now.
I hope this helps people.