Reducing active configuration objectsfor Drupal 11 , 10 , 9 , and 8

Last updated :  

Every piece of active configuration — every view, every image style, every field storage, every content type — lives in Drupal's config storage and gets loaded from there whenever something needs it. A site that's accumulated years of experimental views nobody uses, disabled-but-not-deleted image styles, and duplicate field configurations carries that weight on every config lookup, however small each individual lookup's cost.

What you'll learn in this lesson

  • Why "config bloat" is a real, if usually modest, performance concern
  • Finding genuinely unused configuration objects
  • Config caching, and where accumulated config actually costs the most

Where config load actually gets expensive

# Total config object count — a rough proxy for accumulated weight.
drush config:status --state=Unchanged | wc -l
drush php:eval "echo count(\Drupal::configFactory()->listAll());"
Config is cached — the real cost is elsewhere. Individual config reads are backed by Drupal's own config cache, so a single \Drupal::config('system.site')->get('name') call isn't itself slow. The actual cost of config bloat shows up in bulk operations that iterate over many config objects at once — a config export/import during deploy, an admin listing page that loads every view's configuration to display a summary, or listAll()-style discovery calls that genuinely have to enumerate everything.

Finding genuinely unused config

# List every view — cross-reference against ones actually referenced
# in your theme, menu links, or block placements.
drush php:eval "print_r(\Drupal::configFactory()->listAll('views.view.'));"

# Config Inspector (contrib) is the more thorough tool for finding
# orphaned config referencing deleted entities/fields.
composer require drupal/config_inspector

The same audit discipline from the Module Optimization section's "disabling unused modules" lesson applies here: don't assume something's unused just because it's unfamiliar — verify it's not referenced anywhere (a menu link, a block placement, another config entity's dependency) before removing it.

Cleaning up safely

# Delete via the entity API, not raw database manipulation —
# this correctly handles dependent config cleanup too.
drush php:eval "\Drupal\views\Entity\View::load('unused_view')->delete();"

Quick check: is a single \Drupal::config('system.site')->get('name') call meaningfully slower on a site with 5,000 config objects versus one with 50? If you said no — individual config reads are cached and don't scale with total config count, it's bulk operations like export/import that feel the difference — you've understood exactly where this lesson's concern actually applies.

Key takeaways

  • Individual config reads are cached — total config count doesn't slow down a single lookup.
  • Bulk operations (export/import, admin listing pages, discovery calls) are where accumulated config weight actually shows up.
  • Verify a config object is genuinely unreferenced (menu links, block placements, dependencies) before removing it — don't assume from unfamiliarity alone.
  • Delete via the entity API, not raw database manipulation, so dependent config cleanup happens correctly.

Coming up next

You've trimmed what config exists. Next, we look at managing configuration that deliberately differs between environments — without that difference itself becoming a performance or deployment problem.