NextCloudPi‘s target audience is domestic hosters and one of the use cases that attracts users is to self-host their own picture collection.
The main complaint for such users is that gallery is too slow. When you open the gallery previews are generated on the fly which affects responsiveness. Once they are generated, the next time it will load much faster.
The current solution is to generate the previews offline through a cron job using the Preview Generator App so that they are ready to be fetched when we open the Gallery.
Even when using this App browsing our pictures is usually very slow. This happens typically for the following reasons
- Lack of computing power. SBCs are not very powerful.
- Misconfigured preview sizes (and lack of documentation thereof).
Even using the Preview Generator, it can take days or even weeks on a Raspberry Pi to generate the previews for a big collection which throws many people off.
Another complaint is that too many previews are generated so often the previews folder takes even more space that the pictures themselves.
The most obvious low hanging fruit to try to deal with this issue is noticing the fact that even though our systems are multi processor, only one CPU is used to generate the previews so there are plenty unutilized resources available that are not being used.
First, let’s take a quick look at the Nextcloud Previews system.
How previews work
Every time we upload an image two previews are generated
- Small 32×32 preview. This is the icon in the Files list.

- Max preview. This is the big picture that shows in the browser when you click on it.

The Max preview size defaults to 4096×4096, and can be configured with
occ config:system:set preview_max_x --value 2048 occ config:system:set preview_max_y --value 2048
This produces
root@293626d9121d:/var/www/nextcloud# ls -R data/appdata_ocn7c0nrnm7u/preview/* data/appdata_ocn7c0nrnm7u/preview/63405: 1365-2048-max.jpg 256-256-crop.jpg
There are other previews that are not generated by default but are used by other parts of Nextcloud. These will be generated on the fly unless they are pregenerated with the App.
- The Gallery App requests (js/thumbnail.js)
- 400×200 -> 384×256 / 256×384 (**) for regular thumbnails.
- 200×200 -> 256×171 / 171×256 for folder thumbnails, which shows the first four square thumbnails of the directory.

- The Files App in grid view mode requests (js/filelist.js)
- 250×250 -> 256×256

(*) it requests 400×200 but the backend rounds it up to powers of two -> 384×256. These are examples only.
(**) depending on photo orientation
How the Preview Generator works
We can see that we need a properly configured Preview Generator or we might be generating previews that are useless since they are not going to be used.
By default the App generates all possible sizes from 32×32 to Max which is both a waste of CPU and space since as we just saw many of those won’t be used.
root@293626d9121d:/var/www/nextcloud# ls -R data/appdata_ocn7c0nrnm7u/preview/* data/appdata_ocn7c0nrnm7u/preview/63405: 1024-1024-crop.jpg 171-256.jpg 256-384.jpg 2731-4096-max.jpg 64-64-crop.jpg 683-1024.jpg 1024-1536.jpg 256-256-crop.jpg 2731-2731-crop.jpg43-64.jpg 64-96.jpg
If we don’t want this behavior, the App allows us to configure what sizes we want to generate, but it is not documented anywhere what sizes are really needed unless you dig in the code. To configure this setting
occ config:app:set previewgenerator squareSizes --value="32 256" occ config:app:set previewgenerator widthSizes --value="256 384" occ config:app:set previewgenerator heightSizes --value="256"
So we end up with either people complaining that the previews take more GiB than the actual photos or people naively trying different sizes assuming that they will be used when they will most likely not be.
Recommended configuration
For the reasons stated above, I recommend the following settings for a SBC
occ config:app:set previewgenerator squareSizes --value="32 256" occ config:app:set previewgenerator widthSizes --value="256 384" occ config:app:set previewgenerator heightSizes --value="256" occ config:system:set preview_max_x --value 2048 occ config:system:set preview_max_y --value 2048 occ config:system:set jpeg_quality --value 60 occ config:app:set preview jpeg_quality --value="60"
In my opinion these should be the default settings for the Preview Generator App.
root@293626d9121d:/var/www/nextcloud# ls -R data/appdata_ocn7c0nrnm7u/preview/* data/appdata_ocn7c0nrnm7u/preview/63405: 1365-2048-max.jpg 171-256.jpg 256-256-crop.jpg 256-384.jpg 64-64-crop.jpg
Just configuring the Preview Generator properly results in a 4x speed up and saves lots of wasted space (see results below).
Proposal
In order to try to find a way of using our CPUs more efficiently and to improve performance on low end devices, I forked Nextcloud and the Previews Generator App to create a Proof of Concept implementation that I could run some tests on.
We don’t need very good quality using computationally expensive filters for the small thumbnails, maybe only for the Max preview, so the proposal plays with scaling without interpolation and parallel generation to try to achieve better results.
Using these modifications I was able to achieve a 5x speed up in a 4 core Raspberry Pi and a 10x speed up in my 16 core PC while retaining good image quality.
If we compare with an unconfigured Preview Generator the gain is 20x for the Raspberry Pi and 50x for the PC (see Github link).

You can check more details about these benchmark results on Github.
“Max preview. This is the big picture that shows in the browser when you click on it.”
==>> Do you mean that when playing a slide show, the pictures shown are NOT the actual pictures but generated ones ????
If so, what a wast of power and space.
And I understand why, with fiber connection at home (on a Rock 64), it take ages to display pictures when I’m away.
that is correct. There is a lot of room for improvement IMO
Can I disable max previews so that it shows the original picture? Would safe a lot of space and generation time…
Makes sense to me, you view the generated ones in the browser, and download the full resolution if you choose to.
This is great, thanks so much for this and the work you’ve done. I will give it a try on my docker container, hopefully it will speed it up as well.
Let us hope that Rullzer will include these enhancements in the official app. π
Just one thought. When running php-fpm, then the server does spawn several threads to generate thumbnails. Still extremely slow.
only when you browse the gallery since there are several requests in parallel, but the preview generator only uses one thread (before my changes).
hello,
where and how can i change the directorie’s to preview, not every directory should be shown as a preview or only 2 to 3 specific directories would be in this site !? thanks for your help
you can add a `.nomedia` file for those folders where you don’t want pregeneration of previews
big thanks. that is what i was looking for about two weeks, finally solved.
I am not quite sure I understand the commands above right π
First of all, should I use the commands in the two boxes in the “How the Preview Generator works” section or are those just explanatory?
Second of all, when I ssh into my FreeNAS nextcloud jail and try to run occ config:app:set previewgenerator squareSizes –value=”32 256″ I get an error occ: Command not found.
What am I doing wrong? Thanks in advance for your help!
You can read about the occ command in the Nextcloud documentation
In your ssh session to Nextcloud jail:
cd /usr/local/www/nextcloud
run all command like
sudo -u www php occ config:app:set previewgenerator squareSizes βvalue=β32 256β³
Thank you for your wonderful post. However there seems to be another bug which makes Nextcloud super slow: it is trying to make previews of mp3-s which takes minutes for just one mp3. I have a fresh Nextcloudpi setup (on a Raspi 3), uploaded a directory with a few mp3-s using webdav, and then visit that directory with the Nextcloud ios app without clicking on any file. These lines appear in /var/log/apache2/nc-access.log:
10.10.11.177 – – [21/Jul/2019:10:34:34 +0100] “GET /index.php/core/preview.png?file=body%20mind%20soul/bl%20purpose.mp3&x=576&y=768&a=1&mode=cover HTTP/2.0” 404 0 “-” “Mozilla/5.0 (iOS) Nextcloud-iOS/2.23.7” ~126/126258422~
10.10.11.177 – – [21/Jul/2019:10:34:34 +0100] “GET /index.php/core/preview.png?file=body%20mind%20soul/bl%20ml%201of2.mp3&x=576&y=768&a=1&mode=cover HTTP/2.0” 404 0 “-” “Mozilla/5.0 (iOS) Nextcloud-iOS/2.23.7” ~126/126590957~
10.10.11.177 – – [21/Jul/2019:10:34:34 +0100] “GET /index.php/core/preview.png?file=body%20mind%20soul/bl%20med.mp3&x=576&y=768&a=1&mode=cover HTTP/2.0” 404 0 “-” “Mozilla/5.0 (iOS) Nextcloud-iOS/2.23.7” ~126/126603509~
10.10.11.177 – – [21/Jul/2019:10:34:34 +0100] “GET /index.php/core/preview.png?file=body%20mind%20soul/bl%20law%20of%20life.mp3&x=576&y=768&a=1&mode=cover HTTP/2.0” 404 0 “-” “Mozilla/5.0 (iOS) Nextcloud-iOS/2.23.7” ~126/126610499~
~126/126610499~ means that it ran 126 seconds (and 126610499 us to be precise)
Hi, thank you. You should report that
Hello!
Is it possible to generate previews for videos like .mp4 or even .gif?
Im using the cronjob from the nextcloudpi webpanel, pictures are no problem its really smooth with my rpi 4.
In my gallery i got 4 folders filled with pictures. But there should be 3 more folders filled with videos and gifs.
One of the working gallery folders got 1 gif data and is even pre generated. I just cant understand why the other folders aren’t pre generated.
Would be nice if someone could help me, i saw that this site is really active in the comments!
Ty and have a nice day!
Julian
Hello,
Follow steps:
https://www.allerstorfer.at/nextcloud-install-preview-generator/
In Raspbian:
sudo apt-get install ffmpeg
add /usr/bin/ffmpeg to your env[PATH]
in /etc/php/7.3/fpm/php-fpm.conf
Very Cool! Thanks, after setting app as here written and “reset” the preview cache, there are following files were generated:
/preview/1020200:
total 444
drwxrwxr-x 2 www-data www-data 4096 Jul 24 21:26 .
drwxrwxr-x 13403 www-data www-data 274432 Jul 25 09:03 ..
-rw-rw-r– 1 www-data www-data 128154 Jul 24 21:26 1080-1920-max.jpg
-rw-rw-r– 1 www-data www-data 6133 Jul 24 21:26 144-256.jpg
-rw-rw-r– 1 www-data www-data 9542 Jul 24 21:26 256-256-crop.jpg
-rw-rw-r– 1 www-data www-data 14211 Jul 24 21:26 256-455.jpg
-rw-rw-r– 1 www-data www-data 1618 Jul 24 21:26 64-64-crop.jpg
OLD Preview Folder is bigger and has less files in it:
preview/1020200:
total 1228
drwxr-xr-x 2 www-data www-data 4096 Jan 14 2019 .
drwxrwxr-x 39159 www-data www-data 933888 Jul 24 14:00 ..
-rw-r–r– 1 www-data www-data 309785 Jan 14 2019 1080-1920-max.jpg
-rw-r–r– 1 www-data www-data 1279 Jan 14 2019 32-32-crop.jpg
I think that the correct settting for the jpeg_quality should be
occ config:app:set preview jpeg_quality –value=”60″
I have outlined why in this post: https://help.nextcloud.com/t/thumbnail-quality-setting-is-wrong-undocumented/56435/
Basically you need to look at the Nextloud source code to that the correct setting for jpeg_quality is not the same as for the previewgenerator app.
Great catch thanks. Fixed
Thanks so much for tracking down why Nextcloud can sometimes be so very painfully slow an SBC’s. SBC’s being constrained hardware will indeed reveal where the obvious wastages and bottlenecks and inefficiencies are. Thanks for all your awesome contributions, NachoParker!
Thanks, very insightful!
I did notice that on my Nextcloud (not NextCloudPi) instance, 1024×1024 thumbs are requested for the 32×32 images in the files list. So with your recommended settings, it’s still creating 1024×1024 thumbs on the fly. Is this configurable somewhere? Or is this different for NextCloudPi vs regular Nextcloud? In any case with 1024 added to the `squareSizes` setting, no thumbs are created on the fly anymore so that’s great!
Thanks a lot man. I’ve always had the impression that nextcloud is creating previews when a folder is opened the first time, even though the preview generate plugin was installed. But i’ve never hat time to look into it.
Now everything loads perfectly smooth!!!!
Did you fill out but reports about the different picture sizes? I’ve only could find the push request for the parallel preview generation. Since a lot of users would assume that the preview generation plugin does everything correctly, most would never get the idea to look further into it.
Thanks for the nice report.
If you’re running NC on a brick, you may want to consider browser caching for thumbnails, see https://github.com/nextcloud/documentation/pull/1609
Thank you – this has made a significant difference to generation times and responsiveness.
291/5000
Thank you very much for this guide. My Nextcloud works on a selfmade NAS with Celeron processor, where the preview generation takes ages with default settings. These settings have greatly accelerated the creation of the previews and, above all, the retrieval of images from the phone or web access.
I just noticed it was the previews folder that had filled up my drive, and searching for a solution lead me right here. Thanks for the write-up! One follow-up: I want to start over from scratch, can I just delete that preview folder, or what?
you can delete the folder and run `occ files:scan-app-data`
I’m generally curious how imageflow (https://github.com/imazen/imageflow) would perform compared to the setup used here.
Thank you so much for writing this up! This was causing me a lot of issues.
For nc-previews-auto, it says, “You can specify a nightly duration in minutes, or 0”
How can I determine what time it begins the process nightly? I have other backups and need to stagger these jobs.
Is this already rolling somewhere on github for nextcloud? I assume that nobody will have anything against those changes so can you process it somehow? All of us commenting this post are waiting for your changes π It would be also best if there would be an option to set up the core number for parallel processing in the administrator UI.
Some changes are scheduled for Nextcloud 18. The app changes are open for CR, but they are shipped with NextCloudPi already.
Impressive improvements!
This should be part of the default configuration of Nextcloud. The current default makes the gallery barely unusable also on standard PCs.
Thank you!
Excellent article! Could anyone reproduce the steps to incorporate the “Preview Generator changes” in an automated way? Or does it have to be done by hand? Thank you in advance,
Changes are included by default in NextCloudPi. Also the PR is still pending in the main app.
Trivial newbie question but… do you need to install imagemagick
https://packages.debian.org/buster/imagemagick
to make php-imagick work?
If so, any special configuration neded for imagemagick?
Thank you!
Hello,
Been searching for a way to increase the delay time between slideshow images. I discovered how to accomplish that when viewing slideshow from the gallery , but the images are not as large as the images in photo slideshow. If I could only merge the best characteristics of both photo slideshow and gallery slideshow I would be happy (until the next puzzle to solve comes my way).
Thanks
I’ve checked (actually debugged) sources of last stable Nextcloud 17.0.2, of lib/private/Preview/Generator.php and found these lines in calculateSize() method:
—-
if ($height !== $maxHeight && $width !== $maxWidth) {
/*
* Scale to the nearest power of four
*/
$pow4height = 4 ** ceil(log($height) / log(4));
$pow4width = 4 ** ceil(log($width) / log(4));
// Minimum size is 64
$pow4height = max($pow4height, 64);
$pow4width = max($pow4width, 64);
—-
So actually only size of power of 4 make sense: 64, 256, 1024, 4096
Ans since we don’t want 4096 because it’s too big and since Android app and web app on my browser request minimum 256×256 images and 1024 width / 1024 height in full page previewI’d recommend set this:
occ config:app:set previewgenerator squareSizes –value=”256 1024″
occ config:app:set previewgenerator widthSizes –value=”256 1024″
occ config:app:set previewgenerator heightSizes –value=”256 1024″
Anyway, all other sizes excpet power of foure in these settings doesn’t make sense
Totally true, but I still recommend to generate 64
Hello, thanks for pointing me this topic.
In Nextcloud 16.x I use this previewgenerator configuration to produce exactly the same preview files as they were created from Nextcloud Files App, Nextcloud Gallery and Android Nextcloud App itself:
occ config:app:set previewgenerator squareSizes –value=”256 1024″
occ config:app:set previewgenerator widthSizes –value=”384 2048″
occ config:app:set previewgenerator heightSizes –value=”256 2048″
occ config:system:set preview_max_x –value 2048
occ config:system:set preview_max_y –value 2048
Best regards,
Sebastian
Is there a way to just keep a certain preview and delete the original file after generating the preview? The scenario: Various users upload their pictures for sharing but storage capacities are limited and viewing the e. g. 1024px version in the browser is perfectly fine.
Is there a different method when MariaDB is used as the default DB?
I would like to see the preview just use 32 / 64 for the icon previews and skip all other previews.
If the user clicks to view the full photo it should show the original size. Does anyone know how would that be achieved?
This preview generation issue really seems the Achilles heel of NC in my opinion. To waste an extra 10-25%+ of storage space on preview generation, let alone the time to create the files seems very wasteful.
When you click an image in Files list the image file is immediately downloaded. Can this be changed so the image big preview (slideshow) is opened, just like you click an image in Photos?
What sizes do I need for the android app?
I’m not 100% sure, but I tried to test it a bit and it seemed like it also uses 256 in my case.
I deleted all previews and opened a picture folder in my Android Nextcloud app, afterwards there were previews for the size 256 present in the previews folder.
This is great info but different for me unfortunately. I had the time (and motivation) to dive into the server access log to see what’s being request and here’s what I found for my three platforms/uses:
Chrome Desktop browser
β’ Photo app tiles
o x=256 y=256
β’ File listing thumbnail
o x=625 y=625
β’ Click image, blown up
o x=1536 y=864
β’ Activities thumbnails
o x=150 y=150
Chrome Android browser
β’ Folder listing thumbnails
o x=1000 y=1000 (yes, this is correct. The thumbnail is higher res than the blown up image)
β’ Click image, blown up
o x=360 y=760 (yes, this is correct. The thumbnail is higher res than the blown up image)
Nextcloud Android app
β’ Folder listing thumbnails. This request is different, goes to a thumbnail URL. All other requests go to a preview URL.
o x=512 y=512
β’ Click image, blown up
o x=1440 y=2706
β’ Activities thumbnails
o x=150 y=150
Now to translate this into the necessary OCC commands!
So after the above comments, I wiped out the preview folder and went through each of the above (Chrome Desktop, Chrome Mobile, Android NextCloud) and scrolled through a few page worth of photos. Then I did a ‘find . -name “*.jpg” in the preview folder and exported all the filenames into excel, consolidated, and the results are as follows:
1000-1000-max.jpg
1024-1024-crop.jpg
1024-768.jpg
1080-1440-max.jpg
1080-1920-max.jpg
1080-2221-max.jpg
1080-810-max.jpg
1200-1600-max.jpg
121-256.jpg
1280-720-max.jpg
1440-1080-max.jpg
1440-3040-max.jpg
144-256.jpg
1773-2364-max.jpg
1820-1024.jpg
1920-1080-max.jpg
192-256.jpg
2160-3840-max.jpg
2164-1024.jpg
2280-1080-max.jpg
256-192.jpg
256-256-crop.jpg
2960-1440-max.jpg
3024-4032-max.jpg
3040-1440-max.jpg
3840-2160-max.jpg
4032-1908-max.jpg
4032-3024-max.jpg
540-960-max.jpg
720-1280-max.jpg
720-720-crop.jpg
768-1024.jpg
810-1080-max.jpg
909-1920-max.jpg
960-544-max.jpg
More to follow as I work on this.
And here we are, after limited preview sizes to 1920×1080 in the config.php. Regenerated previews (manually, my browsing photos)
121 256
144 256
192 256
240 240
256 121
256 144
256 192
256 193
256 256
352 240
510 1080
511 1080
512 512
512 1080
525 1080
540 960
608 608
608 1080
640 480
768 1024
810 810
810 1080
880 880
960 540
960 544
1000 1000
1024 1024
1080 810
1433 1080
1440 1080
1860 880
1920 909
1920 1080
Now to translate into occ commands. Apologies for the several posts in a row, just wanted to share the progress with you all for anyone interested.
So I disabled PreviewGenerator and did some testing by logging into my different devices to see what files would end up being generated and it is ALL over the board. The requests are mostly uniform (depending on devices and app and function) but what the backend actually does with those requests varies. So as I stated on my previous post, to put it concisely, the following is what is requested:
Android NC app: 512×512, 1440×2706, 150×150
Windows Chrome: 256×256, 625×625, 1536×864, 150×150
Android Chrome: 1000×1000, 360×760
So there are 9 variants of what is requested from the web server.
NC then translates that into actual file generation, and the image sizes vary wildly. For example, with 480 preview files generated, this is the breakdown:
Max sizes:
352 240 4
510 1080 1
511 1080 9
512 1080 3
525 1080 2
540 960 5
608 1080 10
640 480 1
810 1080 60
960 540 1
960 544 1
1000 1000 2
1080 810 1
1433 1080 1
1440 1080 9
1860 880 2
1920 909 2
1920 1080 119
Cropped:
240 240 4
256 256 123
512 512 3
608 608 1
810 810 32
880 880 2
1024 1024 21
The rest:
121 256 11
144 256 7
192 256 18
256 121 1
256 144 15
256 192 6
256 193 1
768 1024 2
So as you can see, there is quite a bit of variation. I *believe* that if I use the following:
occ config:app:set previewgenerator squareSizes –value=”256 810 1024″
occ config:app:set previewgenerator widthSizes –value=”256″
occ config:app:set previewgenerator heightSizes –value=”256″
occ config:system:set preview_max_x –value 1920
occ config:system:set preview_max_y –value 1080
That should generate the vast majority of the previews needed for my devices.
Does this work together with the Android Yaga App by any chance?
Looks like these commands no longer work on Version 20 of nexcloud server.
Any idea?
Nevermind, got it to work.
Was this merged into Nextcloud?
I believe in 21 it uses Imagick by default, right?