Drupal 11.4 introduces a major improvement in entity loading performance. If you’re a developer or site builder, this change could significantly reduce the number of database queries on your site and speed up page loads.
What Are Single Cardinality Fields?
Single cardinality fields are fields that can only have one value per entity. Common examples include:
title(node title)uid(author)field_pricefield_statuscreated/changedtimestamps
Fields that can hold multiple values (tags, images, file references) are not affected.
How It Worked Before Drupal 11.4
Previously, Drupal would execute a separate SQL query for each single cardinality field.
Example:
Imagine a Product node with 6 single cardinality fields:
title, field_price, field_sku, field_qty, field_in_stock, field_brand
If you load 100 products, Drupal would run:
100 entities × (1 main query + 6 field queries) = 700 SQL queries
That’s a lot of queries for a single page.
How It Works in Drupal 11.4
Now, Drupal loads all single cardinality fields in one query per entity type.
Using the same example:
100 entities × (1 main query + 1 query for all fields) = 200 SQL queries
✅ Fewer queries = faster page loads, less database stress.
Example: Node Loading Before and After
Before (pre-11.4):
$nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple($nids);
- Drupal executes one query per field for each node.
- Slow if many nodes or fields.
After (Drupal 11.4):
$nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple($nids);
- Same code, but Drupal automatically fetches all single cardinality fields in one query.
- Much faster, especially for large Views or batch operations.
Things to Watch Out For
Because more data is loaded at once, some extreme situations can trigger MySQL errors:
- Loading thousands of entities at once
- Entities with very large text or blob fields
- MySQL
max_allowed_packetlimit exceeded (default 32MB)
Recommendations:
- Limit entity queries:
$nodes = \Drupal::entityTypeManager()
->getStorage('node')
->loadMultiple(range(1, 500));
- Load entities in batches:
$chunks = array_chunk($nids, 200);
foreach ($chunks as $chunk) {
$nodes = $storage->loadMultiple($chunk);
// process nodes
}
- Increase MySQL
max_allowed_packetif needed:
[mysqld]
max_allowed_packet = 128M
Who Benefits?
- Site builders: Views and entity-heavy pages are faster
- Developers: Less query optimization needed
- Administrators: Reduced database load
Summary
| Before 11.4 | After 11.4 |
|---|---|
| Separate query for each single cardinality field | Single query for all such fields |
| Many SQL queries per page | Significantly fewer queries |
| Safe with small datasets | May hit max_allowed_packet on huge loads |
| Manual optimization often needed | Automatic optimization in core |
This small change in core may dramatically improve performance for sites with lots of entities and fields. It’s an excellent example of Drupal continuing to optimize for modern, complex websites.
Comments