
Laravel Dynamic Configuration Without Redeploys: A Multi-Tenant Guide
Persist Laravel config overrides in the database, layer global and tenant scopes, and handle runtime loading, caching, and queues without redeploying.
Dynamic Config stores Laravel configuration values in your database, for the whole application or per company, branch or tenant. Load the scopes you need with Config::dynamic()->load(), and every config() call in your application sees the result.
One macro on the Config facade, and Laravel's own config() for everything else.
Config::dynamic() extends Laravel's Config facade, and you read final values with config().
Store values for the whole application, per identifier or per Eloquent model, such as a company, a branch or a tenant.
Each load() applies one scope, and the scope you load last wins.
mail.from.address overrides one value and keeps mail.from.name; associative arrays merge, lists are replaced.
One cache entry per scope, forgotten automatically by set() and forget().
Values keep their types as JSON, and unsupported values fail with errors that never include the value.
Persist values per scope, load them in order, and read the result with config().
1use Illuminate\Support\Facades\Config; 2 3// Persist: once, from a settings page or a seeder. 6 7// Apply: on every request, in the order you want them to win. 8Config::dynamic()->load(); 9Config::dynamic('branch-12')->load();10 11// Read: with Laravel itself.Quick answers about installing and using Dynamic Config.
Store Laravel configuration values in the database, globally or per company, branch or tenant, and merge them into config() with one explicit load call. It's a free, open-source Laravel package by Pharaonic.
Run composer require pharaonic/laravel-dynamic-config in your project's root directory, then php artisan migrate.
The latest release requires PHP 8.3+ and Laravel 13.
No. Each load() applies exactly one scope. Call Config::dynamic()->load() and then Config::dynamic('branch-12')->load() to layer the branch on top of the global values.
No. load() merges the values into Laravel's config repository once, and each scope is cached until it is written. config() then reads memory as usual.
Yes. Dynamic values are applied on top of the cached config at runtime and never written into the cache file. Octane gives each request its own config, and the documentation shows how to restore the config between queue jobs.
Yes. Dynamic Config is open source under the MIT license, so you can use it in personal and commercial projects.
Read the Dynamic Config documentation for setup, configuration, and usage examples.
Open an issue or a pull request on GitHub, or ask in the Pharaonic Discord.
Practical guides that use Laravel Dynamic Config, or solve the problem it was built for.

Persist Laravel config overrides in the database, layer global and tenant scopes, and handle runtime loading, caching, and queues without redeploying.
Read the full documentation for installation, configuration, scopes and layering, merge rules, stored values, caching, long-running processes and real-world examples.