Laravel Maintenance

axvi/laravel-maintenance
AxVi
4 views
Laravel Maintenance
Advanced maintenance mode management for Laravel with database-driven state, IP whitelisting, bypass tokens, scheduled maintenance windows, and a beautiful 503 page.

Features

  • IP address whitelisting with optional expiration
  • Multiple named bypass tokens (cookie for web, header for APIs, URL bypass)
  • Scheduled maintenance windows with auto-disable
  • Beautiful, customizable 503 page with countdown timer
  • Database-driven — works seamlessly across multiple servers
  • Built-in cache layer — avoids DB queries on every request
  • Exclude paths from maintenance (health checks, webhooks, etc.)
  • Configurable database connection and table names
  • Artisan commands for full CLI management
  • Events: MaintenanceModeEnabled, MaintenanceModeDisabled, MaintenanceBypassGranted
  • Automatically replaces Laravel's built-in maintenance middleware

Installation

composer require axvi/laravel-maintenance

Run migrations:

php artisan migrate

Migrations are loaded automatically. If you need to customize them:

php artisan vendor:publish --tag=maintenance-migrations

Optionally publish the config and 503 view:

php artisan vendor:publish --tag=maintenance-config
php artisan vendor:publish --tag=maintenance-views

How it works

This package replaces Laravel's built-in PreventRequestsDuringMaintenance middleware with its own CheckMaintenanceMode middleware. The bypass check order is:

  1. Excluded paths — URLs matching except patterns are always allowed
  2. IP whitelist — if the request IP is in the maintenance_ips table (cached)
  3. Cookie — if the request has a valid bypass cookie
  4. Header — if the request has a valid token in the X-Maintenance-Token header
  5. 503 response — HTML page with countdown (or JSON for API requests)

All state is stored in the database, so maintenance mode works consistently across multiple application servers. Lookups are cached to minimize performance impact.

Usage

Enable maintenance mode

# Basic
php artisan maintenance:down

# With message, IP whitelist and secret token
php artisan maintenance:down \
  --message="We'll be back in 30 minutes" \
  --allow=192.168.1.1 \
  --secret=my-secret-token \
  --ends-at="2025-01-01 03:00:00"

Disable maintenance mode

php artisan maintenance:up

Manage IPs

php artisan maintenance:ip add 192.168.1.50 --label="Dev machine"
php artisan maintenance:ip add 10.0.0.1 --expires-at="2025-06-01 00:00:00"
php artisan maintenance:ip remove 192.168.1.50
php artisan maintenance:ip list

Manage tokens

# Add with auto-generated UUID token
php artisan maintenance:token add dev-token

# Add with explicit token value
php artisan maintenance:token add dev-token abc123

# Add with expiration
php artisan maintenance:token add temp-token --expires-at="2025-06-01 00:00:00"

php artisan maintenance:token revoke dev-token
php artisan maintenance:token list

Bypass methods

URL bypass (web)

Visit https://yourapp.com/maintenance/{secret-token} — sets a bypass cookie valid for 12 hours. The route prefix is configurable via bypass_route.prefix in the config.

Header bypass (API)

X-Maintenance-Token: my-secret-token

The header name is configurable via middleware.header_name in the config.

Caching

By default, the package caches the maintenance state and IP whitelist to avoid database queries on every HTTP request. The cache is automatically invalidated when you enable/disable maintenance or modify the IP whitelist.

To use a specific cache store (e.g. Redis):

'cache' => [
    'enabled' => true,
    'store'   => 'redis',
    'ttl'     => 30,
],

Found a bug or have a feature request? Open an issue on GitHub. Follow me on LinkedIn or X.

Share this package