Drupal Core Adds Native CLI Entry Point and Refines Data Loading

Drupal core activity this week focused on scaling the data layer for large field sets and improving the developer experience with a new CLI entry point. These changes address both low level database limits and high level operational workflows.

Native CLI Application in Drupal Core

One of the most significant changes this week is the introduction of a native CLI entry point directly in Drupal. The project has historically relied on external tools like Drush for command line operations. The new CLI entry point in Drupal Core lands a dedicated drupal script in the core/scripts directory.

This update introduces a formal framework for core commands. It includes initial support for several critical administrative tasks. The new application supports a cache-rebuild command, which allows operators to clear and rebuild system caches without a full web bootstrap. It also includes a status command for checking system requirements and a cron command for triggering scheduled tasks.

The implementation uses the Symfony Console component to provide a familiar interface for PHP developers. By moving these capabilities into core, the project reduces the bootstrap overhead for simple maintenance tasks. It also provides a stable target for hosting providers and automation scripts that need to interact with the system without installing additional dependencies.

Chunked Field Loading and Database Join Limits

Large Drupal installations often hit platform limits when dealing with complex entity types. A recent fix addresses a specific bottleneck where field loading can hit the MySQL 61 table join limit if there are approximately 60 fields. This issue occurs because the SQL storage engine tries to load all single cardinality fields in a single query with multiple left joins.

The solution implemented in core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php introduces a chunking strategy for field loading. The storage engine now uses a FIELD_MINIMUM_CHUNK_SIZE constant set to 25. When the number of fields exceeds this limit, the system splits the fields into smaller groups.

protected const int FIELD_MINIMUM_CHUNK_SIZE = 25;

if (count($single_cardinality_fields) > static::FIELD_MINIMUM_CHUNK_SIZE) {
  $chunks = array_chunk($single_cardinality_fields, static::FIELD_MINIMUM_CHUNK_SIZE, TRUE);
  // ... process chunks
}

This change ensures that Drupal can scale to hundreds of fields on a single entity type without triggering database errors. The logic also includes a smart merging strategy for the last chunk to avoid tiny queries with only one or two fields. This refinement is critical for enterprise sites that use many fields to model complex data structures.

Data Consistency and Revision Management

Maintaining data integrity during entity loading is vital for complex content workflows. A fix for loadUnchanged() ensures that the method returns an in memory modified entity correctly when a revision swap occurs. Previously, if a hook swapped in a non default revision during preloading, the system might return inconsistent state.

The update ensures that the entity storage properly tracks the revision state even when custom logic intervenes in the loading process. This prevents bugs where stale data might be used for validation or during an update cycle. For developers working with the entity API, this makes the behavior of loadUnchanged() more predictable across different revision scenarios.

Additionally, the project improved the security of the media preview endpoint. A fix was applied where the endpoint leaked labels of non viewable media by searching by UUID. The updated logic strictly enforces access checks before revealing any metadata about a media item, protecting private content from discovery through brute force or UUID harvesting.

Performance Tuning and Security Testing

Beyond the major features, several performance and testing improvements were merged. The project decided to drop the explicit clear of plugin caches in the main flush function. Since plugin caches are already handled by more specific clear operations, removing this redundant call reduces the total time spent on cache invalidation.

In the realm of security, new test suites were added to ensure long term protection against previously identified vulnerabilities. These include tests for SA-CORE-2025-003 and tests for SA-CORE-2025-001. Adding these regression tests to the core suite prevents future refactors from accidentally reintroducing these security flaws.

The project also introduced a OneTimeAuthentication service to replace the aging user_pass_rehash function. This modernizes the way Drupal handles password reset links and other single use login tokens. The new service provides a cleaner API and better integration with the dependency injection container, which is part of the ongoing effort to modernize the core codebase for PHP 8.3 and beyond.

How to prepare

Engineers should evaluate their use of custom CLI scripts as the core drupal command matures. While Drush remains the standard for many advanced tasks, core commands might provide a lighter alternative for CI pipelines.

Operators running sites with very large numbers of fields should monitor their database performance after updating. The new chunking logic might result in more queries during entity load but should eliminate the risk of hitting join limits.

Finally, keep an eye on PHP 8.5 compatibility. The project is already fixing scenarios where options widgets access null keys to ensure a smooth transition to the next PHP version.