Vaultwarden Database Backends: How to Configure PostgreSQL, MySQL, or SQLite

Vaultwarden supports SQLite, MySQL/MariaDB, and PostgreSQL, selected at compile time via Cargo feature flags and at runtime through the DATABASE_URL environment variable.

Vaultwarden, the Rust-based Bitwarden server implementation, provides enterprise-grade password management with flexible database options. Understanding which database backends Vaultwarden supports and how to configure PostgreSQL, MySQL, or SQLite ensures your deployment matches your performance and scalability requirements. This article examines the source code in src/db/mod.rs and Cargo.toml to show exactly how database selection works and how to configure each backend properly.

Supported Database Backends

Vaultwarden can store encrypted vault data in three distinct backends. The actual driver compiled into your binary is determined by Cargo features, while runtime detection occurs through URL scheme parsing in DbConnType::from_url (lines 57‑82 of src/db/mod.rs).

SQLite

SQLite is the default choice for single-container deployments and small teams. It requires no external database server and stores data in a local file. The source code detects SQLite when DATABASE_URL contains a plain file path (e.g., data/db.sqlite3). No additional drivers or network configuration are required, and the database file is created automatically under the DATA_FOLDER directory (default ./data).

MySQL and MariaDB

MySQL and MariaDB support is enabled via the mysql Cargo feature. At runtime, Vaultwarden identifies this backend when DATABASE_URL begins with mysql://. The connection pool is established through DbPool::from_config() (lines 183‑206), which executes MySQL-specific Diesel migrations (mysql_migrations) and creates a DbConnInner::Mysql connection pool type.

PostgreSQL

PostgreSQL support is compiled using the postgresql feature flag. The backend is activated when DATABASE_URL starts with postgresql:// or postgres://. According to the source code, this triggers postgresql_migrations and instantiates the DbConnInner::Postgresql pool type, making it ideal for high-concurrency scenarios requiring robust transactional support.

Compile-Time Configuration with Cargo Features

The Cargo.toml (lines 24‑29) defines three optional features: sqlite, mysql, and postgresql. By default, all database features are disabled, requiring explicit selection during build time to minimize binary size and dependencies.

Enable your desired backend during compilation:


# SQLite only (lightweight, single-file)

cargo build --release --features sqlite

# PostgreSQL support

cargo build --release --features postgresql

# MySQL/MariaDB support

cargo build --release --features mysql

# Multiple backends (runtime selection via DATABASE_URL)

cargo build --release --features "sqlite postgresql mysql"

While you can enable multiple features simultaneously, only the backend matching your DATABASE_URL scheme will be utilized at runtime. The pre-built Docker images (vaultwarden/server) include all three drivers by default.

Runtime Configuration via DATABASE_URL

All database configuration is environment-driven. Vaultwarden reads DATABASE_URL and related pool settings from environment variables or an .env file (see the .env.template in the repository root).

URL Format Examples

Configure your .env file according to your selected backend:

  • SQLite: DATABASE_URL=data/db.sqlite3
  • MySQL: DATABASE_URL=mysql://user:[email protected]:3306/vaultwarden
  • PostgreSQL: DATABASE_URL=postgresql://user:[email protected]:5432/vaultwarden

The DbConnType::from_url implementation parses these prefixes to determine which driver to initialize (lines 57‑82 of src/db/mod.rs).

Connection Pool Tuning

Vaultwarden exposes five environment variables for pool optimization, read in src/config.rs and applied in DbPool::from_config():

  • DATABASE_MAX_CONNS: Maximum pooled connections (default: 10)
  • DATABASE_MIN_CONNS: Minimum idle connections (default: 2)
  • DATABASE_TIMEOUT: Connection acquisition timeout in seconds (default: 30)
  • DATABASE_IDLE_TIMEOUT: Seconds before closing idle connections (default: 600)
  • DATABASE_CONN_INIT: Optional SQL executed on each new connection (e.g., SET sql_mode='STRICT_TRANS_TABLES' for MySQL)

Example .env configuration for a high-traffic PostgreSQL instance:

DATABASE_URL=postgresql://vw_user:vw_pass@db:5432/vaultwarden
DATABASE_MAX_CONNS=20
DATABASE_MIN_CONNS=5
DATABASE_TIMEOUT=15

Docker and Production Examples

PostgreSQL with Docker Compose

For production deployments requiring persistent, networked storage:

version: "3.8"
services:
  vaultwarden:
    image: vaultwarden/server:latest
    environment:
      - DATABASE_URL=postgresql://vw_user:vw_pass@db:5432/vaultwarden
      - DATABASE_MAX_CONNS=20
      - DATABASE_TIMEOUT=15
    volumes:
      - ./vw-data:/data
    ports:
      - "8080:80"
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    environment:
      - POSTGRES_USER=vw_user
      - POSTGRES_PASSWORD=vw_pass
      - POSTGRES_DB=vaultwarden
    volumes:
      - ./pg-data:/var/lib/postgresql/data

SQLite Write-Ahead Logging (WAL)

For improved SQLite durability and concurrency, enable WAL mode:

ENABLE_DB_WAL=true

This triggers PRAGMA journal_mode = WAL; on each connection via DbConnType::default_init_stmts in src/db/mod.rs (lines 94‑102), reducing write locks and improving performance for concurrent access.

MySQL Strict Mode Initialization

Enforce data integrity on MySQL connections using the initialization hook:

DATABASE_CONN_INIT="SET sql_mode='STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';"

The initialization string is passed to Diesel's batch_execute during connection acquisition (src/db/mod.rs, lines 35‑41).

Summary

  • Vaultwarden supports SQLite, MySQL/MariaDB, and PostgreSQL through Cargo feature flags (sqlite, mysql, postgresql) defined in Cargo.toml lines 24‑29.
  • Runtime backend selection occurs via DATABASE_URL parsing in DbConnType::from_url (src/db/mod.rs lines 57‑82), detecting schemes like mysql:// or postgresql://.
  • Connection pools are configured through environment variables including DATABASE_MAX_CONNS, DATABASE_TIMEOUT, and DATABASE_CONN_INIT.
  • SQLite requires no external server and supports WAL mode via ENABLE_DB_WAL, while MySQL and PostgreSQL require reachable database instances with proper credentials.
  • Pre-built Docker images include all database drivers, but custom builds must specify features using cargo build --features.

Frequently Asked Questions

Can I enable multiple database features at compile time?

Yes. You can enable multiple Cargo features simultaneously using syntax like cargo build --release --features "sqlite postgresql mysql". However, at runtime, Vaultwarden will only use the backend that matches your DATABASE_URL scheme. The DbConnType::from_url function in src/db/mod.rs (lines 57‑82) detects the specific prefix (e.g., mysql:// vs. postgresql://) and instantiates only the corresponding connection pool.

How do I enable Write-Ahead Logging (WAL) for SQLite?

Add ENABLE_DB_WAL=true to your environment variables or .env file. When this variable is set, Vaultwarden executes PRAGMA journal_mode = WAL; on each new SQLite connection via the DbConnType::default_init_stmts logic in src/db/mod.rs (lines 94‑102). WAL mode improves concurrency and durability by allowing readers to operate while a writer is active, significantly enhancing performance for multi-user scenarios.

Why does Vaultwarden require feature flags for database support?

Vaultwarden uses Cargo feature flags to keep the compiled binary size minimal and reduce unnecessary dependencies. The Cargo.toml (lines 24‑29) defines sqlite, mysql, and postgresql as optional features, all disabled by default. This modular approach ensures that if you only need SQLite, you don't compile or link MySQL or PostgreSQL client libraries into your binary.

What is the default connection pool configuration?

By default, Vaultwarden maintains a minimum of 2 idle connections and a maximum of 10 total connections, with a 30-second timeout for acquiring new connections. These values are defined in src/config.rs and applied in DbPool::from_config() in src/db/mod.rs (lines 183‑206). You can override these defaults using DATABASE_MAX_CONNS, DATABASE_MIN_CONNS, and DATABASE_TIMEOUT environment variables.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →