I am a sysadmin and I had a user complain that spell checking wasn’t working in Collabora. I found that this was because allowed_languages in my config was set to an empty string.
Setting it to just en_US enabled spell checking, but now instead of documents loading in a second or two, they take 75 seconds for a nearly empty .odt document. What’s worse is that it gets past the loading screen and just shows the user a blank document, making them think the server lost all their data. However, if they just sit and stare at the screen for 75 seconds, everything will appear and everything seems to work fine.
During this long load time, one core on the server is pegged at 100% for the entire duration.
I installed collaboraoffice-dict-en via apt to get my dictionary. I also installed hunspell. I’ve tried making my locale’s dict_path point to both /opt/collaboraoffice/share/extensions and /usr/share/hunspell with no apparent difference. I also put in an override for my coolwsd.service to allow access to those directories (ReadOnlyPaths=/usr/share/hunspell /opt/collaboraoffice), so this isn’t a permission error (which is also supported by the fact that spell checking works if you tolerate the load time).
My dictionaries are 841Kb (hunspell) and 539Kb (from collaboraoffice-dict-en). Nothing out of the ordinary. I’d expect them to be read and loaded into memory in tens of milliseconds. I’ve seen the warning in the config, and I understand loading more dictionaries takes more time, but the posts I’ve seen on this forum seem to define 1 second as acceptable, 1.5 seconds as getting a little long, and 2.0 seconds to be an unacceptably long time. I’d be delighted to have a 2 second load time at this point. I’d tolerate a 5 second load time if I had to, but going beyond that is where I have to draw the line.
To try to figure out what’s going on, I’ve done straces of all coolfork processes, following all forks. I can see that it’s loading a .dic file that is 551,797 bytes which is pretty close to /opt/collaboraoffice/share/extensions/dict-en/en_US.dic (which is 551,762 bytes). The interesting thing is that if I stop coolwsd, replace that file with a tiny test dictionary, start coolwsd, and re-run the test, I see that exact same size dictionary. In both cases it’s reading /lo/program/../share/wordbook/en_US.dic and I’m not sure where that’s coming from. In there’s an en-US.dic in /opt/collaboraoffice/share/extensions/dict-en but no en_US.dic there.
Also worth noting is that I never see any .aff files loaded. I’d expect that by following all forks, it’d show up somewhere in my strace data, but it’s possible I missed it. It’s also possible that this file isn’t really needed and the fact that it’s not loading is expected behavior. In any case, I wanted to mention it in case it’s a clue.
Digging through the strace data for the process which loads the document and the dictionary, it basically looks like this:
- chroot stuff
- bind-mounts
- opens the en_US.dic and reads only the first 4Kb
- copies some presets
- reads standard.dic (45 bytes)
- opens en_US.dic again and only reads the first 4Kb
- loads the document (test.odt, 13,388 bytes)
- does NSS stuff
- opens en_US.dic and reads the entire thing in 4KB chunks. The reads are instant, but this is where 70 seconds of CPU time is spent (in userspace, not waiting on syscalls).
- standard.dic is opened and read again
- font loading
The inability to replace the dictionary file is limiting my ability to test with a small dictionary to see how long that takes. I tried enabling en_GB and de_DE (which I installed for testing purposes). This causes documents to take 120 seconds to load. So it’s not triple the duration, but it does make a meaningful difference.
I also briefly tried a command line option that would disable jails. It didn’t seem to make a difference, so I removed it.
My setup is operating with Nextcloud, specifically the richdocuments app integration. I’m currently on Collaboraoffice 25.04.11-3, the latest available from apt at the time of writing.
The bigest question I have is: how do I continue troubleshooting this issue from here?
Specifically, is there some way I can replace the dictionary file that is going to be used in practice so I can figure out if a tiny dictionary loads faster, or if the dictionary needs to be in a different format?
And why am I the only person who seems to be having this problem? This feels like it’s a dictionary parsing issue, but I know there are lots of people who run the Nextcloud/Collabora combo, and I have to imagine that at least some of them turn on spell checking. I also expect the number of them who would accept a load time of 60+ seconds per document to be exactly zero.
But the “slow load times” I saw people taking about were 2 seconds, which is nothing like what I’m experiencing. If anyone could post a comment here if you have languages/spell checking enabled and it’s working fine, that’d be appreciated. If someone can attempt to re-create this issue on a test server, that’d be double appreciated. I’m using this Ansible role to set up my server on a Debian 13 VM. If I disable all languages (which is the role’s default), it works beautifully. Enable any language and it gets me here.
The way I’m collecting strace data is basically this:
# Get the list of coolfork pids and run strace on each one
pids=`ps -ef | grep [c]oolfork | awk '{ print $2 }'`
for p in $pids; do strace -ff -o /tmp/coolwsd_traces/ -p $p & done
# Click on the document in the Nextcloud web UI, wait for it to completely load
# Gracefully kill each of the strace processes
pids=`ps -ef | grep [s]trace | awk '{ print $2 }'`
for p in $pids; do kill $p; done
If someone is willing to go through the thousands of lines of the strace files, I’ll post them. Same goes for my XML config, even through I went over all the settings that seem relevant.
This one is a real head scratcher, that’s for sure! Any help would be appreciated. I’ve already spent 9 hours over the course of 3 days trying to figure this one out. I want that effort to result in a bug getting fixed, a features added, or some documentation to warn people about this. In the meantime, I’m leaving spell checking off so Collabora is usable.
Edit to add: I’m not using Docker or any other container technology. So this isn’t an issue of Docker getting in the way. I am using ProtectSystem=strict in the .service file and the chroot that is implemented with Collabora is in place, but both of those are default settings.