LIMIT_EXCEEDED oplossen in Salesforce-deployments

De Apex-tests van een deployment, of de dataload erachter, raakten een van Salesforce's governor- of orgbrede limieten.

Treedt op bij: uitvoering van Apex-tests of bulk-dataoperaties, niet bij de validatie van de metadata-deploy zelf

Wat het betekent

LIMIT_EXCEEDED omvat een familie van Salesforce-limieten, meestal Apex-governorlimieten zoals SOQL-query's, DML-instructies of CPU-tijd, die worden geraakt tijdens de testuitvoering die een deployment vereist. Het kan ook betekenen dat een orgbrede limiet, zoals dagelijkse API-aanroepen of massa-e-mailontvangers, is overschreden door automatisering die de deployment activeert.

Per-transactie governorlimieten (100 SOQL-query's, 150 DML-instructies, 10.000 CPU-milliseconden synchroon) worden bij elke transactie gereset, dus dit wijst bijna altijd op niet-gebulkte code binnen één transactie in plaats van een echt capaciteitsplafond op de org.

Diagnose

Veelvoorkomende oorzaken

Apex-testdata-setup doet te veel in één transactie
Een testmethode voegt grote hoeveelheden records toe of activeert cascaderende automatisering die het SOQL-, DML- of CPU-gebruik voorbij de per-transactielimiet duwt.
Bulk-dataload slaat bulkification over
Een datamigratie verwerkt records één voor één, of in kleine batches, en activeert een trigger die niet is geschreven om bulkvolumes efficiënt af te handelen.
Dagelijkse API- of e-maillimiet al verbruikt
Andere integraties of geplande taken in de org hebben al het grootste deel van een gedeelde dagelijkse limiet verbruikt voordat de eigen operaties van de deployment liepen.

De oplossing

  1. Bulkify het codepad dat de limiet raakt
    Herschrijf de trigger, klasse of test om te werken op collecties in plaats van individuele records, waardoor het aantal SOQL- en DML-aanroepen per transactie afneemt.
    // 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. Verminder de testdatavolume tot het minimum
    Beperk de Apex-testsetup tot de kleinste dataset die de te testen logica nog steeds uitoefent.
  3. Controleer orglimieten vóór grote deployments
    Bekijk API- en andere dagelijkse limieten in Setup voordat u een bulk-dataload of deployment uitvoert die toevoegt aan het gebruik dat die dag al is verbruikt.
In de praktijk

Hoe Serpent dit voorkomt

Serpent reserveert vooraf opgewarmde scratch-orgs voor testruns, zodat een bulktest of dataload een schone set limieten raakt in plaats van te concurreren met alles wat al draait in een gedeelde sandbox. Zie de bibliotheek met Salesforce-deploymentfouten.

Releasedashboard met conflictmeldingen in Serpent

Preventie

Schrijf elke trigger vanaf de eerste regel bulk-veilig, niet achteraf
Voer standaard query's en DML uit op collecties in nieuwe triggers, zodat bulkveiligheid het startontwerp is, niet een fix die wordt toegepast na de eerste LIMIT_EXCEEDED-fout.
Voer belastingstests uit met realistische batchgroottes vóór productie
Voer migratie- en bulklaadscripts uit tegen datavolumes op productieschaal in een scratch-org of sandbox voordat u de echte lading plant.
Bewaak orgbrede limieten, niet alleen per-transactielimieten
Volg het dagelijkse gebruik van API-aanroepen en massa-e-mail in de tijd, zodat de eigen operaties van een deployment niet degene zijn die een gedeelde limiet uiteindelijk laten overlopen.
Veelgestelde vragen

LIMIT_EXCEEDED, uitgelegd

Is LIMIT_EXCEEDED hetzelfde als een governor-limietuitzondering in Apex?
Ze zijn nauw verwant. Governorlimieten werpen een System.LimitException binnen Apex, wat als testfout naar voren komt; LIMIT_EXCEEDED is de bredere API-fout voor het overschrijden van orgbrede limieten zoals API-aanroepen of massa-e-mailontvangers.
Worden governorlimieten gereset tussen Test.startTest() en Test.stopTest()?
Ja. Test.startTest() geeft de code die volgt een verse set governorlimieten, los van wat de eigen setup van de test heeft verbruikt, en dat is waarom het verplaatsen van zware setup ervoor belangrijk is.
Zijn governorlimieten hetzelfde in alle Salesforce-edities?
De meeste per-transactie Apex-limieten zijn hetzelfde in alle edities, maar sommige orgbrede limieten, zoals API-aanroepen per dag, schalen mee met de editie en het aantal gebruikerslicenties, waardoor twee orgs bij zeer verschillende volumes REQUEST_LIMIT_EXCEEDED kunnen raken.

Start gratis. Geen creditcard, geen installatie, geen verplichting.

Binnen 15 minuten ingericht. Geen DevOps-aanwerving nodig.

Benieuwd naar sneller releasen voordat je instapt? Laten we praten

Vrijblijvend.