Problem / Motivation

Running drush updatedb takes over 2 minutes on sites that use the jsonapi_views module, even when there are no pending database updates. The delay occurs entirely inside drupal_flush_all_caches(), specifically inside \Drupal\Core\Routing\RouteBuilder::rebuild(), triggered by jsonapi_views calling ResourceTypeRepository::get() for every view and bundle combination.

Root cause chain

  1. drush updb always calls drupal_flush_all_caches() unconditionally — even when no schema updates ran. This is by design for compatibility with updates that rely on cache clearing. It runs inside the UpdateKernel.
  2. UpdateKernel replaces the entire cache factory with UpdateBackend (UpdateCacheBackendFactory, introduced in #3055443: Switch to a null backend for all caches for running the database updates). UpdateBackend extends NullBackend: all cache reads return nothing, all writes are discarded.
  3. cache.jsonapi_resource_types is a BackendChain (introduced in #3018287: ResourceTypeRepository computes ResourceType value objects on *every request*) combining an in-memory backend and the default DB backend. This is the service injected into ResourceTypeRepository.
  4. UpdateBackend wraps — and effectively replaces — the entire BackendChain. The memory layer inside the chain is never reached because UpdateCacheBackendFactory decorates cache_factory before the chain is consulted.
  5. ResourceTypeRepository::all() has no instance-level fallback cache. Every call checks $this->cache->get('jsonapi.resource_types'), gets nothing back from NullBackend, then performs a full rebuild: iterates all entity types × all bundles, calls createResourceType() and calculateRelatableResourceTypes() for each, and dispatches events. This is expensive (1–8 seconds per call depending on site size).
  6. jsonapi_views generates routes by calling ResourceTypeRepository::get() once per view+bundle. On a moderately sized site this triggers dozens of full all() rebuilds, totalling ~120 seconds during a single drush updb.

Measurements (Drupal 10.6.8, 187 modules, 23 views, 9 entity types)

State drush updb time
Before any fix ~2 minutes
After jsonapi_views [#3484714] patch only ~80 seconds
After adding $allResourceTypes instance cache to all() ~4 seconds

Profiling was done by adding error_log() timing instrumentation to drupal_flush_all_caches() and RouteBuilder::rebuild() step by step. The full breakdown:

[FLUSH] cache_flush+deleteAll:               0.19s
[FLUSH] rebuildContainer:                    0.09s
[FLUSH] plugin cache_clearer:                0.03s
[ROUTER] getRouteDefinitions (YAML scan):    0.03s
[ROUTER] route object creation loop:       120.38s  ← all time here
[ROUTER]   jsonapi_views provider:          116.16s  ← single contributor
[ROUTER] dumper->dump:                       0.27s

The 116 seconds in jsonapi_views came from repeated calls to ResourceTypeRepository::all() with a NullBackend active.

Steps to reproduce

  1. Install Drupal with jsonapi and jsonapi_views enabled.
  2. Create 10 or more Views over entity types that have multiple bundles (e.g. node).
  3. Run time drush updb.
  4. Observe the delay after [success] No pending updates.

Proposed resolution

Add an instance-level property to ResourceTypeRepository that caches the result of all() within the same service instance. This is not affected by which cache backend is active.

Why this should be safe

Remaining concern

Even with this core fix applied, jsonapi_views still calls ResourceTypeRepository::get() once per view+bundle on the first all() within a new container instance. The companion issue [#3484714] (already RTBC) addresses that separately by caching results per entity type in jsonapi_views/src/Routing/Routes.php. Both fixes together are what produce the ~4 second result above.

Issue fork drupal-3591918

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

manuel garcia created an issue. See original summary.

manuel garcia’s picture

Title: updb` is very slow on sites with jsonapi_views because UpdateBackend bypasses the BackendChain memory layer in ResourceTypeRepository » updb is very slow on sites with jsonapi_views because UpdateBackend bypasses the BackendChain memory layer in ResourceTypeRepository

manuel garcia changed the visibility of the branch 3591918-updb-is-very to hidden.

manuel garcia’s picture

Status: Active » Needs review
smustgrave’s picture

Version: 11.4.x-dev » main
Status: Needs review » Needs work
Issue tags: +Needs tests

Thank you for reporting

Fixes would need to land in the main branch first but as a bug will need test coverage

manuel garcia’s picture

Thank you @smustgrave for having a look so quickly.
I have now closed the 11.4.x MR and opened a new one for main. Tests still pending.

manuel garcia’s picture

Status: Needs work » Needs review

OK I added a test to ResourceTypeRepositoryTest and cleaned things up a little bit. I had to have ResourceTypeRepository impelement CacheTagsInvalidatorInterface in order to reset the $this->all property when the relevant tags are invalidated.