Open-Source Wikis

/

Laravel

/

Systems

/

Config

laravel/laravel

Config

Active contributors: Taylor Otwell, Nuno Maduro, Dries Vints

Purpose

config/ holds ten PHP files that define every framework setting the skeleton exposes. Each file is a plain return [ ... ] array of keys; values are mostly read from .env via env(). There is no shared base class and no nesting — one file per subsystem.

Directory layout

config/
├── app.php          # APP_NAME, APP_ENV, APP_KEY, APP_DEBUG, locale, maintenance
├── auth.php         # Default guards, user provider, password reset
├── cache.php        # Cache stores (database/file/redis/memcached/dynamodb/octane/array/failover)
├── database.php     # DB connections (sqlite/mysql/mariadb/pgsql/sqlsrv) + redis
├── filesystems.php  # local, public, s3 disks; storage:link target
├── logging.php      # Log channels (stack/single/daily/slack/papertrail/stderr/syslog/errorlog/null)
├── mail.php         # Mailers (smtp/ses/postmark/resend/sendmail/log/array/failover/roundrobin)
├── queue.php        # Queue connections (sync/database/beanstalkd/sqs/redis/deferred/background/failover)
├── services.php     # Third-party API credentials (postmark, resend, ses, slack)
└── session.php      # Session driver, cookie name, lifetime, same-site, partitioned

LOC across the ten files: ~1300. The bulk lives in database.php (172 lines) and session.php (227 lines) where every option carries a comment block.

How values flow

graph LR
    Env[.env file] -->|parsed by vlucas/phpdotenv| EnvVars[$_ENV / getenv]
    EnvVars -->|env helper| ConfigPHP[config/*.php arrays]
    ConfigPHP -->|loaded by framework| ConfigRepo[Illuminate\Config\Repository]
    ConfigCache[bootstrap/cache/config.php] -.->|skips ConfigPHP if cached| ConfigRepo
    ConfigRepo --> AppCode[Application code]

The env() helper only works during config loading. Inside controllers/services you read configuration via config('app.name') or Config::get(...). Once php artisan config:cache is run, the entire config/ tree is baked into bootstrap/cache/config.php and env() calls inside the cached files become unreachable.

File-by-file summary

config/app.php

The application's identity and core settings.

Key Default Source env
name Laravel APP_NAME
env production APP_ENV
debug false APP_DEBUG
url http://localhost APP_URL
timezone UTC (hardcoded)
locale en APP_LOCALE
fallback_locale en APP_FALLBACK_LOCALE
faker_locale en_US APP_FAKER_LOCALE
cipher AES-256-CBC (hardcoded)
key null APP_KEY
previous_keys [] APP_PREVIOUS_KEYS
maintenance.driver file APP_MAINTENANCE_DRIVER
maintenance.store database APP_MAINTENANCE_STORE

previous_keys is an array_filter(explode(','...)) so multiple comma-separated keys can be rotated without losing the ability to decrypt old payloads.

config/auth.php

Pre-configured for one guard (web) backed by sessions, with the Eloquent provider pointing at App\Models\User. Password reset uses the password_reset_tokens table created by the first migration; expire = 60 minutes; throttle = 60 seconds. Password confirmation timeout: 3 hours (AUTH_PASSWORD_TIMEOUT, default 10800 seconds).

config/cache.php

Default store comes from CACHE_STORE (defaulting to database). Available stores listed in the file: array, database, file, memcached, redis, dynamodb, octane, failover. Cache key prefix defaults to a slugified app name + -cache-. The serializable_classes flag is false by default — a 2026-02-18 change (commit 8a924774) that prevents gadget-chain attacks if APP_KEY leaks.

config/database.php

The most-edited config in any Laravel app. Five connections pre-defined: sqlite (default), mysql, mariadb, pgsql, sqlsrv. The MySQL/MariaDB blocks contain a forward-compat shim:

'options' => extension_loaded('pdo_mysql') ? array_filter([
    (PHP_VERSION_ID >= 80500 ? Mysql::ATTR_SSL_CA : PDO::MYSQL_ATTR_SSL_CA) => env('MYSQL_ATTR_SSL_CA'),
]) : [],

PHP 8.5 deprecated the PDO::MYSQL_ATTR_* constants in favour of Pdo\Mysql::ATTR_*; this branches at runtime so the same config works on 8.3 / 8.4 / 8.5 (commit history references PR #6710 in v12.11.0). The Redis section defines default and cache connections with backoff/retry tuning (max_retries, backoff_algorithm, backoff_base, backoff_cap).

config/filesystems.php

Three disks: local (rooted at storage/app/private), public (rooted at storage/app/public, served via /storage symlink), and s3 (AWS-backed). The links key drives php artisan storage:link, mapping public_path('storage') to storage_path('app/public'). Each disk has throw => false and report => false, so disk operations swallow errors silently — set them to true per-environment if you want exceptions on misconfiguration.

config/logging.php

Default channel is stack (which fans out to whatever LOG_STACK lists, default single). Available channels: single, daily, slack, papertrail, stderr, syslog, errorlog, null, emergency. Deprecation logging is wired to a separate channel (default null) so PHP 8 deprecations don't drown out application logs.

config/mail.php

Default mailer = MAIL_MAILER, default log. Eight mailers configured: smtp, ses, postmark, resend, sendmail, log, array, failover, roundrobin. The failover mailer falls back from smtp to log; the roundrobin mailer alternates between ses and postmark.

config/queue.php

Default connection = QUEUE_CONNECTION, default database. Eight connections: sync, database, beanstalkd, sqs, redis, deferred, background, failover. Notable additions over time: the background driver was added in v12.10.0 (commit b36082a2), and failover (database → deferred) followed soon after. Failed jobs use the database-uuids driver writing to the failed_jobs table.

config/services.php

Just credential blocks for postmark, resend, ses, and slack. New third-party integrations should add a sibling block here, not a new config file.

config/session.php

Default driver = SESSION_DRIVER, default database. Lifetime: 120 minutes. serialization is set to 'json' (not 'php') — same gadget-chain hardening as cache.php's serializable_classes => false. Cookie name defaults to a slugified app name + -session. Same-site policy = lax. Partitioned cookies (CHIPS) are an opt-in via SESSION_PARTITIONED_COOKIE, default false.

Adding configuration

When you add a new feature that needs settings:

  1. Add a section. Either drop a sibling block into services.php (for third-party API credentials) or create config/yourfeature.php mirroring the structure of an existing file.
  2. Use env() only at top-level. Don't sprinkle env() through application code — read via config() instead so config caching doesn't break you.
  3. Document defaults in .env.example. Any new env var that is meant to be set per-environment should appear in .env.example with a sensible default.

Integration points

  • .env drives almost every value here.
  • bootstrap/app.php does not explicitly load this directory — the framework auto-loads every PHP file in config/ during Application::create().
  • bootstrap/cache/config.php is the cached form, written by php artisan config:cache.
  • config/auth.php references App\Models\User (use App\Models\User; at the top), creating a hard dependency between the two.

Entry points for modification

If you need to change behaviour, the rule of thumb is: edit the config file first, edit the .env.example, and only touch application code if a setting is missing entirely. Everything in here is intended to be tweakable without source changes.

Key source files

File Purpose
config/app.php App identity, debug, key, locale, maintenance
config/auth.php Guards, providers, password reset
config/cache.php Cache stores
config/database.php DB connections + Redis
config/filesystems.php Storage disks
config/logging.php Log channels
config/mail.php Mailers
config/queue.php Queue connections + failed-job storage
config/services.php Third-party API credentials
config/session.php Session driver and cookie behaviour

For the full env-to-config mapping see Reference → Configuration.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Config – Laravel wiki | Factory