Loading Only Required Fields from Entitiesfor Drupal 11 , 10 , 9 , and 8

Last updated :  

Loading a full node entity when you only need its title is like ordering the entire menu to eat one appetizer — Drupal's Entity API defaults to fully hydrating every field, every translation, every revision reference, even when your code only ever reads $node->getTitle(). On a page rendering hundreds of entities (a large View, a batch operation), that overhead adds up fast.

What you'll learn in this lesson

  • Why loadMultiple() is dramatically cheaper than a loop of individual load() calls
  • How to fetch only specific field values without loading full entities
  • What the static entity cache does for you automatically, and its limits

loadMultiple() instead of a load loop

// Slow: N separate queries.
foreach ($nids as $nid) {
  $node = \Drupal::entityTypeManager()->getStorage('node')->load($nid);
}

// Fast: one query for all of them.
$nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple($nids);

Every individual load() call triggers its own database round trip (unless the entity is already statically cached). loadMultiple() batches every ID into a single query, exactly the same "one connection, one query" principle you saw in the Database API topic's dynamic-query lessons.

Fetching only a field value, not the whole entity

$titles = \Drupal::entityTypeManager()
  ->getStorage('node')
  ->getQuery()
  ->condition('type', 'article')
  ->accessCheck(TRUE)
  ->execute();

// Still needs loadMultiple() to actually read field values — entityQuery()
// only ever returns IDs. For genuinely field-only reads at scale, query the
// field table directly with Connection::select(), the same DBTNG pattern
// from the Database API topic.
Common misconception: getQuery() never loads entities — it only returns matching IDs, always. Reaching for a raw Connection::select() against the field's own database table (e.g. node__field_example) is the real way to read one field's value across many entities without hydrating full objects, at the cost of losing the Entity API's access checks and field-type abstraction.

Quick check: you need just the titles of 500 published articles for a dropdown. Is loadMultiple() on all 500 nodes the fastest option? If you said no — a direct Connection::select() against node_field_data for just the title column would be faster, since it skips hydrating every other field — you've got the core trade-off this lesson is about.

Key takeaways

  • Always batch entity loads with loadMultiple() instead of looping individual load() calls.
  • getQuery()/entity queries return IDs only — never field values directly.
  • For read-only access to a handful of field values across many entities, a raw DBTNG query against the field table beats full entity hydration.
  • Drupal's static entity cache means a second load() of the same ID in one request is free — the expensive part is the first load and cross-request repetition.

Coming up next

Loading entities efficiently is half the story — the other half is making sure the rendered result gets cached correctly so you don't pay that cost again on the next request. Next, entity-based cache tags.