On this page (12)
- What Google Drive costs
- Alternatives compared
- Nextcloud: the full suite
- Seafile: files are the whole job
- ownCloud Infinite Scale: one small container
- Syncthing: sync between your devices, no server
- FileBrowser Quantum: the maintained web file manager
- File Browser: archived upstream
- How to migrate
- What we did not test
- Hosting needs
- Related
The right self-hosted alternative to Google Drive depends on what you use Drive for. Pick Nextcloud for files plus calendar and office add-ons (untested): 297 MiB idle, files only. Pick Seafile when files are the whole job: 616 MiB idle, the only one of six in our 2 GB tier. Pick ownCloud Infinite Scale for one small container: 151 MiB idle (noisy); its docs suggest 4 GB. Pick Syncthing for device-to-device sync with no server: 22 to 24 MiB idle per node. Pick FileBrowser Quantum for a simple web file manager: 29 MiB idle. Skip the archived File Browser.
The lab put the same 103 files (194,456,599 bytes) through each app as one user on a clean install, three runs each, on 2-vCPU GitHub Actions runners. Rows marked Tested come from those runs. Rows marked Researched come from each project’s own documents, read on Oct 17, 2026 (FileBrowser Quantum: Oct 18, 2026), and nothing in them was benchmarked. RAM and image sizes carry across hosts; timings do not, and we do not rank the apps on speed. The method and its caveats are in Nextcloud vs ownCloud vs Seafile. Each of the five single-stack results has a Test box below. Syncthing has none: its result is two lab nodes, so its per-node figures are in its own section.
Measured readings
Test box: Nextcloud 35.0.2
Measured in our lab on : 3 full runs, each from a fresh stack. Each figure is the median, with the range over the runs under it. The numbers come from the raw result file.
- Idle RAM
- 297 MiBrange 295–301 · 3 runs all containers, median of 3 runs; each run is the mean over 30 s after the stack settled
- Startup peak RAM
- 302 MiBrange 295–302 · 3 runs highest total between healthy and settled
- Peak RAM
- 452 MiBrange 402–479 · 3 runs under load, median of the run peaks
- Settled after
- 190 srange 187–217 · 3 runs after the first healthy response
- Idle CPU
- 2.5 %range 1.8–2.6 · 3 runs of one core, lab host
- Startup
- 27 ssame when rounded in all 3 runs to first healthy response
- App version
- 35.0.2
- Tested
- , 3 runs (compose file verified the same day)
- How the figures are made
- Each run starts a fresh stack and goes through setup, settling, the idle window and the load step. We publish the median over the runs and the lowest and highest value, because the lab host and some apps vary from run to run. Runs, median and range
- Lab host
- AMD EPYC 7763 64-Core Processor, 2 cores, 7.8 GiB RAM, x86_64.Ubuntu 24.04.5 LTS, Docker 28.0.4.
- Disk for the images
- About 2.9 GB with the containerd image store, the default on fresh installs of Docker Engine 29 and later (our estimate: unpacked plus compressed size, plus 10%; not measured on a containerd host). About 1.9 GB with the older overlay2 store (the unpacked column, as measured on this lab host). Plan for the larger figure. How we size disk
- How idle was measured
- After the stack was healthy and set up, we sampled total RAM until it stayed within max(2% of its mean, 10 MiB) over 60 s (at least 120 s, at most 600 s), then measured idle over the next 30 s. Rule in full
- Peak RAM measured
- Under load. One user (the admin), over plain HTTP on the Compose network, one request at a time. A Python script generates 103 random files (100 small ones of 1 KB to 1 MB, about 50 MB together, and three of 50 MB), uploads them over WebDAV (MKCOL, then one PUT per file), lists the folder with PROPFIND, and downloads five files (three small, two large) and checks their SHA-256. About 200 MB in total. No browser, no sync client, no chunked upload, no previews, no sharing. `occ files:scan` is not part of this load (the harness cannot run commands inside the stack); it was run by hand, see the article.
| Container | Idle RAM | Peak RAM (under load) | Image, compressed (download) | Image, unpacked (disk, overlay2 store) |
|---|---|---|---|---|
| app | 204 MiBrange 204–211 · 3 runs | 309 MiBrange 308–317 · 3 runs | 517 MB | 1.5 GB |
| cron | 34 MiBsame when rounded in all 3 runs | 147 MiBrange 34–167 · 3 runs | 517 MB (same image as app) | 1.5 GB (same image as app) |
| db | 46 MiBsame when rounded in all 3 runs | 51 MiBrange 49–51 · 3 runs | 120 MB | 304 MB |
| redis | 10 MiBrange 10–12 · 3 runs | 11 MiBrange 11–13 · 3 runs | 39 MB | 119 MB |
| Total | 297 MiBrange 295–301 · 3 runs | 452 MiBrange 402–479 · 3 runs | 676 MB | 1.9 GB |
Every run (3)
| Run | Idle RAM | Peak RAM | Startup peak | Startup | Lab host CPU |
|---|---|---|---|---|---|
| 1 | 301 MiB | 402 MiB | 302 MiB | 27 s | AMD EPYC 7763 64-Core Processor |
| 2 | 295 MiB | 452 MiB | 295 MiB | 27 s | AMD EPYC 7763 64-Core Processor |
| 3 (closest to median idle) | 297 MiB | 479 MiB | 302 MiB | 27 s | AMD EPYC 7763 64-Core Processor |
0 s to 220 s after healthy; the line spans 0 to 298 MiB. Dashed line: settled.
Timeline as a table
| Seconds after healthy | Total RAM |
|---|---|
| 30 | 260 MiB |
| 60 | 256 MiB |
| 90 | 258 MiB |
| 120 | 259 MiB |
| 150 | 298 MiB |
| 180 | 297 MiB |
| 210 | 297 MiB |
| 220 | 297 MiB |
RAM is MiB (220 bytes); image sizes are MB (106 bytes). The unpacked column is what our lab host's Docker reported; see Disk for the images for other setups. Per-container peaks happen at different moments, so they do not add up to the total peak. Medians of separate columns need not add up either.
Download verified compose fileDownload .envRaw result JSONHow we measure
Lab notes (3)
- Image: the official `nextcloud` apache variant. The `cron` service is the same image started with /cron.sh: two containers in memory, one image on disk.
- The first install is automatic (database and admin variables in compose.yaml), so there is no web wizard and no installed apps beyond the image's defaults.
- Periodic job: service cron runs a scheduled job every 300 s on the wall-clock grid. After the settle rule is met, the idle window starts only once the job has ticked at least once since the stack became healthy and the last tick is 60 s old (extra wait capped at 360 s), so idle reflects a stack after one run of the job. The wait is part of settle_seconds_used; runs[].periodic has the tick times (computed from the clock, not read from the job).
Measured readings
Test box: Seafile 13.0.28
Measured in our lab on : 3 full runs, each from a fresh stack. Each figure is the median, with the range over the runs under it. The numbers come from the raw result file.
- Idle RAM
- 616 MiBrange 590–759 · 3 runs all containers, median of 3 runs; each run is the mean over 30 s after the stack settled
- Startup peak RAM
- 620 MiBrange 590–761 · 3 runs highest total between healthy and settled
- Peak RAM
- 905 MiBrange 876–911 · 3 runs under load, median of the run peaks
- Settled after
- 125 srange 124–128 · 3 runs after the first healthy response
- Idle CPU
- 1.8 %range 1.5–1.9 · 3 runs of one core, lab host
- Startup
- 18 ssame when rounded in all 3 runs to first healthy response
- App version
- 13.0.28
- Tested
- , 3 runs (compose file verified the same day)
- How the figures are made
- Each run starts a fresh stack and goes through setup, settling, the idle window and the load step. We publish the median over the runs and the lowest and highest value, because the lab host and some apps vary from run to run. Runs, median and range
- Lab host
- AMD EPYC 9V45 96-Core Processor, 2 cores, 7.8 GiB RAM, x86_64.Ubuntu 24.04.5 LTS, Docker 28.0.4.
- Disk for the images
- About 3.2 GB with the containerd image store, the default on fresh installs of Docker Engine 29 and later (our estimate: unpacked plus compressed size, plus 10%; not measured on a containerd host). About 2.1 GB with the older overlay2 store (the unpacked column, as measured on this lab host). Plan for the larger figure. How we size disk
- How idle was measured
- After the stack was healthy and set up, we sampled total RAM until it stayed within max(2% of its mean, 10 MiB) over 60 s (at least 120 s, at most 600 s), then measured idle over the next 30 s. Rule in full
- Peak RAM measured
- Under load. The same load as the Nextcloud and ownCloud tests, through Seafile's own Web API. One user (the admin), over plain HTTP on the Compose network, one request at a time, each on a new connection. A Python script generates the same 103 random files (100 small ones of 1 KB to 1 MB, about 50 MB together, and three of 50 MB; same seed, same names, same order), creates a folder in the library, asks for one upload address for that folder (GET upload-link) and uploads the files to it with one multipart POST each, lists the folder with one GET of the directory, and downloads five files (three small, two large; one request for the download address and one for the file each) and checks their SHA-256. About 200 MB in total. The web API is used instead of WebDAV because it is what Seafile's web interface, mobile apps and scripts use; WebDAV is a separate, optional component that is off by default in Seafile 13. No browser, no sync client (Seafile's desktop client uses its own block-based sync protocol, which is not exercised), no chunked upload, no thumbnails, no sharing.
| Container | Idle RAM | Peak RAM (under load) | Image, compressed (download) | Image, unpacked (disk, overlay2 store) |
|---|---|---|---|---|
| db | 133 MiBrange 132–133 · 3 runs | 134 MiBsame when rounded in all 3 runs | 104 MB | 327 MB |
| redis | 9 MiBsame when rounded in all 3 runs | 9 MiBsame when rounded in all 3 runs | 56 MB | 146 MB |
| seafile | 475 MiBrange 449–617 · 3 runs | 762 MiBrange 734–769 · 3 runs | 560 MB | 1.6 GB |
| Total | 616 MiBrange 590–759 · 3 runs | 905 MiBrange 876–911 · 3 runs | 720 MB | 2.1 GB |
Every run (3)
| Run | Idle RAM | Peak RAM | Startup peak | Startup | Lab host CPU |
|---|---|---|---|---|---|
| 1 | 759 MiB | 911 MiB | 761 MiB | 18 s | AMD EPYC 9V45 96-Core Processor |
| 2 (closest to median idle) | 616 MiB | 905 MiB | 620 MiB | 18 s | AMD EPYC 9V45 96-Core Processor |
| 3 | 590 MiB | 876 MiB | 590 MiB | 18 s | AMD EPYC 9V45 96-Core Processor |
0 s to 160 s after healthy; the line spans 0 to 617 MiB. Dashed line: settled.
Timeline as a table
| Seconds after healthy | Total RAM |
|---|---|
| 30 | 613 MiB |
| 60 | 613 MiB |
| 90 | 614 MiB |
| 120 | 616 MiB |
| 150 | 616 MiB |
| 160 | 617 MiB |
RAM is MiB (220 bytes); image sizes are MB (106 bytes). The unpacked column is what our lab host's Docker reported; see Disk for the images for other setups. Per-container peaks happen at different moments, so they do not add up to the total peak. Medians of separate columns need not add up either.
Download verified compose fileDownload .envRaw result JSONHow we measure
Lab notes (6)
- Host: a GitHub Actions runner (ubuntu-latest, x86_64, 2 vCPU, 8 GB RAM; the CPU model varies between runners and each run records its own). Numbers are valid for that host only.
- Image: seafileltd/seafile-mc:13.0.28, Seafile Community Edition 13.0.28 (18 Sep 2026), the newest release Seafile's own changelog (plus.seafile.com/wiki/publish/seafile-wiki/5L80/) does not label beta. 14.0.9 (14 Oct 2026) is labelled beta there and is not tested. The image's version label says 24.04 (the Ubuntu base), so the version is read from the running server (GET /api2/server-info/).
- Companions (Seafile 13 official Docker file): MariaDB 10.11 and Redis, in their own containers. Memcached is optional since 13 and not used. Caddy (reverse proxy), SeaDoc (online documents), the notification server, the metadata server, Seafile AI, the thumbnail server and WebDAV are not run. The container count is three, against four for Nextcloud (app, cron, PostgreSQL, Redis) and one for ownCloud Infinite Scale.
- Measured: idle RAM and CPU after the first start with the admin account and one empty library; RAM and CPU while the load of load.description runs (a few seconds); image sizes; start-up time. Not measured: the desktop or mobile sync clients, external storage or S3 backends, online editing (SeaDoc, OnlyOffice, Collabora), full-text search, previews, LDAP/SSO, many users, long-term growth.
- Equivalence with the Nextcloud test: same 103 files (same generator and seed), same order, one request at a time, one user, plain HTTP, 5 downloads with a SHA-256 check. Differences that come from the products: Seafile needs one request for an upload address (reused for every file) and one per download address; Nextcloud's PROPFIND also returns the folder itself, Seafile's listing returns files only, so `listing_entries` is 103 for both. The Nextcloud result calls the listing `propfind_entries` and `propfind_seconds`.
- The load script reports every request kind with the HTTP statuses it got (`requests` in the load result); any failed request fails the run.
Measured readings
Test box: ownCloud Infinite Scale 8.2.1
Measured in our lab on : 3 full runs, each from a fresh stack. Each figure is the median, with the range over the runs under it. The numbers come from the raw result file.
- Idle RAM
- 151 MiBrange 101–155 · 3 runs all containers, median of 3 runs; each run is the mean over 30 s after the stack settled
- Startup peak RAM
- 282 MiBrange 252–323 · 3 runs highest total between healthy and settled
- Peak RAM
- 305 MiBrange 304–309 · 3 runs under load, median of the run peaks
- Settled after
- 181 ssame when rounded in all 3 runs after the first healthy response
- Idle CPU
- 0.8 %range 0.6–1.0 · 3 runs of one core, lab host
- Startup
- 5.4 srange 5.4–5.5 · 3 runs to first healthy response
Varies between runs. The highest run was more than 1.5 times the lowest: idle RAM was 155 MiB, 151 MiB, 101 MiB in runs 1 to 3. The figures above are the median; plan for the top of the range. Each run was the same stack and version started fresh, so the spread comes from the app or the lab host.
- App version
- 8.2.1
- Tested
- , 3 runs (compose file verified the same day)
- How the figures are made
- Each run starts a fresh stack and goes through setup, settling, the idle window and the load step. We publish the median over the runs and the lowest and highest value, because the lab host and some apps vary from run to run. Runs, median and range
- Lab host
- AMD EPYC 9V45 96-Core Processor, 2 cores, 7.8 GiB RAM, x86_64.Ubuntu 24.04.5 LTS, Docker 28.0.4.
- Disk for the images
- About 359 MB with the containerd image store, the default on fresh installs of Docker Engine 29 and later (our estimate: unpacked plus compressed size, plus 10%; not measured on a containerd host). About 238 MB with the older overlay2 store (the unpacked column, as measured on this lab host). Plan for the larger figure. How we size disk
- How idle was measured
- After the stack was healthy and set up, we sampled total RAM until it stayed within max(2% of its mean, 10 MiB) over 60 s (at least 120 s, at most 600 s), then measured idle over the next 30 s. Rule in full
- Peak RAM measured
- Under load. The same load as the Nextcloud and Seafile tests, over WebDAV. One user (the admin), over HTTPS with a self-signed certificate on the Compose network (not verified), basic authentication, one request at a time, each on a new connection. A Python script generates the same 103 random files (100 small ones of 1 KB to 1 MB, about 50 MB together, and three of 50 MB; same seed, same names, same order), uploads them to a folder in the admin's personal space (MKCOL, then one PUT per file), lists the folder with PROPFIND (Depth 1), and downloads five files (three small, two large) and checks their SHA-256. About 200 MB in total. The address is /dav/spaces/<space id>, the form the official desktop and mobile apps use (Nextcloud's test uses /remote.php/dav/files/admin). No browser, no sync client, no chunked (TUS) upload, no thumbnails, no sharing, no search.
| Container | Idle RAM | Peak RAM (under load) | Image, compressed (download) | Image, unpacked (disk, overlay2 store) |
|---|---|---|---|---|
| ocis | 151 MiBrange 101–155 · 3 runs | 305 MiBrange 304–309 · 3 runs | 88 MB | 238 MB |
Every run (3)
| Run | Idle RAM | Peak RAM | Startup peak | Startup | Lab host CPU |
|---|---|---|---|---|---|
| 1 | 155 MiB | 305 MiB | 252 MiB | 5.4 s | AMD EPYC 9V45 96-Core Processor |
| 2 (closest to median idle) | 151 MiB | 309 MiB | 282 MiB | 5.5 s | AMD EPYC 9V45 96-Core Processor |
| 3 | 101 MiB | 304 MiB | 323 MiB | 5.4 s | AMD EPYC 9V45 96-Core Processor |
0 s to 220 s after healthy; the line spans 0 to 282 MiB. Dashed line: settled.
Timeline as a table
| Seconds after healthy | Total RAM |
|---|---|
| 30 | 271 MiB |
| 60 | 272 MiB |
| 90 | 276 MiB |
| 120 | 282 MiB |
| 150 | 151 MiB |
| 180 | 153 MiB |
| 210 | 151 MiB |
| 220 | 152 MiB |
RAM is MiB (220 bytes); image sizes are MB (106 bytes). The unpacked column is what our lab host's Docker reported; see Disk for the images for other setups. Per-container peaks happen at different moments, so they do not add up to the total peak. Medians of separate columns need not add up either.
Download verified compose fileDownload .envRaw result JSONHow we measure
Lab notes (9)
- Warning: max/min across runs is above 1.5 for idle_mem_mib: the app is bimodal or the host is noisy. The published figure is the median; read it together with the range.
- Host: a GitHub Actions runner (ubuntu-latest, x86_64, 2 vCPU, 8 GB RAM; the CPU model varies between runners and each run records its own). Numbers are valid for that host only.
- Which ownCloud: ownCloud Infinite Scale (oCIS), image owncloud/ocis:8.2.1 (GitHub release v8.2.1, marked Latest, 2 Oct 2026; Docker Hub tag rebuilt 12 Oct 2026). owncloud.com/download-server calls Infinite Scale 'Our Flagship Product' and 'ownCloud's modern successor to the old PHP monolith (ownCloud 10 / oC10)'. The classic PHP server (owncloud/server 10.16.x and 11.0.x) is not tested; see lab/notes/owncloud-flavour-2026-10-16.md for the evidence.
- Infinite Scale is one container with no separate database or cache: users, metadata and the search index live in its two volumes. The container count is one, against four for Nextcloud and three for Seafile, so compare the total, not the container.
- TLS: oCIS serves HTTPS on port 9200 with a self-signed certificate it generates (default, as in ownCloud's evaluation guide). OCIS_INSECURE=true lets its services accept that certificate, and the load scripts do not verify it. A reader behind a reverse proxy with a real certificate would not need either.
- Basic authentication (PROXY_ENABLE_BASIC_AUTH=true) is on so a script can use WebDAV without an OpenID Connect login; ownCloud describes it as 'not recommended' and the web interface and apps do not need it. It is in the published compose too.
- Measured: idle RAM and CPU after the first start with the admin account; RAM and CPU while the load of load.description runs (a few seconds); image size; start-up time. Not measured: the desktop or mobile sync clients, external storage or S3 backends, online editing (Collabora, ONLYOFFICE), Tika full-text search, antivirus, previews, Keycloak/LDAP, many users, background work after the script ends (search indexing), long-term growth.
- Equivalence with the Nextcloud test: same 103 files (same generator and seed), same order, same request kinds (MKCOL, 103 PUT, PROPFIND Depth 1, 5 GET), one request at a time, one user. Differences: HTTPS instead of HTTP, the /dav/spaces/<id> address, and PROPFIND on oCIS returns 104 entries as on Nextcloud (folder plus 103 files); `listing_entries` counts the files (103). The Nextcloud result calls the listing `propfind_entries` and `propfind_seconds`.
- The load script reports every request kind with the HTTP statuses it got (`requests` in the load result); any failed request fails the run.
Measured readings
Test box: File Browser 2.63.23
Measured in our lab on : 3 full runs, each from a fresh stack. Each figure is the median, with the range over the runs under it. The numbers come from the raw result file.
- Idle RAM
- 15 MiBrange 13–15 · 3 runs all containers, median of 3 runs; each run is the mean over 30 s after the stack settled
- Startup peak RAM
- 15 MiBrange 13–15 · 3 runs highest total between healthy and settled
- Peak RAM
- 23 MiBrange 21–23 · 3 runs under load, median of the run peaks
- Settled after
- 122 ssame when rounded in all 3 runs after the first healthy response
- Idle CPU
- 0.5 %same when rounded in all 3 runs of one core, lab host
- Startup
- 5.4 ssame when rounded in all 3 runs to first healthy response
- App version
- 2.63.23
- Tested
- , 3 runs (compose file verified the same day)
- How the figures are made
- Each run starts a fresh stack and goes through setup, settling, the idle window and the load step. We publish the median over the runs and the lowest and highest value, because the lab host and some apps vary from run to run. Runs, median and range
- Lab host
- AMD EPYC 9V45 96-Core Processor, 2 cores, 7.8 GiB RAM, x86_64.Ubuntu 24.04.5 LTS, Docker 28.0.4.
- Disk for the images
- About 61 MB with the containerd image store, the default on fresh installs of Docker Engine 29 and later (our estimate: unpacked plus compressed size, plus 10%; not measured on a containerd host). About 39 MB with the older overlay2 store (the unpacked column, as measured on this lab host). Plan for the larger figure. How we size disk
- How idle was measured
- After the stack was healthy and set up, we sampled total RAM until it stayed within max(2% of its mean, 10 MiB) over 60 s (at least 120 s, at most 600 s), then measured idle over the next 30 s. Rule in full
- Peak RAM measured
- Under load. The same load as the Nextcloud, Seafile and ownCloud tests, through File Browser's HTTP API. One user (the first user, an administrator), over plain HTTP on the Compose network, one request at a time, each on a new connection. A Python script generates the same 103 random files (100 small ones of 1 KB to 1 MB, about 50 MB together, and three of 50 MB; same seed, same names, same order), creates a folder (POST /api/resources/loadtest/), uploads the files with one POST of the raw body each, lists the folder with one GET, and downloads five files (three small, two large; GET /api/raw/...) and checks their SHA-256. About 200 MB in total. The web interface uploads with the TUS protocol; this test uses the plain POST that scripts use, so it measures one request per file as the other apps do. No browser, no thumbnails, no sharing, no search, no command runner.
| Container | Idle RAM | Peak RAM (under load) | Image, compressed (download) | Image, unpacked (disk, overlay2 store) |
|---|---|---|---|---|
| filebrowser | 15 MiBrange 13–15 · 3 runs | 23 MiBrange 21–23 · 3 runs | 17 MB | 39 MB |
Every run (3)
| Run | Idle RAM | Peak RAM | Startup peak | Startup | Lab host CPU |
|---|---|---|---|---|---|
| 1 | 15 MiB | 23 MiB | 15 MiB | 5.4 s | AMD EPYC 9V45 96-Core Processor |
| 2 | 13 MiB | 21 MiB | 13 MiB | 5.4 s | AMD EPYC 9V45 96-Core Processor |
| 3 (closest to median idle) | 15 MiB | 23 MiB | 15 MiB | 5.4 s | AMD EPYC 9V45 96-Core Processor |
0 s to 160 s after healthy; the line spans 0 to 15 MiB. Dashed line: settled.
Timeline as a table
| Seconds after healthy | Total RAM |
|---|---|
| 30 | 15 MiB |
| 60 | 15 MiB |
| 90 | 15 MiB |
| 120 | 15 MiB |
| 150 | 15 MiB |
| 160 | 15 MiB |
RAM is MiB (220 bytes); image sizes are MB (106 bytes). The unpacked column is what our lab host's Docker reported; see Disk for the images for other setups. Per-container peaks happen at different moments, so they do not add up to the total peak. Medians of separate columns need not add up either.
Download verified compose fileDownload .envRaw result JSONHow we measure
Lab notes (7)
- Host: a GitHub Actions runner (ubuntu-latest, x86_64, 2 vCPU, 8 GB RAM; the CPU model varies between runners and each run records its own). Numbers are valid for that host only.
- MAINTENANCE: the project is archived. v2.63.23 (27 Jul 2026, Docker Hub tag filebrowser/filebrowser:v2.63.23, also `latest` and `v2`) is the last planned release; the README says 'File Browser is archived on 2026-09-01' and 'there will be no further releases, bug fixes, or security fixes', and lists unfixed issues (JWTs cannot be revoked, so a logout or password change does not invalidate older tokens; the command runner is off by default). The container prints a wind-down notice at start. The tested image still works and stays on Docker Hub; it is tested because readers still run it, not because it is a recommendation. See lab/notes/filebrowser-syncthing-2026-10-16.md for the evidence.
- Image: the default bare image (BusyBox, one static Go binary, runs as UID/GID 1000), not the `s6` variant. One container; users and settings are in a Bolt database file (/database/filebrowser.db) and files are plain files in /srv.
- Measured: idle RAM and CPU after the first start with one user and an empty file root; RAM and CPU while the load of load.description runs (a few seconds); image size; start-up time. Not measured: the web interface or a browser, TUS (resumable) uploads, thumbnails and previews of images or video, the search, sharing links, multiple users, a reverse proxy, desktop or mobile sync (File Browser has no sync client at all; it is a file manager, not a sync tool).
- Equivalence with the Nextcloud test: same 103 files (same generator and seed), same order, one request at a time, one user, plain HTTP, 5 downloads with a SHA-256 check. Differences that come from the product: no address requests, the login token is a header (X-Auth), and the folder listing returns files only, so `listing_entries` is 103.
- The first user is created from FB_USERNAME and FB_PASSWORD (a bcrypt hash) on the first start, the 'quick setup' of the quick-start docs; without FB_PASSWORD File Browser generates a random password and prints it once in the log. The lab sets one so the steps can log in.
- The load script reports every request kind with the HTTP statuses it got (`requests` in the load result); any failed request fails the run.
Measured readings
Test box: FileBrowser Quantum v2.0.1-stable
Measured in our lab on : 3 full runs, each from a fresh stack. Each figure is the median, with the range over the runs under it. The numbers come from the raw result file.
- Idle RAM
- 29 MiBrange 27–31 · 3 runs all containers, median of 3 runs; each run is the mean over 30 s after the stack settled
- Startup peak RAM
- 40 MiBrange 40–44 · 3 runs highest total between healthy and settled
- Peak RAM
- 44 MiBrange 42–48 · 3 runs under load, median of the run peaks
- Settled after
- 175 srange 175–181 · 3 runs after the first healthy response
- Idle CPU
- 0.5 %same when rounded in all 3 runs of one core, lab host
- Startup
- 5.4 srange 5.4–5.5 · 3 runs to first healthy response
- App version
- v2.0.1-stable
- Tested
- , 3 runs (compose file verified the same day)
- How the figures are made
- Each run starts a fresh stack and goes through setup, settling, the idle window and the load step. We publish the median over the runs and the lowest and highest value, because the lab host and some apps vary from run to run. Runs, median and range
- Lab host
- INTEL(R) XEON(R) PLATINUM 8573C, 2 cores, 7.8 GiB RAM, x86_64.Ubuntu 24.04.5 LTS, Docker 28.0.4.
- Disk for the images
- About 221 MB with the containerd image store, the default on fresh installs of Docker Engine 29 and later (our estimate: unpacked plus compressed size, plus 10%; not measured on a containerd host). About 137 MB with the older overlay2 store (the unpacked column, as measured on this lab host). Plan for the larger figure. How we size disk
- How idle was measured
- After the stack was healthy and set up, we sampled total RAM until it stayed within max(2% of its mean, 10 MiB) over 60 s (at least 120 s, at most 600 s), then measured idle over the next 30 s. Rule in full
- Peak RAM measured
- Under load. The same load as the Nextcloud, Seafile, ownCloud and File Browser tests, through FileBrowser Quantum's HTTP API. One user (the admin), over plain HTTP on the Compose network, one request at a time, each on a new connection. A Python script generates the same 103 random files (100 small ones of 1 KB to 1 MB, about 50 MB together, and three of 50 MB; same seed, same names, same order), creates a folder and uploads the files (POST /api/resources, the documented "create or upload a resource" call: one POST of the raw body per file, whole file, not chunked), lists the folder with one GET (GET /api/resources), and downloads five files (three small, two large; GET /api/resources/download) and checks their SHA-256. About 200 MB in total. The web interface cuts large uploads into chunks; this test sends each file whole, so it measures one request per file as the other apps do. No browser, no thumbnails or previews, no sharing, no search, no WebDAV.
| Container | Idle RAM | Peak RAM (under load) | Image, compressed (download) | Image, unpacked (disk, overlay2 store) |
|---|---|---|---|---|
| filebrowser | 29 MiBrange 27–31 · 3 runs | 44 MiBrange 42–48 · 3 runs | 63 MB | 137 MB |
Every run (3)
| Run | Idle RAM | Peak RAM | Startup peak | Startup | Lab host CPU |
|---|---|---|---|---|---|
| 1 | 31 MiB | 48 MiB | 44 MiB | 5.5 s | INTEL(R) XEON(R) PLATINUM 8573C |
| 2 | 27 MiB | 42 MiB | 40 MiB | 5.4 s | INTEL(R) XEON(R) PLATINUM 8573C |
| 3 (closest to median idle) | 29 MiB | 44 MiB | 40 MiB | 5.4 s | INTEL(R) XEON(R) PLATINUM 8573C |
0 s to 210 s after healthy; the line spans 0 to 40 MiB. Dashed line: settled.
Timeline as a table
| Seconds after healthy | Total RAM |
|---|---|
| 30 | 40 MiB |
| 60 | 39 MiB |
| 90 | 39 MiB |
| 120 | 35 MiB |
| 150 | 29 MiB |
| 180 | 29 MiB |
| 210 | 29 MiB |
RAM is MiB (220 bytes); image sizes are MB (106 bytes). The unpacked column is what our lab host's Docker reported; see Disk for the images for other setups. Per-container peaks happen at different moments, so they do not add up to the total peak. Medians of separate columns need not add up either.
Download verified compose fileDownload .envRaw result JSONHow we measure
Lab notes (9)
- Host: a GitHub Actions runner (ubuntu-latest, x86_64, 2 vCPU, 8 GB RAM; the CPU model varies between runners and each run records its own). Numbers are valid for that host only.
- Version and channel: FileBrowser Quantum 2.0.1, the STABLE channel (Docker Hub gtstef/filebrowser:2.0.1-stable, also `stable`, `latest`, `2-stable`, `2.0-stable`; GitHub release v2.0.1-stable of 13 Oct 2026, marked Latest; it is a security release for a path-escape bug with `..` in a user name and a session-token collision). The project's other channel is BETA (2.1.x, tags `beta`, `2.1-beta`; v2.1.2-beta of 13 Oct 2026), which gets features first and, in the project's words, may have unexpected issues; it is not tested here. The image is the default one, with ffmpeg and document preview (about 60 MB compressed per the docs); the `-slim` variant (about 15 MB) is not tested. See lab/notes/filebrowser-quantum-2026-10-18.md for the evidence.
- Not the same program as File Browser 2.63.23 (lab app `filebrowser`): Quantum is a fork that was rewritten. It has its own API (/api/resources with source and path parameters, a bearer token), a YAML config file and a SQLite database, and v2 cannot simply replace a v1 or File Browser install (a one-time migration reads the old database). Do not compare the two apps' numbers as one program.
- Config: one source, the directory /home/filebrowser/data/files, named `files`, written as `config.yaml` inline in the compose file (Compose `configs`). The admin password is the environment variable FILEBROWSER_ADMIN_PASSWORD (plain text, not a hash, unlike File Browser). One named volume holds config, SQLite database, cache and the served folder. The docs bind-mount a folder you own at /folder instead; a second named volume would belong to root and Quantum (UID 1000) could not write into it, and Quantum does not create a missing source folder, so the container's entrypoint runs `mkdir -p` first and then `exec ./filebrowser`. The binary, the user and the data layout are the image's own.
- Indexing: Quantum indexes every source into a SQLite index in the background (folder sizes, search, quotas). The first pass runs at start-up, in the first second, and costs nothing measurable on the empty source, so it is part of start-up and idle does not wait for it. Afterwards the app re-scans on a schedule the docs call adaptive (one full scan, then four quick scans, at intervals from 5 minutes to 12 hours that lengthen while nothing changes). In two sandbox probes on a fresh stack the first scheduled scan was 12 min 51 s and 17 min 40 s after the start (a round wall-clock time), longer than a lab run (about 3 minutes from start to the end of the load), so the idle window and the load window contain no scan and no `periodic:` rule is used. A probe that kept a stack for 15 minutes saw one scan, after the load, lift memory by about 4.5 MiB (21.7 to 26.4 MiB) with 103 files. The slot rule is not documented and only two samples were taken: if a run's `idle` or `peak` looks higher than the others, a scan is a suspect. Not tested: indexing a large tree (the docs' own figures are about 50 MB for 20,000 items, 150 MB for 100,000, 300 MB for 1,000,000), so a reader with a big folder should expect more RAM than the idle figure. See lab/notes/filebrowser-quantum-2026-10-18.md.
- Measured: idle RAM and CPU after the first start with one user and an empty source; RAM and CPU while the load of load.description runs (a few seconds); image size; start-up time. Not measured: the web interface or a browser, chunked uploads, thumbnails and previews (generated on demand when a folder is viewed in the web interface; the API load never asks for one), the search, sharing links, WebDAV, the other login methods (OIDC, LDAP, JWT, proxy, passkeys, TOTP), multiple users and access rules, OnlyOffice, a reverse proxy, desktop or mobile sync (Quantum has no sync client; it is a file manager, not a sync tool), the beta channel, migration from File Browser.
- Equivalence with the Nextcloud test: same 103 files (same generator and seed), same order, one request at a time, one user, plain HTTP, 5 downloads with a SHA-256 check. Differences that come from the product: no address requests, the login token is a header (Authorization: Bearer), and the folder listing returns files and folders apart, so `listing_entries` is 103. Quantum reports sizes in a listing as disk usage (4 KiB blocks) unless `useLogicalSize: true` is set, so the listing check needs the same names and a size at least the file length (`listing_sizes_exact` says whether they were identical, `listing_bytes_reported` is the total it reported).
- The load script reports every request kind with the HTTP statuses it got (`requests` in the load result); any failed request fails the run.
- The app checks for updates at start (server.disableUpdateCheck is false by default) and the default config was left as it is. The login route is rate limited by default; the load logs in once.
What Google Drive costs
Every Google account includes up to 15 GB of storage, “shared across Gmail, Google Drive, and Google Photos” (Google Account Help, read Oct 17, 2026). More storage is sold as a Google One membership, “where available” on that page. The plans page we could read on Oct 17, 2026 showed plan sizes but no prices, so this page states none. Check the page for your country and currency.
Self-hosting swaps that monthly bill for hardware or a VPS you run, plus your time to update and back it up. The sizing tiers below say how much RAM each app needs.
If you want a hosted service that is not Google, we read one example. Proton’s Drive plan page lists a free 5 GB plan and Drive Plus at 200 GB for $4.99/month in its US-dollar monthly view (read Oct 17, 2026), and calls Drive “end-to-end encrypted”. The page also has currency and monthly or yearly toggles, so the price you pay depends on country and billing period. Not tested in our lab.
Alternatives compared
The first table is Tested, apart from its last column. The second is Researched. The same apps also answer “Dropbox alternatives, open source” and “Nextcloud alternative”, but we compared against Drive’s features, not Dropbox’s.
Measured: RAM, images and sizing tier
Each figure is the median of three runs with the lowest to highest run in brackets. RAM is Docker’s working set for all containers of one stack, idle after the stack settled (how we measure idle RAM). Peak is the highest sample while the 103-file load ran. Sources: nextcloud.json, seafile.json, owncloud.json, filebrowser.json, filebrowser-quantum.json and syncthing.json in lab/results/ (figures and script in lab/notes/gdrive-alternatives-2026-10-17.md; that note’s Nextcloud figures are the Oct 8 run, and the Oct 18 Nextcloud figures are in lab/notes/nextcloud-2026-10-18.md; the FileBrowser Quantum figures and script are in lab/notes/gdrive-alternatives-2026-10-18.md).
| App and version | Idle RAM, MiB | Peak RAM under load, MiB | Our sizing tier | Images to download, MB | Tested (date, lab host CPU) | Project’s own RAM guidance (Researched) |
|---|---|---|---|---|---|---|
| Nextcloud 35.0.2 (4 containers) | 297 (295 to 301) | 452 (402 to 479) | 1 GB | 676.4 | Oct 18, 2026, AMD EPYC 7763 | “a minimum of 128MB RAM per process” and “512MB RAM per process” recommended (Nextcloud 35 requirements) |
| Seafile 13.0.28 (3 containers) | 616 (590 to 759) | 905 (876 to 911) | 2 GB | 720.0 | Oct 16, 2026, AMD EPYC 9V45 | Memory 2G, 2 cores (Seafile 13 requirements) |
| ownCloud Infinite Scale 8.2.1 (1 container) | 151 (101 to 155), noisy | 305 (304 to 309) | 1 GB | 87.5 | Oct 16, 2026, AMD EPYC 9V45 | “Using 4GB of RAM is a good starting point” for production (prerequisites) |
| Syncthing v2.1.6 (per node) | Node A 21.9 (21.7 to 23.7); node B 23.5 (21.8 to 23.8) | Node A 64.6 (64.0 to 65.3); node B 45.4 (43.5 to 46.6) | 1 GB | 18.7 (one image for both nodes) | Oct 16, 2026, AMD EPYC 7763 | None found in the FAQ |
| FileBrowser Quantum 2.0.1-stable (1 container) | 29.3 (27.4 to 31.4) | 44.0 (41.9 to 48.1) | 1 GB | 63.1 | Oct 18, 2026, Intel Xeon Platinum 8573C | No figure for the whole app found; its indexing page gives 50 MB for a full scan of 10,000 folders and 10,000 files, 150 MB for 50,000 and 50,000, 300 MB for 500,000 and 500,000 |
| File Browser 2.63.23 (archived, kept as a record) | 14.7 (12.8 to 14.8) | 22.8 (20.8 to 22.8) | 1 GB | 16.8 | Oct 16, 2026, AMD EPYC 9V45 | None found in the README |
How to read it.
- The tier is a floor. Our rule (highest reading in any run, times 1.5, rounded up to 1, 2, 4, 8, 16 or 32 GB; how we size) gives 1 GB for five of the six, so it hides the spread between 15 MiB idle and 452 MiB peak. Use the RAM columns for that. The tier is for one user and 103 files, not for a family with years of photos.
- Project guidance is higher than our tiers for two apps. ownCloud’s 4GB for production is four times our 1 GB tier. Seafile’s 2G matches ours. Nextcloud’s 512MB is per process, and we did not count processes.
- Infinite Scale’s idle figure moves between runs. The three runs idled at 155, 151 and 101 MiB, and the result carries a variance flag. For the first two minutes after start, 10-second means sat between 213 and 322 MiB (startup peak 282 MiB median, highest single sample 323). Details are in the three-way comparison.
- Nextcloud’s idle is measured after cron’s first run, and its peak depends on a cron burst. The Oct 18 run on 35.0.2 gave 297 MiB idle and 452 MiB peak (the Oct 8 run on 35.0.1 gave 299 and 454). The Oct 17 run (265 and 367) was taken before the cron container’s first background run in two of its three runs, and the lab now waits for that run before it measures idle (methodology, 2026-10-18). The peak varies with whether a cron burst of 147 to 182 MiB lands inside the upload: single runs peaked from 402 to 479 MiB on Oct 18, and from 362 to 497 MiB over the three batches. We do not claim 35.0.2 uses less memory (Nextcloud guide).
- The hosts differ. Nextcloud and Syncthing ran on EPYC 7763 runners, Seafile, Infinite Scale and File Browser on EPYC 9V45, and FileBrowser Quantum on an Intel Xeon Platinum 8573C, each in its own job. Peaks rest on 3 to 21 samples, taken 2 to 3 seconds apart.
- Syncthing’s two nodes. The lab ran two nodes because Syncthing needs a peer. The result file’s own totals add them (45.4 MiB idle, 109.4 MiB peak); a reader runs one node per device, so the table gives each node. Node A is the one the files were written into, node B received them.
What each one replaces from Google Drive
Researched, not tested: each cell is from the project’s documents or repository, read on Oct 17, 2026 (the FileBrowser Quantum column: Oct 18, 2026). “Not checked” means we did not look.
| Drive feature | Nextcloud 35 | Seafile 13 Community Edition | ownCloud Infinite Scale 8.2 | Syncthing 2.1 | File Browser 2.63 (archived) | FileBrowser Quantum 2.0 (stable) |
|---|---|---|---|---|---|---|
| Web interface for your files | Yes: “create, preview, edit, delete, share, and re-share files” (manual) | Yes: the manual has pages on viewing files in the web app (contents) | Yes: a bundled web UI (README) | An admin page to add devices, pick folders and see status; we found no file browser in it (getting started) | Yes, it is the whole product: “upload, delete, preview and edit your files” (README) | Yes: the project is a web file manager (README); we did not open the web interface in a browser |
| Share by link | Public link shares with an optional password and expiry date (sharing) | Share links with password and expiry, plus upload links (sharing) | A public-links service with password brute-force protection (docs) | No link sharing in the pages we read: a folder is shared with devices you add by device ID (getting started) | A per-user share permission, on by default (CLI reference); we did not read what a share offers |
Sharing options, including an expiration time, are listed (README); we did not try a share |
| Desktop sync client | Windows 10+, macOS 13+, Linux AppImage (clients) | A desktop client with selective sync and conflict pages (manual) | An ownCloud desktop app (documentation index) | Syncthing itself runs on each device: Linux, Windows, macOS and BSD builds (downloads) | None; browser only | None found in the README; we did not look further |
| Mobile apps | Android and iOS, with instant upload for photos and videos (clients) | Android and iOS clients (manual) | Android and iOS apps (documentation index) | No official iOS support planned (FAQ); the official Android app is discontinued: its README says the last release would be the December 2024 Syncthing version, the repository is archived (banner: Dec 3, 2024), and no replacement is named (repository) | None; browser only | The comparison chart in the README marks a mobile app as unavailable |
| Office documents | Nextcloud Office (needs a Euro-Office Document Server) or Collabora Online (a self-hosted server or a built-in app) (office docs) | OnlyOffice integration and SeaDoc (OnlyOffice, manual) | Collabora Online, OnlyOffice Docs or Microsoft Office Online Server through a WOPI gateway (README) | None: it copies files, and an app on each device opens them | Previews and edits files; no office suite listed | The comparison chart in the README lists office file support and previews; we did not test either |
| Calendar and contacts (not Drive, but part of a Google account) | CalDAV and CardDAV; the Calendar app “comes installed with Nextcloud Hub by default, but can be disabled” (groupware, calendar); we did not check what our Docker stack enabled | None in the manual’s contents | None in the 8.2 documents we read (details) | Not its job | Not its job | Not its job |
| Photos | A Photos app with timeline and albums, included since Nextcloud 18 (README) | A Gallery view that groups images by date, part of the Metadata feature, which the manual lists as an extra Metadata Server component (Gallery view, manual) | Photo upload from the Android app only: “Upload of photos and videos recorded on your Android device”; no timeline or albums checked (Android app) | Folder sync only | Previews files only (README) | Thumbnails and previews are listed (README); we checked no timeline or albums |
Photo backup from a phone is a different job from file sync. For a photo library with machine-learning search, see the Immich Docker Compose guide and its measured RAM.
Nextcloud: the full suite
Nextcloud is the closest match to a whole Google account: files, plus a calendar, contacts and online office as documented add-ons. In the lab, the four-container stack (app, cron, PostgreSQL, Redis) idled at 297 MiB and peaked at 452 MiB while one user uploaded the 103 files over WebDAV (35.0.2, Oct 18; the Oct 8 run on 35.0.1 gave 299 and 454). The load was files over WebDAV only; we did not set up or use the calendar, contacts or office apps, so these numbers say nothing about them. It is also the only app here for which we ran proxy, cron, update and restore tests.
The verified compose file, the trusted-domain, Redis and cron settings and the reverse proxy are in the Nextcloud Docker Compose guide, so we do not repeat them. Why you might pick it over Seafile or Infinite Scale is in When to pick Nextcloud.
Seafile: files are the whole job
Seafile 13.0.28 idled at 616 MiB across Seafile, MariaDB and Redis, and peaked at 905 MiB during the upload. That is the most RAM and the most image data (720.0 MB) of the six, and the only 2 GB tier. Its manual describes a Git-like block storage model and a desktop client with selective sync (researched). It has no calendar or contacts section in the manual’s contents. The lab used Seafile’s upload API because its WebDAV component is off by default; we did not run the sync client.
The lab’s compose file and .env are under Compose files in the comparison. The reasons to pick it are under When to pick Seafile.
ownCloud Infinite Scale: one small container
Infinite Scale 8.2.1 (oCIS, ownCloud’s Go rewrite) is one container: 151 MiB idle, 305 MiB under the upload, 87.5 MB of image. That is a little over half of Nextcloud’s idle RAM (297 MiB), with the noise noted above. ownCloud’s own guidance of 4GB for production, and its production Compose example with Collabora and ONLYOFFICE asking for “at minimum 4-6GB”, is the number to plan on for real users. We tested Infinite Scale, not ownCloud Classic (the PHP server), and the license terms for the Docker image are unsettled in our sources; both are covered in Which ownCloud and Infinite Scale license.
Syncthing: sync between your devices, no server
Syncthing is not a cloud or a server. Its FAQ says it “does not upload your data to the cloud but exchanges your data across your machines as soon as they are online at the same time”. Every device runs the same program, and two devices connect only if each has the other’s device ID (getting started). There are no share links, and its web page manages devices and folders rather than showing your files (researched, see the table above). What you get instead is a copy of a folder on each device, with nothing stored on a server you pay for unless you choose to run one as an always-on peer. Check your phones before choosing it: its FAQ says the team has no plans to support iOS officially, and the official Android app is discontinued (feature table above).
That changes what the lab could measure. Syncthing has no upload call, so the lab ran two nodes, wrote the 103 files into node A’s folder and timed how long node B took to have them all. The second node and a shared volume are lab-only; the compose file below is the single node you would run.
| Syncthing v2.1.6, Oct 16, 2026, 3 runs, AMD EPYC 7763 (lab host) | Median | Lowest to highest run |
|---|---|---|
| Idle RAM, node A, MiB | 21.9 | 21.7 to 23.7 |
| Idle RAM, node B, MiB | 23.5 | 21.8 to 23.8 |
| Peak RAM while syncing, node A (files written here), MiB | 64.6 | 64.0 to 65.3 |
| Peak RAM while syncing, node B (receiver), MiB | 45.4 | 43.5 to 46.6 |
| Time until node B had all 103 files (194.5 MB), s | 2.77 | 2.73 to 2.91 |
| Files on B matching their SHA-256 | 103 of 103 in all 3 runs | |
| Failed REST calls | 0 in all 3 runs |
Source: syncthing.json (raw result), figures in lab/notes/gdrive-alternatives-2026-10-17.md. The peak rests on 4 samples per node.
Two more differences from a node you would run. The lab switched off global discovery, local discovery, relays, NAT traversal and usage reporting, and the network had no route out, so idle RAM on a node with those on may differ; we did not measure that. And we found no RAM guidance in Syncthing’s FAQ. Our test had 103 files; memory for a large library was not measured.
The compose file below is the single node you would run. The lab ran this image and its healthcheck in the two-node setup above, not this exact file with its ports mapped (its header says so). Its header comments also mark where it differs from the project’s Docker README. Set a password for the web interface before you publish its port to anything but localhost, as the file’s header says.
# Verified compose for Syncthing, tested 2026-10-16 by the SelfHostBench lab (3 runs; the figures are the median).
# Lab host: AMD EPYC 7763 64-Core Processor, 2 vCPU, 7.8 GiB RAM, x86_64, Docker 28.0.4.
# Floating image tags below were replaced by the version resolved at test time;
# the registry digest is in the comment on each image line.
# Measurements: syncthing.json (schema 3).
# Lab difference: Syncthing is peer to peer, so the lab runs TWO nodes: the published service (node A) and a second, identical service (node B, `syncthing-b`), which is not in the published file. The lab publishes no host ports, puts both on a Compose network with no route out (`internal: true`), gives each node a fixed GUI API key, and mounts one shared volume at /data in both nodes so the load step can write into node A's folder and read the files node B received. A real deployment has one node per device, on different machines. Image, user, volume at /var/syncthing and healthcheck are the published file's. The published single-node file has not been run with its ports mapped in the lab.
# Syncthing 2.1.6: continuous peer-to-peer file synchronisation. This is ONE node, the thing you run on a server and pair your laptop, phone and other machines with.
# Syncthing has no central server and no upload API: every device runs the same program, and a folder is shared by adding the other device's ID on both sides.
#
# Follows README-Docker.md of the Syncthing repository (tag v2.1.6). Differences from it, all marked below: a pinned tag, a named volume instead of ./st-sync,
# published ports on a bridge network instead of `network_mode: host`, the web interface bound to localhost only, a 5-second healthcheck.
# The GUI has no password after the first start. Set one (Actions > Settings > GUI, "GUI Authentication User" and "Password") before you publish the port to anything but localhost.
name: syncthing
services:
syncthing:
image: syncthing/syncthing:2.1.6 # sha256:4d0281bdcb4ed9baf503d251d0544ddd856f49fce3f114056257ae172b7fb670 (version v2.1.6, from label:org.opencontainers.image.version)
# The name other devices show for this one. Change it.
hostname: my-syncthing
restart: unless-stopped
environment:
# The user the process runs as (the image starts as root and switches). Files in your folders are owned by this user.
PUID: "1000"
PGID: "1000"
# The image sets STGUIADDRESS=0.0.0.0:8384 so the GUI answers on the Docker network; the port mapping below keeps it on localhost of the host.
ports:
# Web GUI and REST API. Localhost only: reach it with an SSH tunnel (ssh -L 8384:127.0.0.1:8384 you@server) or put a TLS reverse proxy in front.
- "127.0.0.1:8384:8384"
# Sync protocol (TCP, and QUIC over UDP). Other devices connect here; open it in the server's firewall.
- "22000:22000/tcp"
- "22000:22000/udp"
# Local discovery (UDP broadcast). It does not cross Docker's bridge network, so on a LAN it finds nothing from here; README-Docker.md recommends
# `network_mode: host` for that reason (then delete this `ports:` block). On a VPS, devices find each other by address or global discovery, and this line is unneeded.
- "21027:21027/udp"
volumes:
# Configuration, keys, the index database and the default folder (~/Sync = /var/syncthing/Sync). Your device ID comes from the key in here: back it up.
- syncthing:/var/syncthing
# More folders: mount them below and add them in the GUI. A named volume or a path, for example:
# - /srv/files:/data/files
healthcheck:
# The image's own check (the no-auth health endpoint) with a 5 s interval instead of 60 s, so the container is "healthy" a few seconds after the start.
test: ["CMD-SHELL", "curl -fkLsS -m 2 127.0.0.1:8384/rest/noauth/health | grep -o --color=never OK || exit 1"]
interval: 5s
timeout: 5s
start_period: 5s
retries: 3
volumes:
syncthing:FileBrowser Quantum: the maintained web file manager
FileBrowser Quantum is a web file manager for one or more folders on a server, and the one we would pick for a new install: it is maintained and idled at 29.3 MiB. Its README calls it “a massive fork of the file browser open-source project”, and it is Apache-2.0 licensed. The archived File Browser’s README does not name it or any other successor (see the next section). It is actively released: the releases page, read Oct 18, 2026, lists seven tagged releases between Oct 4 and Oct 13 (stable and beta; the page gives no year, and the Docker Hub push date for 2.0.1-stable is Oct 13, 2026). Release v2.0.1-stable, the one we tested and marked Latest, fixed two advisories: a High one (“New accounts named with “..” breaks out of scoped folder on creation”) and a Medium one (a session token collision when several users log in at once). So update promptly. It has its own API (calls take source and path parameters), a YAML config file and a SQLite database, so we treat it as a different program from File Browser 2.63.23, not a new version, and its numbers are a separate row.
We tested gtstef/filebrowser:2.0.1-stable, the project’s stable channel, which its version page calls “the most reliable version as the name implies” (beta “may encounter unexpected issues”). The lab host was a GitHub Actions runner with an Intel Xeon Platinum 8573C (2 vCPU), on Oct 18, 2026, three runs, the same 103 files as the other apps. The load went through Quantum’s documented upload call (POST /api/resources), one request per file; the web interface cuts large uploads into chunks, and we did not use that path.
| FileBrowser Quantum 2.0.1-stable, Oct 18, 2026, 3 runs, Intel Xeon Platinum 8573C (lab host) | Median | Lowest to highest run |
|---|---|---|
| Idle RAM, MiB | 29.3 | 27.4 to 31.4 |
| Peak RAM during the 103-file load, MiB | 44.0 | 41.9 to 48.1 |
| Idle CPU, % of one core (lab host) | 0.45 | 0.45 to 0.46 |
| Image to download, MB | 63.1 | |
| Our sizing tier | 1 GB | highest reading 48.1 MiB, times 1.5 is 72 MiB |
| Requests that failed | 0 of 110 in all 3 runs | |
| Downloaded files matching their SHA-256 | 5 of 5 in all 3 runs |
Source: filebrowser-quantum.json (raw result), figures in lab/notes/gdrive-alternatives-2026-10-18.md. The peak rests on 3 samples per run. The folder listing reports sizes as disk usage (4 KiB blocks), so the lab checked the 103 names and that no size was below the file’s length; the listing summed to 194,654,208 bytes against 194,456,599 uploaded.
Against the archived File Browser. Quantum idled at about twice the RAM in these runs: 29.3 MiB against 14.7 MiB (2.0 times), 44.0 against 22.8 MiB at peak (1.9 times), and a 63.1 MB image against 16.8 MB (3.8 times). The idle ranges do not overlap (27.4 to 31.4 against 12.8 to 14.8). Both sit in our 1 GB tier. Treat the ratio as two runs on two hosts, not a controlled comparison: File Browser ran on Oct 16 on an AMD EPYC 9V45, Quantum on Oct 18 on an Intel Xeon Platinum 8573C, and the two programs use different APIs. RAM and image size carry across hosts better than timings, and we do not compare upload times. The default image includes ffmpeg and document preview; the project’s -slim variant leaves them out, and we did not test it.
What the idle figure does not include. Quantum indexes its folder in a SQLite database: one pass at start, then scheduled scans. The indexing page says scans run on “a complexity-based schedule that ranges from 5 minutes to 12 hours”, and gives 50 MB for a full scan of 10,000 folders and 10,000 files (150 MB for 50,000 and 50,000). In two probes on our development sandbox, not published results, the debug log scheduled the first scan 12 min 51 s and 17 min 40 s after the start, and a lab run lasts about 3 minutes, so we saw no scan inside the idle or load windows (lab/notes/filebrowser-quantum-2026-10-18.md, section 4). The same probe saw memory after a load fall slowly, from 36 to 21.6 MiB over 8 minutes, and a scan with 103 files add about 4.5 MiB. Idle here is an empty folder, measured before the load; a stack just after a big upload will read higher, and a large tree will use more.
The compose file below is the one the lab ran.
# Verified compose for FileBrowser Quantum, tested 2026-10-18 by the SelfHostBench lab (3 runs; the figures are the median).
# Lab host: INTEL(R) XEON(R) PLATINUM 8573C, 2 vCPU, 7.8 GiB RAM, x86_64, Docker 28.0.4.
# Floating image tags below were replaced by the version resolved at test time;
# the registry digest is in the comment on each image line.
# Measurements: filebrowser-quantum.json (schema 3).
# Companion env file: filebrowser-quantum.env (save it as .env next to this file).
# Secrets are not published: the lab's values are public. In filebrowser-quantum.env:
# FILEBROWSER_ADMIN_PASSWORD is commented out. Uncomment it and set your own value (the comment above it explains how).
# FileBrowser Quantum 2.0.1 (stable channel): a web file manager for one or more folders on the server. The actively maintained fork of the archived File Browser
# (filebrowser/filebrowser, archived 2026-09-01). Single container, no database server (users and settings are in a SQLite file).
#
# Follows the Docker page of the project's docs (filebrowserquantum.com, "Getting started > Docker", v2.0.x): the image, a data directory at /home/filebrowser/data that holds
# config.yaml, the database and the cache, port 80, runs as UID/GID 1000. Differences from the docs, all marked below: a pinned tag, the admin password set through the
# environment (the docs let Quantum print a random one into the log), ONE named volume instead of two /path bind mounts (the served folder is a directory inside it),
# the config file written inline under `configs` (needs Docker Compose 2.23.1 or newer), a localhost-only port, and a health check every 5 s.
#
# Channels: Quantum ships a `stable` and a `beta` channel. This file follows STABLE (2.0.x). Beta (2.1.x) gets new features first and "may encounter unexpected issues".
# Image variants: the default image (about 60 MB) includes ffmpeg and document preview; `-slim` (about 15 MB) leaves them out. This file uses the default image.
#
# Do not expose it directly to the internet: put a reverse proxy with TLS in front.
name: filebrowser-quantum
services:
filebrowser:
image: gtstef/filebrowser:2.0.1-stable # sha256:2e3936caf7b12908f7d3ebb68ddfcea075cda5f732e4bd95beae6cfa529cbec7 (version v2.0.1-stable, from label:org.opencontainers.image.version)
restart: unless-stopped
# Quantum does not create the folder it serves, and a second named volume would belong to root while Quantum runs as UID 1000 and must write into it.
# So the folder is a directory inside the data volume (which the image prepares for UID 1000), made here before Quantum starts. `exec` keeps Quantum as the main process.
# With a /path bind mount of a folder you own, as in the docs, you do not need this line: mount it at /folder and set `path: /folder` in the config below.
entrypoint: ["sh", "-c", "mkdir -p /home/filebrowser/data/files && exec ./filebrowser"]
ports:
# Localhost only. A reverse proxy on the host sends traffic here. The docs publish 80:80 on every interface.
- "127.0.0.1:8080:80"
environment:
# The admin password (the user is `admin` unless auth.adminUsername is set in config.yaml). Set in .env. Quantum uses any value except an empty one or `admin`
# as given and does not ask for a change at the first login. Without a value it generates a random password and prints it once in the log
# (docker compose logs filebrowser), which is what the docs describe; here a value is required so the first login is known.
# The docs say a password set in the configuration is applied again at every start, so change it here, not only in the web interface.
FILEBROWSER_ADMIN_PASSWORD: "${FILEBROWSER_ADMIN_PASSWORD:?set FILEBROWSER_ADMIN_PASSWORD in .env}"
volumes:
# config.yaml is mounted here (see `configs`). Quantum keeps its SQLite database (database.sqlite: users, settings, shares) and its cache (tmp/) here, and the folder it
# serves is files/ in this directory. This is your data: back it up.
- filebrowser-data:/home/filebrowser/data
configs:
- source: quantum_config
target: /home/filebrowser/data/config.yaml
healthcheck:
# The image's own check (GET /health with curl, every 30 s, 10 s start period) with a shorter interval so the container is marked healthy within seconds.
test: ["CMD", "curl", "-f", "http://localhost:80/health"]
interval: 5s
timeout: 3s
start_period: 2s
retries: 3
configs:
quantum_config:
content: |
# FileBrowser Quantum config (docs: filebrowserquantum.com > Configuration; every key not set here has its default).
server:
# Thumbnails, the icon cache and other cached files; inside the data volume so they survive a restart.
cacheDir: /home/filebrowser/data/tmp
sources:
# The folder to serve, from the container's point of view (never "/" and never /var). `name` is how the API refers to the source.
- path: /home/filebrowser/data/files
name: files
config:
# New users (and, from 2.0.1, every user at every start) get this source.
defaultEnabled: true
volumes:
filebrowser-data:Two parts of it differ from the project’s Docker page, which mounts a folder you own at /folder and a ./data directory. Both are explained in the file’s header and in lab/notes/filebrowser-quantum-2026-10-18.md (section 2).
- The
entrypointline. Quantum does not create a missing source folder (it fails with “Failed to open root directory … no such file or directory”), and a second named volume would belong to root while Quantum runs as UID 1000 and must write into it. So the served folder is a directory inside the data volume, which the image prepares for UID 1000, and the container creates it withmkdir -pbeforeexec ./filebrowser. A one-shot service that fixes ownership would also work, but the lab harness expects every service to keep running. With a bind-mounted folder you own, as in the docs, you can drop the line and mount it at/folder. Not tested in our lab: the lab used the one-volume layout. - The
configs:block. Theconfig.yamlis written inline in the compose file (this needs Docker Compose 2.23.1 or newer) instead of a file you create. It is mounted read-only and Quantum starts and runs normally with it, because it writes nothing toconfig.yaml. Its one source is the folder from the line above, withdefaultEnabled: trueso every user gets it.
The stack does not start without an admin password, and the file takes it from .env. The lab’s value is public, so the .env below has the line commented out: uncomment it and set your own. Do not leave a placeholder, because Quantum uses any value except admin or an empty one as the real password.
# Admin password of FileBrowser Quantum (user `admin`). Choose your own, long. The stack does not start without it.
# A placeholder would become a real, known password, so the lab's value is not published and this line is commented out.
# Generate one with: openssl rand -hex 16
# FILEBROWSER_ADMIN_PASSWORD=What we did not test for Quantum: login by OIDC, LDAP or a proxy; a large folder tree (only the docs’ figures above); previews and thumbnails, which the web interface generates and our API load never asked for; chunked uploads from the web interface; and the beta channel (2.1.x). The full list is under What we did not test.
File Browser: archived upstream
File Browser is a web file manager for one directory on a server. It is the smallest app in this test, at 14.7 MiB idle (12.8 to 14.8), 22.8 MiB peak and a 16.8 MB image, and the lab’s 110 requests all succeeded. It is also unmaintained. The project’s README, read Oct 17, 2026, opens with (GitHub’s own banner on the repository reads Aug 31, 2026):
File Browser is archived on 2026-09-01. The last planned release has already shipped. There will be no further releases, bug fixes, or security fixes.
The README lists two classes of issue that “will not be fixed”: the command runner and hooks (off by default), and session tokens that cannot be revoked, so a leaked token stays valid until it expires. For anyone still running it, the README says not to expose it directly to the internet and to put it behind a reverse proxy that does TLS and its own authentication. Our version, 2.63.23, is the last release (Jul 27, 2026). Our advice, based on those two unfixed issue classes and the end of security fixes: do not start a new install.
The README does not name a successor; it links only a July 2026 background post. The fork we tested, FileBrowser Quantum, is in the section above. We keep these numbers as a record of what existed: the maintained fork we tested uses about twice the RAM, and we did not test whether Quantum opens a File Browser database.
How to migrate
Not run in our lab: we moved no real data into or out of any of these apps. What the sources say.
- Export from Google. Google’s Takeout help page (read Oct 17, 2026) says you can export Drive data as Zip or Tgz archives, delivered by “Add to Drive”, which counts toward your Google storage, and that “Your archive expires in about 7 days”. It does not say whether Google Docs, Sheets and Slides are converted to other formats, so open a few exported files before you delete anything.
- Import. Each app takes plain files. Nextcloud and Seafile take uploads in the web interface or through their desktop clients, Syncthing takes whatever you put in the shared folder, and File Browser and FileBrowser Quantum serve a directory. We did not test any import, and calendars, contacts, shares and version history do not come with a file copy.
- Back up first. The only restore we tested is Nextcloud’s, in its guide. A database dump alone did not restore there.
What we did not test
- Desktop and mobile sync clients for any app: the lab used API scripts, and for Syncthing a second container.
- Photo backup and photo apps, including Nextcloud’s Photos. For photos, see the Immich guide.
- Online office (Collabora, OnlyOffice, Euro-Office, SeaDoc), full-text search and previews.
- More than one user, sharing, public links, and files over 50 MB.
- A transfer over the internet or a relay, Syncthing with discovery and relays on, and any large library. Every app had 103 files.
- ARM hardware (one x86-64 runner type only), and memory growth over days.
- ownCloud Classic, Seafile 14 and Nextcloud AIO.
- FileBrowser Quantum beyond the API load: the web interface in a browser, OIDC, LDAP and proxy login, a large folder tree, previews and thumbnails, chunked uploads, WebDAV, shares, several users, a reverse proxy, the beta channel (2.1.x), the
-slimimage, and moving a File Browser database into it. - The apps behind a real reverse proxy with a domain. Only Nextcloud has that test, in its guide.
- Hosted services, including Proton Drive.
Hosting needs
Our tiers are for one user. For a household, use the project’s guidance where it is higher: 4 GB for Infinite Scale, 2 GB for Seafile. Syncthing needs no new server, because it runs on devices you already own. FileBrowser Quantum fits our 1 GB tier (48.1 MiB highest reading, 29.3 MiB idle) with room for a larger folder than our 103 files. File Browser should not be a new install. The module below is for Nextcloud, the full-suite pick; Seafile needs the next RAM tier up.
Where to run it
- Hardware. The Nextcloud stack idled at 297 MiB and peaked at 452 MiB under load (medians of 3 runs) in our lab. The highest reading in any run was 479 MiB. Plan for at least 1 GB of RAM, sized from the highest run.
- VPS. The smallest plan that runs this comfortably has 1 GB of RAM, plus disk for your data and the images. Plan for about 2.9 GB for the images (Docker 29 and later with the containerd image store, the default on fresh installs; 1.9 GB with the older overlay2 store).
- Keep it safe. Back up the data volume before you rely on it, and put the app behind a reverse proxy with HTTPS before you expose it to the internet. See backing up self-hosted apps.
How we size: recommended RAM is the highest reading in any of our runs (under load or during startup, not the median) times 1.5, rounded up to the next of 1, 2, 4, 8, 16 or 32 GB. The extra half covers the operating system, Docker, file cache and spikes our sampling can miss. Your own data and extra apps need more. Disk for images: Docker Engine 29 and later uses the containerd image store on fresh installs, which keeps each image twice (as downloaded and unpacked); older installs use overlay2, which keeps it unpacked only. We plan for the larger figure: unpacked plus compressed size, plus 10%, rounded up. Your data volumes and growth come on top.
Related
- Nextcloud in depth: the Nextcloud Docker Compose guide, with the verified file and the update, backup and restore tests.
- The three file servers side by side, with the host and API caveats: Nextcloud vs ownCloud vs Seafile.
- Photos instead of files: the Immich Docker Compose guide and its RAM requirements.
- How the lab measures RAM, CPU and image sizes: methodology. Other apps in the same format: the self-hosted apps index.
- Primary sources, read Oct 17, 2026: Google’s storage and Takeout help pages; Nextcloud’s sharing, web interface, office and groupware documents, client downloads and Photos README; the Seafile user manual and sharing page; the ownCloud Infinite Scale README and documentation; Syncthing’s FAQ, getting started, config reference, downloads and Android repository; the File Browser README; and, read Oct 18, 2026, the FileBrowser Quantum repository, releases, version page, indexing page and Docker page.
Update log
- Added FileBrowser Quantum 2.0.1-stable (stable channel), lab-tested on Oct 18, 2026 (Intel Xeon Platinum 8573C, 3 runs, the same 103 files through its documented upload API, one request per file): idle 29.3 MiB (27.4 to 31.4), peak 44.0 MiB (41.9 to 48.1), 63.1 MB image, 1 GB tier. It replaces 'researched, not tested' for Quantum, adds a Test box, its compose file, a feature column and a not-tested list, and becomes the page's pick for a simple web file manager; the archived File Browser stays as a record (14.7 MiB idle on an EPYC 9V45 on Oct 16, so Quantum idles at about twice as much on a different CPU). The title says 6 apps (was 5). Figures: lab/notes/gdrive-alternatives-2026-10-18.md.
- Refreshed the Nextcloud figures for the Oct 18, 2026 run (35.0.2, AMD EPYC 7763), which measures idle after the cron container's first background run: idle 297 MiB (range 295 to 301; was 265 on Oct 17 and 299 on Oct 8), peak 452 MiB (range 402 to 479; was 367 and 454), sizing tier unchanged at 1 GB, 676.4 MB of images to download (unchanged). The Oct 17 idle figure was taken before cron's first run in two of its three runs. Ratios against Infinite Scale recomputed (its idle median is 51% of Nextcloud's, was 57%; its peak is 68%, was 83%). The other four apps are unchanged. Figures: lab/notes/nextcloud-2026-10-18.md.
- Refreshed the Nextcloud figures for 35.0.2 (run of Oct 17, 2026, AMD EPYC 7763; was 35.0.1, run of Oct 8): idle 265 MiB (was 299), peak 367 MiB (was 454), sizing tier unchanged at 1 GB, 676.4 MB of images to download (was 674.7). The change is the Nextcloud cron container, not the app (details in the Nextcloud guide). The other four apps are unchanged. Figures: lab/notes/nextcloud-2026-10-17.md.
- First published. Nextcloud 35.0.1 (run of Oct 8, 2026), Seafile 13.0.28, ownCloud Infinite Scale 8.2.1, File Browser 2.63.23 and Syncthing 2.1.6 (runs of Oct 16, 2026), three runs each on GitHub Actions runners, the same 103-file load. Syncthing ran as two lab nodes; the page quotes each node, not the sum. File Browser is archived upstream; FileBrowser Quantum was researched, not tested, at that time. Feature rows are researched from project documents read on Oct 17, 2026. Figures and sources are in lab/notes/gdrive-alternatives-2026-10-17.md.