Managing environment-specific configurationsfor Drupal 11 , 10 , 9 , and 8

Last updated :  

Development needs verbose logging, disabled caches, and debug tools. Production needs the exact opposite — aggressive caching, minimal logging, no debug tools at all. Config Split solves the real tension here: your exported configuration is one shared baseline, with environment-specific overrides layered on top, rather than manually toggling settings by hand on each environment and hoping you remember which ones.

What you'll learn in this lesson

  • Why manually-toggled environment settings are a performance risk, not just an inconvenience
  • Setting up Config Split for a development/production split
  • What belongs in settings.php instead, and why

The risk of manual toggling

The performance failure mode this solves: a developer disables caching locally to see changes immediately, forgets to re-enable it before deploying, and production runs for days with render caching effectively off — a severe, entirely avoidable performance regression caused by a manual setting that should never have been able to leak into production in the first place.

Setting up Config Split

composer require drupal/config_split
drush en config_split -y
# config_split.config_split.development.yml
id: development
label: Development
folder: '../config/split/development'
module:
  devel: 0
  devel_webprofiler: 0
blacklist:
  - system.performance

A split defines modules and config that only apply in that specific environment — Devel and Webprofiler enabled only in the development split, for instance, with the base exported config staying at whatever's safe for production. Activate the split locally, deactivate it (or never activate it at all) on production, and the environment-specific settings genuinely can't leak across by accident.

What belongs in settings.php, not Config Split

Config Split handles configuration entities — module enablement, view settings, and similar. Genuinely environment-specific values that were never meant to be exported at all (database credentials, API keys, the $settings['hash_salt']) belong in settings.local.php instead, exactly the pattern you've used throughout this tutorial for things like cache backend configuration — never in exported config, never in version control alongside your codebase.

Quick check: where should a Redis connection password go — a Config Split override, or settings.local.php? If you said settings.local.php, you've correctly distinguished "configuration entities that can safely differ by environment" from "genuine secrets that should never be exported as config at all," the same distinction from the earlier API-key discussion in this tutorial's own build.

Key takeaways

  • Manually toggled dev-only settings are a real risk — they can leak into production if a deploy step forgets to reset them.
  • Config Split defines environment-specific config and module overrides as a structured, version-controlled layer over your base config.
  • Genuine secrets (database credentials, API keys) belong in settings.local.php, never in exported config or Config Split.
  • A cache-affecting setting (like system.performance) accidentally left in a dev split and deployed is exactly the failure mode this whole approach prevents.

Coming up next

You've now covered configuration management for performance. Next, we shift to session and user-account handling — a different but related source of per-visitor overhead.