Where is the best place to store configuration settings? We have been discussing this internally recently. Two knee jerk reactions are “files on disk” and “in the database” (with the latter possibly immediately replaced by Redis or some other optimized shared storage or cache).
And to be clear, here I am talking about settings that developers should control (not Merchants). Things like memory limits, cache controls, enable/disable module switches – techie stuff.
Some background requirements
- We want to keep things simple for low end sites. We don’t want to add too much complexity – more moving parts implies more that can break and more machine resources needed to host the site.
- We want to support larger sites as well which can afford to do more.
- We want to support clusters of web servers where you have the issue of wanting to get configuration changes to multiple web servers, preferably in sync.
Some examples of configuration settings
- DB connection needs to be in a configuration file (or similar). There needs to be at least some configuration in files.
- If you want to say enable/disable a module, should this be in a configuration file or in a shared store (MySQL, Redis, etc)? (See towards the end of https://github.com/magento/magento2/issues/800 for example.)
- Should Magento have a standard support for “switches” for modules to leverage consistently? E.g. a standard way to turn off features, with Magento providing a standard API for fetching settings. I mention this one explicitly as some settings you don’t need fast reaction time on, but there may be others where maybe you want “the site is broken, turn that module off fast!”.
Discussion points that have come up
- DB connection details makes sense in files on disk. Changes slowly, you want to control it per environment (dev, test, prod), and you need them before you can fetch anything out of the database!
- Configuration files implies changing settings involves deploying new code to site, which for a simple site means taking your site down (for at least a short period of time). (A more advanced site may have a cluster of servers where you cycle them one by one to roll out the new code base.)
- Using a database (or other shared store) means all web servers can see the change at the same time without going down, but implies they have to fetch the configuration settings per HTTP request. (You could have a file system cache to fetch at most once a minute, or similar.)
- Storing configuration in a database makes sense. But if every module has its own configuration and fetches it, this can add up per HTTP request. (Framework support for such settings would allow it to fetch all settings in a single database access.)
- A database cache is of course possible, as long as you have a way to clear the cache.
- We want to support small sites by keeping the requirements down. Is a shared high performance configuration store process (e.g. Redis) too much for a minimal recommended site?
- Configuration settings in files on disk can be tracked by version control. If in database, you need to ship a script to update the database.
- Advanced sites do want to be able to have different configuration settings for different environments such as dev/test/staging/prod (e.g. via environment variables or different configuration files).
- If you update database settings, it is not guaranteed all web sites will be in sync for a short period of time (especially with caching). Taking a site down is an absolute guarantee.
There are lots of considerations around this. The ones the leap out to me personally include version control of your configuration, the max allowable time between wanting to make a change and it being live to site (e.g. to quickly turn a module off without taking site down), and the potential performance overhead per HTTP request. A simple approach is to use files on disk and require the software to be redeployed – minimal performance impact, but best scheduled to off peak.
The answer is almost certainly “it depends”. Some settings are fine in configuration files on disk, others are best in a shared database. The question in my mind is how to come up with guiding principles around how to choose which to use and when, and whether the Magento framework needs to provide any additional support here. Right now “files on disk are fine for settings that don’t change often or don’t need to be changed quickly” is one such principle. What ones do you have?