LIMIT_EXCEEDED in Salesforce-Deployments beheben

Die Apex-Tests eines Deployments, oder der dahinterliegende Datenladevorgang, haben eines der Governor- oder orgweiten Limits von Salesforce erreicht.

Tritt auf bei: Ausführung von Apex-Tests oder Massen-Datenoperationen, nicht bei der Validierung des Metadaten-Deployments selbst

Was das bedeutet

LIMIT_EXCEEDED umfasst eine Familie von Salesforce-Limits, am häufigsten Apex-Governor-Limits wie SOQL-Abfragen, DML-Anweisungen oder CPU-Zeit, die während der von einem Deployment geforderten Testausführung erreicht werden. Es kann auch bedeuten, dass ein orgweites Limit, wie tägliche API-Aufrufe oder Massen-E-Mail-Empfänger, durch eine vom Deployment ausgelöste Automatisierung überschritten wurde.

Governor-Limits pro Transaktion (100 SOQL-Abfragen, 150 DML-Anweisungen, 10.000 CPU-Millisekunden synchron) werden bei jeder Transaktion zurückgesetzt, daher deutet dies fast immer auf nicht bulk-fähigen Code innerhalb einer Transaktion hin, statt auf eine echte Kapazitätsgrenze der Org.

Diagnose

Häufige Ursachen

Apex-Testdaten-Setup erledigt zu viel in einer Transaktion
Eine Testmethode fügt große Mengen an Datensätzen ein oder löst kaskadierende Automatisierung aus, die die SOQL-, DML- oder CPU-Nutzung über das Pro-Transaktions-Limit hinaustreibt.
Massen-Datenladevorgang überspringt die Bulkifizierung
Eine Datenmigration verarbeitet Datensätze einzeln oder in kleinen Batches und löst einen Trigger aus, der nicht darauf ausgelegt wurde, Massenvolumen effizient zu verarbeiten.
Tägliches API- oder E-Mail-Limit bereits verbraucht
Andere Integrationen oder geplante Jobs in der Org haben bereits den Großteil eines gemeinsamen Tageslimits verbraucht, bevor die eigenen Operationen des Deployments liefen.

Die Lösung

  1. Den Codepfad, der das Limit erreicht, bulkifizieren
    Schreiben Sie den Trigger, die Klasse oder den Test so um, dass er mit Sammlungen statt einzelnen Datensätzen arbeitet, wodurch SOQL- und DML-Aufrufe pro Transaktion reduziert werden.
    // Bad: SOQL inside a loop
    for (Account a : accounts) {
        List<Contact> cons = [SELECT Id FROM Contact WHERE AccountId = :a.Id];
    }
    
    // Good: one query outside the loop
    Map<Id, List<Contact>> conMap = new Map<Id, List<Contact>>();
    for (Contact c : [SELECT Id, AccountId FROM Contact WHERE AccountId IN :accountIds]) {
        if (!conMap.containsKey(c.AccountId)) conMap.put(c.AccountId, new List<Contact>());
        conMap.get(c.AccountId).add(c);
    }
  2. Testdatenvolumen auf das nötige Minimum reduzieren
    Reduzieren Sie das Apex-Testsetup auf den kleinsten Datensatz, der die zu testende Logik noch abdeckt.
  3. Org-Limits vor großen Deployments prüfen
    Überprüfen Sie API- und andere Tageslimits in Setup, bevor Sie einen Massen-Datenladevorgang oder ein Deployment ausführen, das zur bereits an diesem Tag verbrauchten Nutzung hinzukommt.
In der Praxis

Wie Serpent das verhindert

Serpent hält vorgewärmte Scratch-Orgs für Testläufe bereit, sodass ein Massentest oder Datenladevorgang auf einen sauberen Satz an Limits trifft, statt mit allem anderen zu konkurrieren, das bereits in einer gemeinsam genutzten Sandbox läuft. Siehe die Bibliothek der Salesforce-Deploymentfehler.

Release-Dashboard mit Konfliktwarnungen in Serpent

Prävention

Jeden Trigger von der ersten Zeile an bulk-sicher schreiben, nicht nachrüsten
Führen Sie Abfragen und DML in neuen Triggern standardmäßig auf Sammlungen aus, sodass Bulk-Sicherheit das ursprüngliche Design ist, nicht eine Korrektur nach dem ersten LIMIT_EXCEEDED-Fehler.
Vor der Produktion mit realistischen Batch-Größen lasttesten
Führen Sie Migrations- und Massenladeskripte gegen Datenvolumen im Produktionsmaßstab in einer Scratch-Org oder Sandbox aus, bevor Sie die echte Ladung planen.
Orgweite Limits überwachen, nicht nur die pro Transaktion
Verfolgen Sie die tägliche Nutzung von API-Aufrufen und Massen-E-Mails über die Zeit, damit nicht die eigenen Operationen eines Deployments ein gemeinsames Limit letztlich überschreiten.
Häufige Fragen

LIMIT_EXCEEDED, erklärt

Ist LIMIT_EXCEEDED dasselbe wie eine Governor-Limit-Exception in Apex?
Sie sind eng miteinander verwandt. Governor-Limits lösen innerhalb von Apex eine System.LimitException aus, die als Testfehler erscheint; LIMIT_EXCEEDED ist der breitere API-Fehler für das Überschreiten orgweiter Limits wie API-Aufrufe oder Massen-E-Mail-Empfänger.
Werden Governor-Limits zwischen Test.startTest() und Test.stopTest() zurückgesetzt?
Ja. Test.startTest() gibt dem nachfolgenden Code einen frischen Satz an Governor-Limits, getrennt von dem, was das eigene Setup des Tests verbraucht hat, weshalb es wichtig ist, aufwendiges Setup davor zu verschieben.
Sind Governor-Limits in allen Salesforce-Editionen gleich?
Die meisten Apex-Limits pro Transaktion sind über alle Editionen hinweg gleich, aber manche orgweiten Limits wie tägliche API-Aufrufe skalieren mit Edition und Anzahl der Benutzerlizenzen, sodass zwei Orgs bei sehr unterschiedlichen Mengen REQUEST_LIMIT_EXCEEDED erreichen können.

Kostenlos starten. Keine Kreditkarte, keine Installation, keine Verpflichtung.

In unter 15 Minuten eingerichtet. Keine DevOps-Einstellung nötig.

Neugierig auf schnelleres Shipping, bevor Sie einsteigen? Sprechen wir

Unverbindlich.