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

> Learn how to configure Vaultwarden's supported database backends including PostgreSQL, MySQL, and SQLite. Easily set up your chosen database with DATABASE_URL.

- Repository: [Daniel García/vaultwarden](https://github.com/dani-garcia/vaultwarden)
- Tags: how-to-guide
- Published: 2026-03-07

---

**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`](https://github.com/dani-garcia/vaultwarden/blob/main/src/db/mod.rs) and [`Cargo.toml`](https://github.com/dani-garcia/vaultwarden/blob/main/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`](https://github.com/dani-garcia/vaultwarden/blob/main/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`](https://github.com/dani-garcia/vaultwarden/blob/main/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:

```bash

# 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:password@127.0.0.1:3306/vaultwarden`
- **PostgreSQL**: `DATABASE_URL=postgresql://user:password@127.0.0.1:5432/vaultwarden`

The `DbConnType::from_url` implementation parses these prefixes to determine which driver to initialize (lines 57‑82 of [`src/db/mod.rs`](https://github.com/dani-garcia/vaultwarden/blob/main/src/db/mod.rs)).

### Connection Pool Tuning

Vaultwarden exposes five environment variables for pool optimization, read in [`src/config.rs`](https://github.com/dani-garcia/vaultwarden/blob/main/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:

```env
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:

```yaml
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:

```env
ENABLE_DB_WAL=true

```

This triggers `PRAGMA journal_mode = WAL;` on each connection via `DbConnType::default_init_stmts` in [`src/db/mod.rs`](https://github.com/dani-garcia/vaultwarden/blob/main/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:

```env
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`](https://github.com/dani-garcia/vaultwarden/blob/main/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`](https://github.com/dani-garcia/vaultwarden/blob/main/Cargo.toml) lines 24‑29.
- Runtime backend selection occurs via `DATABASE_URL` parsing in `DbConnType::from_url` ([`src/db/mod.rs`](https://github.com/dani-garcia/vaultwarden/blob/main/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`](https://github.com/dani-garcia/vaultwarden/blob/main/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`](https://github.com/dani-garcia/vaultwarden/blob/main/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`](https://github.com/dani-garcia/vaultwarden/blob/main/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`](https://github.com/dani-garcia/vaultwarden/blob/main/src/config.rs) and applied in `DbPool::from_config()` in [`src/db/mod.rs`](https://github.com/dani-garcia/vaultwarden/blob/main/src/db/mod.rs) (lines 183‑206). You can override these defaults using `DATABASE_MAX_CONNS`, `DATABASE_MIN_CONNS`, and `DATABASE_TIMEOUT` environment variables.