A password manager is the one service where “I will sort out the backup later” really means “I will lock myself out of everything later.” So before you pick software, decide whether you want to run a server at all.
The short answer
You have three self-controlled options. KeePassXC keeps your passwords in one encrypted file on your own devices and needs no server [16][17]. Vaultwarden is an unofficial, lightweight server that the official Bitwarden apps can talk to [1]. The official Bitwarden server comes from the vendor but is a heavier stack, and some of its features need a paid license [9][12]. There is also a fourth option, and it is often the best one: do not self-host, and use a hosted service. Our assessment: if you cannot promise yourself a tested backup and quick updates, a hosted service or a local KeePassXC file is the safer choice. Self-hosting does not change the encryption. It changes who patches the server, who backs it up and who is to blame at 2 a.m.
How it works
- What self-hosting changes, and what it does not. In all three options the vault is encrypted on your device before it is stored. Bitwarden lists zero-knowledge encryption as a core property [14]. A KeePassXC database is always fully encrypted, and unencrypted data is never written to disk [16]. A self-hosted Bitwarden-compatible server therefore holds ciphertext, not your passwords. What moves to you is everything around it: the operating system, the container image, the TLS certificate, the backup and every update. If the server or its backup disappears, so does access to your accounts, unless you keep another copy.
- Vaultwarden is unofficial. The project describes itself as an “unofficial Bitwarden compatible server written in Rust” and states that it is not associated with Bitwarden or Bitwarden, Inc. One active maintainer works at Bitwarden and contributes in their own time, independent of the company [1]. The README asks you to report problems to the Vaultwarden project and not to the official Bitwarden support channels [1]. Bitwarden says the same from its side: it cannot guarantee that official clients work perfectly with non-official servers such as Vaultwarden, and its support may be limited if you use one. It advises keeping such a server as up to date as possible [13]. Bitwarden’s security audits are listed for Bitwarden’s own apps, web vault and libraries [15]. We found no statement that they cover Vaultwarden. Our assessment: do not treat those audits as a certificate for the server software you run.
- Updates are part of the deal. Vaultwarden 1.37.4 was released on 5 Oct 2026 as a security release. Its notes list seven advisories: one rated High (8.1), five Medium and one Low, concerning organization membership, two-factor authentication, invitations, attachments, event logs, cipher sharing and the organization API key. The project says they were still private pending CVE assignment [6]. You do not need to understand every item. The lesson is that fixes ship regularly and that a vault server you never update drifts into risk. Bitwarden says the same about its own server: updates may contain important security fixes, and newer clients may stop supporting older servers [11].
- HTTPS is mandatory, and the proxy comes first. The Vaultwarden web vault needs HTTPS and a secure context for the browser’s Web Crypto API, so it only works with HTTPS enabled. The project recommends a reverse proxy [1]. Its hardening guide advises against the TLS support built into the Rocket web framework, because Rocket itself calls it not ready for production use [4]. Inside the container Vaultwarden listens on port 80, and the README example publishes it only to the loopback address
127.0.0.1:8000so that the proxy is the only way in [1]. Bitwarden’s own server also wants consistent protocols: HTTPS for production, HTTP for testing only, and no mixing of the two between proxy and server [9]. We explain proxies in our guide “Reverse proxy for a homelab” (linked under “Related pages”). - The admin token is a password, so treat it like one. The Vaultwarden admin page is optional. It only exists if you set
ADMIN_TOKEN, and the token is the login password for the page. The wiki recommends a long random value and advises enabling HTTPS first. It also describes how to store the token as an Argon2id hash:vaultwarden hashprints a PHC string, which is a standard hash format, and you put that string intoADMIN_TOKENinstead of the plain password [2]. With Docker Compose you must escape each$as$$, or keep the value in a.envfile in single quotes [2]. Admin sessions last 20 minutes by default [2]. If you do not need the page, leaveADMIN_TOKENunset and the page stays off [2][5]. The hardening guide adds two more switches: disable open registration after you have created your accounts (SIGNUPS_ALLOWED=false), and keep password hints from being shown on the login page [4][5]. - Backups: what exactly goes in. Vaultwarden keeps its state in a
datafolder. With the default SQLite database, the wiki marks the database file and theattachmentsfolder as required,config.jsonand thersa_key*files as recommended, andsendsandicon_cacheas optional [3]. Do not copy the live database file blindly. The wiki recommends the SQLite.backupcommand, and since version 1.32.1 there is a built-in/vaultwarden backupcommand. It also advises at least one remote copy, an extra layer of encryption (the config file holds the admin token and mail credentials in plain text), and no reliance on VM or filesystem snapshots as the only method [3]. Restoring means stopping Vaultwarden, replacing the files and deleting any olddb.sqlite3-walfirst [3]. The wiki also says to rehearse the restore. Our restic guide covers the tooling (linked under “Related pages”). - The official self-hosted server. Bitwarden’s standard Linux deployment needs Docker Engine 26 or newer and at least 2 GB RAM and 12 GB storage, with 4 GB and 25 GB recommended. It ships with a Microsoft SQL Server Express database and an installer script, and you request an installation ID and key at bitwarden.com/host [9]. Updates run as
./bitwarden.sh updateselffollowed by./bitwarden.sh update, and Bitwarden recommends a backup first [11]. In the standard deployment the database container takes nightly backups that are kept for 30 days, but the vendor still asks you to copy the whole./bwdatadirectory as a disaster-recovery measure [10]. There is also Bitwarden Lite: one container, at least 200 MB RAM and 1 GB storage, aimed at personal use and home labs, with a choice of SQLite, PostgreSQL, MySQL/MariaDB or MSSQL. It does not take nightly backups, and database maintenance and backups are yours [8][10]. It also needs an installation ID and key [8]. Self-hosting is free, but some features need a license file that you download from a paid cloud subscription [12]. Premium costs US$19.80 per year, billed annually, excluding taxes (pricing page, 24 Oct 2026) [14]. - KeePassXC: no server, different work. The database is a
.kdbxfile. KeePassXC uses the formats KDBX 3.1 and KDBX 4 and recommends KDBX 4 with Argon2, preferably Argon2id, for key derivation. It suggests a decryption time of about one second, and warns that a phone can take two to four times longer than your computer [16][17]. As extra protection you can add a key file or a YubiKey or OnlyKey. Keep the key file away from the synced database folder, and lose neither it nor the master password: both mean the database is gone [16][17]. KeePassXC has no sync of its own. The guide says you can store the file in cloud storage or sync it with tools such as Syncthing or Nextcloud, and recommends a service with version history [16][17]. Version 2.8.0 added remote synchronization with external tools such as rsync or scp, but the guide warns that this is not atomic and later changes on the remote side can be overwritten [16][18]. There is no official mobile app. The team recommends KeePassDX and KeePass2Android for Android and Strongbox and KeePassium for iOS, which are separate projects [17]. The 2.8.0 release of 21 Oct 2026 also fixes several vulnerabilities that affect all 2.7.x versions and earlier. The team rates them low to moderate and none concerns the core cryptography [18]. Update your desktop client as well. - The hosted route. Bitwarden’s free plan is advertised as “always free”, and Premium is listed at US$19.80 per year [14]. Hosted does not mean careless: the audit list shows that the vendor’s own software is regularly tested by outside firms [15].
- A short decision table. Our assessment, not a rule:
| Option | Who runs the server | Fits when | Breaks when |
|---|---|---|---|
| Hosted Bitwarden | Bitwarden | You want the least upkeep and sharing with family | You must keep data strictly on your own hardware |
| KeePassXC file | Nobody | One person or few devices, you accept manual sync and no official phone app | You need shared vaults or many users |
| Vaultwarden | You | You already run backups and updates reliably, and want the Bitwarden apps | Updates or backups are “someday” |
| Official Bitwarden server | You | You need vendor-supported self-hosting, perhaps for an organization | You only want a light home setup (consider Lite) |
A homelab example
This is a sketch for your own server, not a report on ours. We do not state which password manager Bytearium uses. The domain and paths are made up.
Assume Docker with the Compose plugin and a reverse proxy that already serves vault.example.net over HTTPS (see the proxy guide). First hash the admin token. This asks for the password twice and prints a PHC string [2]:
mkdir -p /srv/vaultwarden && cd /srv/vaultwarden
docker run --rm -it vaultwarden/server:1.37.4 /vaultwarden hashSave the printed string in /srv/vaultwarden/.env in single quotes, and restrict the file with chmod 600 .env:
VAULTWARDEN_ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$...'Create /srv/vaultwarden/compose.yaml. The image tag 1.37.4 exists on Docker Hub as of 24 Oct 2026 [7]. Pin it, and change it on purpose when you update:
services:
vaultwarden:
image: vaultwarden/server:1.37.4
container_name: vaultwarden
restart: unless-stopped
environment:
DOMAIN: "https://vault.example.net"
ADMIN_TOKEN: ${VAULTWARDEN_ADMIN_TOKEN}
volumes:
- ./vw-data/:/data/
ports:
- 127.0.0.1:8000:80Check the escaped result with docker compose config, then start with docker compose up -d. For the proxy, pick one of the example configurations the project lists (Caddy, nginx and others) and point it at 127.0.0.1:8000 [1][4]. Open the site, create your account, and then add SIGNUPS_ALLOWED: "false" under environment and run docker compose up -d again so the container is recreated [2][4][5].
Backup, daily from cron on the host (install the sqlite3 package there, because the image has none [3]):
#!/bin/sh
set -eu
D=/srv/vaultwarden
mkdir -p "$D/backup"
sqlite3 "$D/vw-data/db.sqlite3" ".backup '$D/backup/db-$(date +%Y%m%d-%H%M).sqlite3'"
find "$D/backup" -name 'db-*.sqlite3' -mtime +14 -delete
restic -r /mnt/backup/restic-vault backup "$D/backup" "$D/vw-data" \
--exclude "$D/vw-data/icon_cache" --exclude "$D/vw-data/db.sqlite3*"The restic repository must exist already (restic init), and a copy should leave the building. The 3-2-1 and restic guides explain how. Then rehearse: restore to an empty directory, run sqlite3 <file> "PRAGMA integrity_check;" on the restored database, and start a throw-away container on a spare machine behind a test name with HTTPS. Log in once. If that works, you have a backup. If you never try it, you have a hope.
As a last resort independent of any server, export your vault now and then. Bitwarden lists an encrypted export among its features [14], and KeePassXC has a chapter on importing from other applications [16]. Keep exports encrypted and delete the plain ones.
Checklist
- Decide first whether you want to run a server at all, and write down who restores the vault if you are not available.
- Check that the web vault is reachable only through HTTPS, and that the container port is published to
127.0.0.1behind your proxy. - Pin an exact image tag such as
vaultwarden/server:1.37.4, read the release notes before each change, and update promptly after security releases. - Leave
ADMIN_TOKENunset if you do not need the admin page. If you use it, store an Argon2id hash made withvaultwarden hash. - Disable open registration after creating your accounts, and keep password hints off the login page.
- Back up the database with
.backupor/vaultwarden backup, plusattachments,config.jsonand thersa_key*files. Encrypt the copy and keep one off site. - Restore a backup on another machine every quarter, and note the date and result.
- Keep a KeePassXC key file or YubiKey backup apart from the database, and update KeePassXC to 2.8.0 or newer.
- Take the hosted route if you cannot do the steps above in a reliable rhythm.