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, partitionedLOC 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:
- Add a section. Either drop a sibling block into
services.php(for third-party API credentials) or createconfig/yourfeature.phpmirroring the structure of an existing file. - Use
env()only at top-level. Don't sprinkleenv()through application code — read viaconfig()instead so config caching doesn't break you. - Document defaults in
.env.example. Any new env var that is meant to be set per-environment should appear in.env.examplewith a sensible default.
Integration points
.envdrives almost every value here.bootstrap/app.phpdoes not explicitly load this directory — the framework auto-loads every PHP file inconfig/duringApplication::create().bootstrap/cache/config.phpis the cached form, written byphp artisan config:cache.config/auth.phpreferencesApp\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.