# Vaultwarden Rate Limiting: How to Configure Login and Admin Protection

> Secure Vaultwarden with rate limiting. Learn to configure login and admin protection using environment variables for robust authentication security. Protect your instance effectively.

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

---

**Vaultwarden protects authentication endpoints with two independent token-bucket rate limiters—one for user logins and one for admin actions—configurable via the `LOGIN_RATELIMIT_*` and `ADMIN_RATELIMIT_*` environment variables.**

The [dani-garcia/vaultwarden](https://github.com/dani-garcia/vaultwarden) repository implements per-IP rate limiting using the **governor** crate to prevent brute-force attacks against both the login API and the admin panel. These mechanisms are instantiated at startup as static singletons and enforce strict request throttling before authentication handlers process credentials.

## How Vaultwarden Rate Limiting Works

Vaultwarden employs **token-bucket limiters** built on the governor crate (v0.10.4), a thread-safe Rust implementation of the leaky-bucket algorithm. Each limiter tracks requests per IP address independently, allowing short bursts while enforcing average rate constraints over time.

### The Two Built-in Limiters

The system maintains separate limiters for different attack surfaces:

**Login Limiter** (`LIMITER_LOGIN` in [`src/ratelimit.rs`](https://github.com/dani-garcia/vaultwarden/blob/main/src/ratelimit.rs))
- **Protects**: All password-login and two-factor authentication attempts
- **Default interval**: 60 seconds per request (`login_ratelimit_seconds`)
- **Default burst**: 10 requests (`login_ratelimit_max_burst`)
- **Config keys**: `LOGIN_RATELIMIT_SECONDS`, `LOGIN_RATELIMIT_MAX_BURST`

**Admin Limiter** (`LIMITER_ADMIN` in [`src/ratelimit.rs`](https://github.com/dani-garcia/vaultwarden/blob/main/src/ratelimit.rs))
- **Protects**: Admin API calls, admin-token validation, and admin UI routes
- **Default interval**: 300 seconds per request (`admin_ratelimit_seconds`)
- **Default burst**: 3 requests (`admin_ratelimit_max_burst`)
- **Config keys**: `ADMIN_RATELIMIT_SECONDS`, `ADMIN_RATELIMIT_MAX_BURST`

Both limiters initialize as `static` `LazyLock` instances at startup, reading configuration values from the global `CONFIG` object:

```rust
// src/ratelimit.rs – login limiter initialization
static LIMITER_LOGIN: LazyLock<Limiter> = LazyLock::new(|| {
    let seconds = Duration::from_secs(CONFIG.login_ratelimit_seconds());
    let burst = NonZeroU32::new(CONFIG.login_ratelimit_max_burst())
        .expect("Non-zero login ratelimit burst");
    RateLimiter::keyed(Quota::with_period(seconds)
        .expect("Non-zero login ratelimit seconds")
        .allow_burst(burst))
});

```

When a protected endpoint receives a request, Vaultwarden calls the appropriate check function before processing credentials:

```rust
pub fn check_limit_login(ip: &IpAddr) -> Result<(), Error> {
    LIMITER_LOGIN.check_key(ip).map_err(|_| err_code!("Too many login requests", 429))
}

pub fn check_limit_admin(ip: &IpAddr) -> Result<(), Error> {
    LIMITER_ADMIN.check_key(ip).map_err(|_| err_code!("Too many admin requests", 429))
}

```

These functions return `HTTP 429 Too Many Requests` immediately when the token bucket for that IP is exhausted.

## Configuring Rate Limits

Vaultwarden reads rate-limiting configuration from environment variables or a `.env` file, with defaults defined in [`src/config.rs`](https://github.com/dani-garcia/vaultwarden/blob/main/src/config.rs).

### Default Configuration Values

According to the configuration structure in [`src/config.rs`](https://github.com/dani-garcia/vaultwarden/blob/main/src/config.rs), the defaults are:

```rust
/// Seconds between login requests
login_ratelimit_seconds:       u64, false, def, 60;
/// Max burst size for login requests
login_ratelimit_max_burst:     u32, false, def, 10;

/// Seconds between admin login requests
admin_ratelimit_seconds:       u64, false, def, 300;
/// Max burst size for admin login requests
admin_ratelimit_max_burst:     u32, false, def, 3;

```

### Environment Variable Configuration

Set the following variables in your environment or `.env` file (documented in `.env.template` lines 451-455):

```dotenv

# .env file

LOGIN_RATELIMIT_SECONDS=120
LOGIN_RATELIMIT_MAX_BURST=5
ADMIN_RATELIMIT_SECONDS=60
ADMIN_RATELIMIT_MAX_BURST=2

```

When running the Docker image, pass variables directly:

```bash
docker run -d \
  -e LOGIN_RATELIMIT_SECONDS=120 \
  -e LOGIN_RATELIMIT_MAX_BURST=5 \
  -e ADMIN_RATELIMIT_SECONDS=60 \
  -e ADMIN_RATELIMIT_MAX_BURST=2 \
  -v /path/to/data:/data \
  vaultwarden/server:latest

```

### Admin UI Configuration

You can modify rate limits through the Vaultwarden admin UI, which persists values to [`DATA_FOLDER/config.json`](https://github.com/dani-garcia/vaultwarden/blob/main/DATA_FOLDER/config.json). However, **environment variables take precedence** over UI-configured values. For permanent changes that survive container restarts or UI resets, use the `.env` file or Docker environment variables.

## Practical Implementation Examples

### Tightening Security for High-Risk Deployments

To reduce brute-force vulnerability for internet-facing instances:

```dotenv

# Require 5 minutes between login attempts, allow burst of 3

LOGIN_RATELIMIT_SECONDS=300
LOGIN_RATELIMIT_MAX_BURST=3

# Restrict admin access to once per 10 minutes, burst of 1

ADMIN_RATELIMIT_SECONDS=600
ADMIN_RATELIMIT_MAX_BURST=1

```

### Disabling Rate Limits for Internal Networks

While not recommended for production, you can effectively disable limiting by setting high burst values (though Vaultwarden requires non-zero values):

```dotenv

# Effectively unlimited for trusted networks

LOGIN_RATELIMIT_SECONDS=1
LOGIN_RATELIMIT_MAX_BURST=1000
ADMIN_RATELIMIT_SECONDS=1
ADMIN_RATELIMIT_MAX_BURST=1000

```

## Key Source Files

- **[`src/ratelimit.rs`](https://github.com/dani-garcia/vaultwarden/blob/main/src/ratelimit.rs)**: Contains the `LIMITER_LOGIN` and `LIMITER_ADMIN` static instances, plus `check_limit_login()` and `check_limit_admin()` functions.
- **[`src/config.rs`](https://github.com/dani-garcia/vaultwarden/blob/main/src/config.rs)**: Defines the configuration structure with default values for the four ratelimit parameters.
- **[`src/api/identity.rs`](https://github.com/dani-garcia/vaultwarden/blob/main/src/api/identity.rs)**: Invokes `check_limit_login()` before processing identity authentication requests.
- **`.env.template`**: Documents the environment variables for operator configuration.

## Summary

- Vaultwarden uses **two independent token-bucket limiters** (governor crate) to protect login and admin endpoints separately.
- **Login rate limiting** defaults to 60-second intervals with a burst capacity of 10 requests per IP.
- **Admin rate limiting** defaults to 300-second intervals with a burst capacity of 3 requests per IP.
- Configure limits via the `LOGIN_RATELIMIT_SECONDS`, `LOGIN_RATELIMIT_MAX_BURST`, `ADMIN_RATELIMIT_SECONDS`, and `ADMIN_RATELIMIT_MAX_BURST` environment variables.
- Exceeded limits return **HTTP 429** responses with descriptive error messages.
- Environment variables override settings configured through the admin UI.

## Frequently Asked Questions

### How do I know if Vaultwarden is rate limiting my requests?

When a client exceeds the configured burst size or average rate, Vaultwarden returns **HTTP 429 Too Many Requests** with the message "Too many login requests" or "Too many admin requests" before processing authentication logic. Check your reverse proxy or application logs for these status codes if legitimate users experience lockouts.

### What's the difference between the login and admin rate limiters?

The **login limiter** protects password-based authentication and two-factor endpoints in [`src/api/identity.rs`](https://github.com/dani-garcia/vaultwarden/blob/main/src/api/identity.rs), while the **admin limiter** restricts access to the admin API, admin-token validation, and management UI routes. They operate independently, meaning hitting the login limit does not affect admin access and vice versa.

### Can I configure rate limits through the admin UI instead of environment variables?

Yes, the admin UI persists rate limit changes to [`config.json`](https://github.com/dani-garcia/vaultwarden/blob/main/config.json) in the data folder, but these values are **overridden by environment variables** if both are present. For Docker deployments or infrastructure-as-code setups, environment variables provide more reliable, reproducible configuration.

### Do rate limits apply per user account or per IP address?

Vaultwarden applies rate limits **per IP address**, not per user account. The `check_limit_login()` and `check_limit_admin()` functions extract the client IP from the request and use it as the key for the token-bucket tracker. This prevents attackers from cycling through different usernames to bypass limits, but means shared NAT gateways (corporate networks, VPNs) share the same rate limit budget.