Naar de inhoud
maarten.
Alle stories

API-rate limits: foutmeldingen, retries en back-off

Maarten Soetens 12 min lezen

API-rate limits begrenzen hoeveel verzoeken een systeem binnen een bepaalde periode verwerkt. Je leest hoe limieten worden toegepast, wat foutmeldingen en responseheaders vertellen en hoe je retries, wachtrijen en back-off zo inricht dat tijdelijke drukte niet uitgroeit tot een storing.

Wat een API-rate limit precies begrenst

Een API-rate limit bepaalt hoeveel verzoeken een client binnen een bepaalde periode mag doen. Die grens beschermt capaciteit, verdeelt schaarse resources over gebruikers en beperkt misbruik. De limiet kan gelden per seconde, minuut, uur of dag, maar ook per endpoint of soort bewerking. Een leesverzoek kan bijvoorbeeld een andere grens hebben dan een export die veel databasewerk vraagt.

De periode alleen vertelt niet hoe de limiet wordt berekend. Een vaste teller kan aan het begin van elke minuut opnieuw beginnen. Daardoor zijn vlak voor en na de grens samen veel verzoeken mogelijk. Een rolling window beoordeelt juist een voortschrijdende periode, terwijl een token bucket korte pieken toestaat zolang er eerder capaciteit is opgebouwd. Die modellen hebben verschillende gevolgen voor clients: dezelfde gemiddelde snelheid kan bij het ene model worden geweigerd en bij het andere worden geaccepteerd.

Een limiet is bovendien niet altijd hetzelfde als een quota. Een rate limit begrenst de snelheid; een dagelijkse quota begrenst het totale gebruik over een langere periode. Ontwerp clients daarom niet op basis van één aanname zoals verzoeken per minuut. Leg vast welke endpoints worden aangeroepen, welke grenzen de API documenteert en of die grenzen per client, gebruiker of account gelden. Een verkeerde aanname leidt vaak tot pieken die voorspelbaar tegen de limiet lopen.

HTTP 429 en andere signalen van limietoverschrijding

De meest herkenbare HTTP-statuscode voor te veel verzoeken is 429 Too Many Requests. De server geeft daarmee aan dat de client een grens heeft overschreden. De response kan een Retry-After-header bevatten met een tijdstip of een aantal seconden voordat een nieuwe poging zinvol is. Gebruik die aanwijzing als die aanwezig is, maar controleer de documentatie: niet iedere API geeft de header terug en de interpretatie kan per implementatie verschillen.

Niet elke tijdelijke weigering verschijnt als 429. Een gateway kan bij overbelasting 503 Service Unavailable teruggeven, en sommige API’s gebruiken een eigen foutcode in de responsebody. Een 403 duidt doorgaans op een autorisatieprobleem, maar kan bij bepaalde diensten ook voor een geblokkeerde of uitgeputte quota worden gebruikt. Behandel daarom niet elke fout als een rate limit: combineer statuscode, foutcode, headers en API-documentatie voordat je een retrybeleid kiest.

Headers met resterende capaciteit of een resetmoment zijn nuttig voor planning, maar hun namen en beschikbaarheid zijn niet universeel. Een response kan bijvoorbeeld resterende verzoeken en een resetwaarde tonen; een andere API laat die informatie weg of rapporteert haar op accountniveau. Log de relevante responseheaders samen met statuscode en endpoint. Vermijd daarbij tokens en persoonsgegevens. Met die gegevens is te onderscheiden of een fout door een lokale piek, gedeelde accountlimiet of serverbelasting ontstond.

Verschillende limieten per gebruiker, sleutel en endpoint

Rate limits kunnen op meerdere niveaus tegelijk gelden. Een API-provider kan verzoeken tellen per API-sleutel, gebruiker, IP-adres, organisatie of endpoint. Daarnaast kan er een algemene grens zijn voor het hele account. Een client die alleen de limiet van één endpoint bewaakt, kan daardoor alsnog worden geweigerd wanneer andere processen dezelfde sleutel gebruiken. Dit komt vaak voor bij integraties waarin een achtergrondtaak en een interactieve applicatie dezelfde accountcapaciteit delen.

De scope bepaalt welke coördinatie nodig is. Als iedere applicatie-instance zelfstandig denkt dat er nog ruimte is, kunnen meerdere instances gezamenlijk de accountlimiet overschrijden. Lokale tellers zijn dan onvoldoende; de clients hebben een gedeelde limiter nodig, bijvoorbeeld op basis van een centrale datastore. Is de grens daarentegen per API-sleutel en heeft iedere worker een eigen sleutel, dan kan lokale regeling wel volstaan. De keuze beïnvloedt complexiteit, fouttolerantie en de kans dat capaciteit ongebruikt blijft.

Controleer ook of verschillende bewerkingen verschillende gewichten hebben. Een endpoint kan één verzoek tellen als meerdere capaciteitseenheden, bijvoorbeeld wanneer het een grote zoekopdracht uitvoert. Batchverzoeken zijn evenmin automatisch goedkoper: een enkele HTTP-aanroep kan intern veel records verwerken. Neem in de clientlogica de gedocumenteerde scope en eventuele gewichten op. Zonder dat onderscheid kan een dashboard een laag aantal HTTP-verzoeken tonen terwijl de toepassing toch regelmatig haar gebruikslimiet bereikt.

Retries met exponentiële back-off en jitter

Een retry is alleen zinvol wanneer een fout tijdelijk kan zijn. Bij een rate limit moet de client wachten voordat hij opnieuw probeert; onmiddellijk herhalen verhoogt de belasting en levert meestal dezelfde weigering op. Exponentiële back-off vergroot de wachttijd na opeenvolgende fouten, bijvoorbeeld van korte naar steeds langere intervallen. Stel daarbij een maximum in, zodat één verzoek niet onbeperkt buiten beeld blijft. Gebruik waar beschikbaar de Retry-After-header als ondergrens voor de volgende poging.

Voeg jitter toe: een willekeurige variatie op de berekende wachttijd. Zonder jitter kunnen duizenden clients die tegelijk een fout ontvangen ook tegelijk opnieuw proberen. Dat veroorzaakt een retry storm, waarbij herstelverkeer de API opnieuw overbelast. Jitter spreidt pogingen over een tijdvenster. Een gebruikelijke aanpak kiest een willekeurige wachttijd tussen nul en de berekende bovengrens, maar de gekozen variant moet passen bij de vereiste minimale wachttijd en het gedrag van de gebruikte API.

Retries horen een eindpunt te hebben. Beperk het aantal pogingen of stel een totale tijdslimiet in, en stuur een verzoek daarna naar foutafhandeling in plaats van het stilzwijgend te laten verdwijnen. Herhaal niet automatisch fouten als ongeldige invoer, ontbrekende rechten of een niet-bestaand endpoint; wachten verandert die situatie niet. Een brede retry op alle niet-succesvolle statuscodes vergroot belasting en maskeert programmeerfouten. Maak de voorwaarden expliciet en registreer waarom een poging opnieuw wordt gedaan.

Wachtrijen gebruiken om verzoekpieken af te vlakken

Een wachtrij ontkoppelt het moment waarop werk ontstaat van het moment waarop een API-verzoek wordt verstuurd. In plaats van een grote groep verzoeken direct uit te voeren, plaatsen producers taken in een queue en verwerken workers ze binnen een ingestelde snelheid. Zo wordt een piek afgevlakt en kan de toepassing de beschikbare capaciteit gecontroleerd benutten. Dit werkt goed voor achtergrondwerk, zoals synchronisatie, rapportage of bulkverwerking, waarbij een kleine vertraging acceptabel is.

Een queue lost een structureel capaciteitstekort niet op. Als er langdurig meer werk binnenkomt dan workers kunnen verwerken, groeit de wachtrij en loopt de verwerking steeds verder achter. Meet daarom queue depth, ouderdom van de oudste taak en verwerkingssnelheid. Stel grenzen in voor de wachtrij en bepaal wat er gebeurt wanneer die vol raakt: terugdruk naar de producer, taken tijdelijk weigeren of gecontroleerd laten vervallen. Zonder limiet kan een tijdelijke API-storing uiteindelijk het geheugen of de opslag van de applicatie uitputten.

Geef taken waar nodig prioriteit. Een gebruikersactie kan belangrijker zijn dan een periodieke opschoontaak, maar een permanente stroom hoge prioriteit kan lage prioriteiten uithongeren. Gebruik aparte queues of een eerlijk planningsbeleid en houd rekening met limieten die door meerdere queues worden gedeeld. Een gedeelde workerpool zonder centrale snelheidsregeling kan alsnog alle beschikbare verzoeken tegelijk uitsturen. De queue beheert volgorde en buffering; de rate limiter bepaalt de toegestane uitstroomsnelheid.

Verzoektempo regelen met token bucket en concurrency limits

Een limiter aan clientzijde voorkomt dat verzoeken pas worden afgeremd nadat de API ze afwijst. De token-bucketmethode houdt een voorraad tokens bij: iedere aanvraag verbruikt een token en de voorraad wordt met een ingestelde snelheid aangevuld. Een beperkte bucket laat korte pieken toe, terwijl de gemiddelde snelheid begrensd blijft. Een leaky bucket verwerkt verzoeken juist met een gelijkmatige uitstroom. Welke methode past, hangt af van de vraag of de API korte bursts accepteert of een stabiel tempo vereist.

Een snelheidslimiet en een concurrency limit regelen verschillende zaken. De eerste beperkt hoeveel verzoeken per tijdseenheid starten; de tweede begrenst hoeveel verzoeken tegelijk actief zijn. Bij trage API-responses kan een toegestane snelheid alsnog veel gelijktijdige verbindingen opleveren. Bij zeer snelle responses kan een lage concurrency juist onnodig weinig capaciteit benutten. Meet daarom responstijd en doorvoer, en stel beide grenzen af op het gedrag van de API en de client.

In een toepassing met meerdere processen moet duidelijk zijn waar de limiter draait. Een limiter per worker vermenigvuldigt de ingestelde snelheid met het aantal workers. Een centrale limiter voorkomt dat, maar wordt zelf een afhankelijkheid en moet beschikbaar en snel genoeg zijn. Bij uitval kun je kiezen voor fail-open, waarbij verzoeken doorgaan, of fail-closed, waarbij verzending stopt. Die keuze heeft directe gevolgen voor belasting en beschikbaarheid en hoort expliciet bij het ontwerp, niet als toevallig gevolg van een timeout.

Idempotentie en veilige verwerking van opnieuw verzonden verzoeken

Een client kan na een timeout niet altijd weten of de API het verzoek heeft verwerkt. De server kan de wijziging hebben opgeslagen terwijl de response onderweg verloren ging. Een retry kan dan dezelfde bewerking nogmaals uitvoeren. Dat is vooral riskant bij betalingen, het aanmaken van orders of het versturen van berichten. Het probleem staat los van rate limiting, maar wordt zichtbaarder zodra een client automatische retries gebruikt.

Een bewerking is idempotent wanneer herhaling met dezelfde invoer hetzelfde eindresultaat oplevert als één uitvoering. Een GET-verzoek hoort geen gegevens te wijzigen; een PUT kan doorgaans veilig dezelfde waarde opnieuw instellen. Bij niet-idempotente acties, zoals een POST die een nieuw object aanmaakt, kan een API een idempotency key ondersteunen. De client stuurt dan bij alle pogingen dezelfde unieke sleutel mee. De server gebruikt die sleutel om een herhaling te herkennen en eerder vastgelegde resultaten terug te geven.

Controleer hoe lang de API sleutels onthoudt en of dezelfde sleutel met afwijkende inhoud wordt geweigerd. Bewaar de sleutel bij de taak, zodat een worker die na een crash opnieuw start niet ongemerkt een nieuwe bewerking uitvoert. Als de API geen idempotentie ondersteunt, ontwerp dan een reconciliatiestap: controleer eerst of de gewenste wijziging al is doorgevoerd voordat je opnieuw schrijft. Blind retries toepassen op muterende requests kan duplicaten opleveren die achteraf lastig te onderscheiden zijn van geldige transacties.

Rate limits monitoren en retrygedrag testen

Een rate limit is pas goed te beheren wanneer zichtbaar is hoe vaak de toepassing ertegenaan loopt. Meet het aantal 429-responses, retries per verzoek, wachttijd door back-off en het aandeel verzoeken dat uiteindelijk faalt. Splits die gegevens waar mogelijk uit naar endpoint en integratie, maar neem geen API-sleutels of gevoelige queryparameters op in labels. Te veel unieke labels maken metrics onbruikbaar en kunnen monitoring onnodig zwaar maken.

Log retries als onderdeel van dezelfde trace of taak, met het pogingsnummer, de gekozen wachttijd en de oorzaak van de nieuwe poging. Zo is te zien of een verzoek één tijdelijke weigering kreeg of in een terugkerend patroon vastloopt. Een hoog retrypercentage kan wijzen op een verkeerde limiter, meerdere clients die dezelfde quota delen of een API die trager reageert dan de client verwacht. Alleen het eindresultaat loggen verbergt die onderliggende druk.

Test limietgedrag bewust. Een mockserver kan 429-responses, wisselende Retry-After-waarden, timeouts en 503-fouten teruggeven. Controleer dat de client wacht, jitter toepast, niet oneindig blijft proberen en de wachtrij niet ongecontroleerd laat groeien. Test ook gelijktijdige workers: een limiter die correct werkt in één proces kan bij horizontale schaal alsnog de gezamenlijke grens overschrijden. Neem in dashboards zowel API-fouten als queue-achterstand op, omdat een laag foutpercentage samengaat met een oplopende verwerkingsvertraging.

Veelgestelde vragen

Hoe kan ik het aantal API-verzoeken verlagen zonder functionaliteit te verliezen?

Je kunt het aantal API-verzoeken vaak verlagen door gegevens tijdelijk te cachen en onnodige herhaalde aanvragen te voorkomen. Controleer eerst welke gegevens veilig opnieuw kunnen worden gebruikt en hoe lang ze actueel moeten blijven.

  • Cache stabiele gegevens en stel een passende vervaltijd in.
  • Combineer waar mogelijk meerdere opvragingen of haal alleen gewijzigde gegevens op.
  • Voorkom dubbele aanvragen wanneer meerdere onderdelen tegelijk dezelfde informatie opvragen.
  • Gebruik conditionele verzoeken als de API bijvoorbeeld ETag of Last-Modified ondersteunt.

Controleer na wijzigingen of de gegevens nog voldoende actueel zijn. Een langere cacheduur verlaagt het verkeer, maar kan gebruikers ook verouderde informatie tonen.

Wat doe ik als een API-provider geen exacte rate limit publiceert?

Als de provider geen exacte rate limit publiceert, begin dan met een conservatieve verzoeksnelheid en verhoog die alleen stapsgewijs wanneer de API stabiel blijft.

  • Vraag de provider om limieten, scopes en eventuele gebruiksvoorwaarden te verduidelijken.
  • Gebruik een lage startsnelheid en bewaak 429-responses, time-outs en responstijden.
  • Verlaag de snelheid wanneer weigeringen toenemen en verhoog haar pas na een stabiele periode voorzichtig.
  • Test met een sandbox of mockserver in plaats van limieten op productie agressief uit te proberen.

Beschouw een periode zonder foutmeldingen niet als bewijs dat er geen grens bestaat. De limiet kan afhankelijk zijn van endpoint, accountbelasting of andere clients die dezelfde capaciteit gebruiken.

Hoe voorkom ik dat API-limieten van meerdere gebruikers mijn frontend verstoren?

Voorkom verstoringen door gedeelde API-limieten centraal aan de serverzijde te beheren in plaats van iedere browser rechtstreeks dezelfde API-sleutel te laten gebruiken.

  • Bewaar geheime API-sleutels op een backend en stuur ze niet mee naar de browser.
  • Laat de backend verzoeken verdelen en bepaal hoe capaciteit tussen gebruikers wordt toegewezen.
  • Beperk aanvragen per gebruiker waar dat nodig is, zodat één gebruiker niet alle gedeelde capaciteit verbruikt.
  • Geef de frontend duidelijke terugkoppeling wanneer een verzoek wordt uitgesteld of tijdelijk niet kan worden uitgevoerd.

Een backend voorkomt niet automatisch alle limietproblemen: ook daar kunnen meerdere servers of processen dezelfde quota delen. Zorg daarom dat de centrale regeling rekening houdt met alle clients die die quota gebruiken.

Wat moet een gebruiker zien als een API-verzoek door een rate limit wordt uitgesteld?

Laat de gebruiker weten dat de verwerking langer duurt en geef een realistische indicatie van de status, in plaats van een verzoek stilzwijgend te laten hangen.

  • Toon bij achtergrondwerk bijvoorbeeld dat de taak in de wachtrij staat.
  • Geef voortgang of een statuspagina als de verwerking meerdere stappen of veel tijd kost.
  • Bied een manier om later terug te komen of een melding te ontvangen wanneer het werk klaar is.
  • Voorkom dat een gebruiker door herhaald klikken onbedoeld extra taken aanmaakt.

Toon geen exacte wachttijd als die onzeker is. Maak ook duidelijk of de gebruiker de pagina veilig kan verlaten en wat er gebeurt als de taak uiteindelijk mislukt.

Wanneer moet ik een waarschuwing instellen voor API-rate limits?

Stel waarschuwingen in wanneer rate-limitproblemen een merkbare impact kunnen hebben op gebruikers of wanneer het gebruik structureel dicht bij de beschikbare capaciteit komt.

  • Waarschuw bij een aanhoudende stijging van 429-responses, niet alleen bij één losse fout.
  • Volg ook het retrypercentage, de totale wachttijd en het aantal verzoeken dat uiteindelijk mislukt.
  • Splits signalen waar mogelijk uit naar endpoint of integratie om de oorzaak sneller te vinden.
  • Maak onderscheid tussen een tijdelijke piek en een langdurig patroon dat aanpassing vereist.

Kies drempels op basis van normaal gebruik en de gevolgen van uitval. Test meldingen vooraf en voorkom dat iedere afzonderlijke 429 een alarm veroorzaakt; dat kan belangrijke waarschuwingen onzichtbaar maken.

Portret van Maarten

Maarten

Freelance developer in Nijmegen

Even kennismaken?

Vertel kort wat er speelt. Dan hoor je wat er kan, wat ik anders zou doen en waar AI bij jou wél en niet iets toevoegt. Vrijblijvend.

[email protected]
Het kantoor in Nijmegen
© 2026 maarten.online Sitemap Privacy Algemene voorwaarden
Het kantoor in Nijmegen

Maarten.

Freelance developer in Nijmegen. Liever direct contact? Dat kan ook.

Kennismaken

Laat je gegevens achter, dan kijken we of het klikt. Vrijblijvend en zonder verkooppraat.

Maarten

Stuur een bericht via WhatsApp

Hoi! Waar kan ik je mee helpen?

nu