>
Open Source

An open-source swap that makes Nextcloud feel heavy

I have been running Nextcloud for years, mostly because it was the default answer to self-hosted file management. But every time I used it, I felt like I was running an entire office suite just to browse some files. Nextcloud tries to be a calendar, a contact store, a video-calling server, a photo gallery, a document editor, and a file sync client, all in one package. Most of those features I never opened. The file browser alone was 200MB of RAM at idle, and the update cycle was a monthly project. I replaced the whole stack with FileBrowser, and my NAS has been quiet ever since.

What Nextcloud was actually doing on my NAS

The Nextcloud container on my NAS was 1.4GB on disk for the application code, plus a MariaDB database (a community-maintained drop-in replacement for MySQL) at 800MB, plus a Redis cache (an in-memory key-value store that speeds up repeated database lookups) at 60MB, plus a separate container for the collaborative document editor, plus a cron container, plus a sidecar for the video-call server I had disabled in the admin panel. The total disk footprint for “open a folder and download a PDF” was about 2.5GB.

The RAM footprint at idle was the part that bothered me. The Nextcloud app server was sitting around 180MB at idle. The database was 120MB. The Redis instance was 40MB. The cron container was 60MB. None of those processes were doing work. They were just running, waiting for a request. My NAS has 16GB of RAM, and Nextcloud was eating about 8% of it for the privilege of letting me browse a folder of 4,000 files. The Photo gallery feature I had never opened was the most expensive piece. It indexes every image in the background and stores thumbnails in a separate database table.

I was also paying in update time. Nextcloud ships a major release every 6 months and a security patch every month. Each major release required a manual upgrade dance: pull the new image, run a occ upgrade command (Nextcloud’s command-line tool for running database migrations and other admin tasks), check the log for errors, fix any app incompatibilities, then push the new image to the swarm (a group of Docker machines that Nextcloud can be deployed across). The dance took about 90 minutes per cycle, and the security patches took about 20 minutes. That is roughly 12 hours a year of maintenance, and I was the only person using the calendar.

The thing I kept coming back to was the question: what am I actually using Nextcloud for? I was using it for file sync, file browsing, and the occasional share-a-link-with-someone feature. That is a small set of features. Nextcloud is a 1,400-person engineering effort. The mismatch between what I needed and what I was running had been bothering me for two years.

What I replaced it with

The replacement is filebrowser/filebrowser, a single Go binary (a Go binary is a single compiled program that contains everything the application needs to run, with no separate runtime to install) in a 50MB Docker image. It has no database. It stores its configuration in a single JSON file. It stores its users in the same JSON file. The state of the application is a 12KB text file. The data is whatever directory on disk you point it at. That is the entire architecture.

The container runs on the same NAS. The image pulls in about 5 seconds. The container starts in about 1 second. The RAM usage at idle is 8MB. The disk usage is 50MB. I have not touched it in four months.

Feature list is short. You log in with a username and password. You see a list of files and folders. You can upload, download, rename, delete, and create folders. You can share a file with a link. You can change permissions on a share. You can search by filename. You can preview images and PDFs in the browser. You can edit text files in a built-in editor. There is no calendar. There is no contacts sync. There is no document editor. There is no video-calling. The whole UI is two pages: the login page and the file browser. I prefer it that way.

For the file sync part, I did not replace Nextcloud’s sync client with anything. I already had Syncthing running on every device. Syncthing is a peer-to-peer file sync tool that copies files between your devices without a central server. The directory FileBrowser serves is the same directory Syncthing syncs. FileBrowser does not know Syncthing exists. Syncthing does not know FileBrowser exists. They share a folder. That is the integration.

The setup that actually took less time than I expected

The first install was about 15 minutes. I pulled the image, wrote a docker-compose file with the volume mount, set an admin password, and pointed the container at my data directory. I created one user for my partner, gave her read-write access to a single shared folder, and set the share-link expiration to 7 days. We have been using it for four months without changing a single setting.

The thing that took longer than I expected was the URL routing. I have a reverse proxy (a server that sits in front of the web app and forwards browser requests to it) on the NAS that handles SSL termination (the point at which the encrypted HTTPS connection is decrypted back into plain HTTP before being passed to the app) for the half-dozen self-hosted apps I run. Adding FileBrowser to the proxy config took another 15 minutes, mostly because I had to look up the websocket upgrade headers FileBrowser needs for the live console feature. The console feature lets you open a shell in a directory through the web UI. I do not use it often, but when I do use it, having it work is the difference between this being a one-time install and a recurring chore.

Backups were the only other thing I had to set up. The data directory is on the same ZFS pool (ZFS is a filesystem with built-in support for snapshots, which are point-in-time copies of the data that take up almost no extra space) as the rest of my NAS, and the pool is snapshotted nightly and replicated off-site every Sunday. The FileBrowser config file is in the same volume, so it gets the same backup. There is no separate database backup. There is no Redis backup. The state of the system is the file system.

What I gave up

The thing I gave up first was the calendar. I had a Nextcloud calendar that my partner and I shared for meal planning, school pickup times, and the recurring dentist appointment. I replaced it with a self-hosted Radicale server (a small Python application that implements the CalDAV protocol, the standard way calendar apps sync events between devices) running in another 30MB container. CalDAV is the protocol Apple’s Calendar app, Mozilla Thunderbird, and most other calendar apps speak natively, so the iOS Calendar app and the macOS Calendar app both picked it up with no extra config. Radicale has no web UI. The web UI was a Nextcloud feature I did not need.

The thing I gave up second was the document editor. Nextcloud’s built-in editor (powered by Collabora, a fork of LibreOffice that runs in a separate container and serves a remote editing API) is genuinely useful for the rare case where two people need to edit a Word document at the same time. I have used it maybe four times in three years. The cost was a 1.2GB Collabora container that I had to keep updated in lockstep with the Nextcloud server. I have not replaced this. I open Word documents in LibreOffice on my laptop now, the same way I did before I installed Nextcloud.

Photo gallery work is the third thing I gave up. I had a few thousand photos in Nextcloud’s gallery, and the Memories app (a community plugin that replaced the built-in gallery) had a face-recognition feature that I occasionally used to find a specific picture of a specific person. I am now hosting the photos in a different setup, an Immich container, which I am not going to go into detail about here. The point is that the photo gallery was Nextcloud’s most expensive feature, and I was not using 80% of what it offered.

If you need the calendar, the document editor, and the photo gallery all in one package, and you have 4GB of RAM to spare on your home server, Nextcloud is still the right answer. If you only need a file browser and file sync, FileBrowser plus Syncthing is about 5% of the footprint and about 1% of the maintenance. That was my case.

Trade-offs

FileBrowser is not free in features. The web UI is a file browser. There is no tag system, no comments, no shared annotations, no version history, no audit log, no granular permissions beyond “this user can read this folder” or “this user can read and write this folder.” If you need any of those features, you are going to add them with shell scripts and cron jobs, or you are going to end up back on Nextcloud.

FileBrowser is not free in security surface, either. The web UI runs as a single Go binary with a built-in HTTP server. There is no application-layer sandbox (a security boundary that prevents a bug in one part of the app from affecting the rest of the server) between the web request and the file system. A bug in the file upload handler is a bug in the file system. The Nextcloud team has had a decade of hardening and a paid security team to find bugs. FileBrowser is a single maintainer working on it in his spare time. I am comfortable with that trade-off because my data is backed up, the file browser only has access to the directory I mounted, and the worst case is “an attacker deletes everything in that directory,” which my backup recovers from in about 20 minutes.

For my use case, which is a household of two people syncing about 80GB of documents, photos, and a few videos, the trade-off is clearly worth it. For a team of 20 people sharing a 5TB drive with role-based access controls, Nextcloud is the right tool and FileBrowser is not. The mistake I made for two years was running the team-of-20 tool in a household-of-2 setup.

What I would tell past me

If I could send a message back to the version of me that first installed Nextcloud in 2022, I would say three things.

  • List the three features you actually use before you install a self-hosted app. The list will be shorter than you think. The list will not include the photo gallery.
  • A 1,400-person engineering effort is not the right tool for one person who wants to open a folder. Match the tool to the actual use, not to the imagined use.
  • A single Go binary with a 12KB config file is sometimes the right answer. Do not assume the small tool is too simple for your use. Try the simple thing first, and reach for the larger tool only when the simple one breaks.

The Nextcloud container is no longer running on my NAS. The disk space it frees up, about 2.5GB, is now used by the Immich photo library. The RAM it frees up, about 400MB, is now used by nothing, which is exactly what I want from a tool I have to think about zero times a day.

What the footprint actually looks like

For the curious, here is what each piece of the new stack costs, in concrete numbers.

  • FileBrowser container. 50MB on disk, 8MB RAM at idle, 1 second startup, four months since the last config change.
  • Radicale container (for CalDAV). 30MB on disk, 12MB RAM at idle, replaced the Nextcloud calendar and contacts features.
  • Syncthing on three devices. 80MB per device, runs as a systemd service (a background process managed by the system service manager), no web UI to maintain.
  • Immich container (for photos). 1.8GB on disk for the ML models plus the photo index, about 350MB RAM, runs nightly face-recognition jobs. This is the one piece I would not call “lightweight,” but it is what I actually want from a photo library.
Filed under: #nextexplorer

Leave a comment