Skip to main content

Inefficient Calls to Schema.getGlobalDescribe

David Martin avatar
Written by David Martin
Updated this week

Overview

In Salesforce Apex, Schema.getGlobalDescribe is a method that allows developers to dynamically fetch metadata information about all objects in the Salesforce schema. While this offers flexibility, it can be resource-intensive, especially in orgs with numerous custom objects and fields, consuming CPU time and memory, and contributing to governor limits like CPU time limits.

Clayton classifies this as an Error because repeated or unnecessary use of Schema.getGlobalDescribe() can lead to performance degradation and governor limit issues, particularly in complex or high-volume applications.

Why This Matters

Calling Schema.getGlobalDescribe() multiple times:

  • Consumes unnecessary system resources, even if the result doesn't change

  • Increases CPU time and heap size usage

  • Impacts performance in bulk operations or during record-triggered automation

  • Violates bulk best practices and may cause issues in batch processing or Flow integrations

This method should be called once, cached, and reused where needed.

What Triggers This Rule

Clayton flags code where Schema.getGlobalDescribe() is:

  • Called more than once in a method or class

  • Placed inside loops or recursive methods

  • Not stored in a local variable or reused after initial retrieval

Example of a Violation Trigger:

Imagine you have an Apex class designed to process a list of records from various standard or custom objects, and for each record, it needs to perform some logic that depends on the object's API name.

public with sharing class ObjectProcessor {    public void processRecords(List<SObject> records) {        for (SObject record : records) {            // ⚠️ Calling getGlobalDescribe() inside a loop            Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();             Schema.SObjectType sobjectType = gd.get(record.getSObjectType().getName());            if (sobjectType != null) {                // Perform some object-specific logic here                System.debug('Processing record from: ' + sobjectType.getDescribe().getName());            } else {                System.debug('Unknown SObject type encountered.');            }        }    }    public void anotherProcess() {        // ⚠️ Calling getGlobalDescribe() multiple times in a class without caching        Map<String, Schema.SObjectType> gd1 = Schema.getGlobalDescribe();        // ... some other logic ...        Map<String, Schema.SObjectType> gd2 = Schema.getGlobalDescribe(); // Second call    }}

Why this triggers the rule:

  • Called inside a loop: In the processRecords method, Schema.getGlobalDescribe() is called in every iteration of the for loop. This means if the records list contains, for example, 100 SObjects, getGlobalDescribe() will be executed 100 times.

  • Called multiple times in a class/method: In anotherProcess, getGlobalDescribe() is invoked twice. The result of Schema.getGlobalDescribe() is static for the transaction and doesn't change, so retrieving it multiple times is redundant and wastes resources.

  • Not cached/reused: The result of the call is not stored in a variable and reused for subsequent needs within the same method or transaction.

As the overview states, Schema.getGlobalDescribe() is a resource-intensive method. Repeated calls, especially within loops or frequently executed methods, will consume unnecessary system resources, increase CPU time, and impact performance, potentially leading to governor limit issues in high-volume or complex applications.
Recommended Approach

Store the result of Schema.getGlobalDescribe() in a variable and reuse it.

Summary

Repeated or inefficient use of Schema.getGlobalDescribe() can slow down your application and contribute to limit violations. Always cache the result and avoid using it in loops or high-frequency contexts. Clayton flags this as an Error to enforce efficient, scalable design practices in Apex.

Did this answer your question?