API-sleutels verdelen bij hoge gelijktijdigheid
Wanneer een applicatie die gebruikmaakt van Large Language Models (LLM's) groeit in het aantal gelijktijdige gebruikers of opdrachten, stuit de infrastructuur al snel op de grenzen die API-aanbieders instellen. Deze limieten worden doorgaans uitgedrukt in verzoeken per minuut (Requests Per Minute, RPM), tokens per minuut (Tokens Per Minute, TPM) of het aantal gelijktijdig openstaande verbindingen (Concurrency). In veel enterprise-omgevingen wordt geprobeerd de capaciteit te vergroten door meerdere API-sleutels in te zetten binnen een centrale gateway.
Het verdelen van netwerkverzoeken over meerdere API-sleutels bij een hoge mate van gelijktijdigheid brengt echter specifieke technische uitdagingen met zich mee. In tegenstelling tot traditionele HTTP-webservers, waar verzoeken vaak een voorspelbare doorlooptijd en verwerkingslast hebben, varieert de belasting van LLM-aanroepen enorm. Een verzoek kan bestaan uit een korte classificatie van tien tokens of een complexe samenvatting van een document met duizenden tokens in de prompt en de uitvoer. Dit artikel behandelt de architectuuurpatronen, selectie-algoritmen, foutafhandeling en randvoorwaarden voor het effectief verdelen van API-sleutels onder hoge gelijktijdige belasting.
Het probleem van verzadiging op sleutelniveau
API-aanbieders koppelen hun doorvoercapaciteit en rate limits aan specifieke identificatiemethoden, zoals een API-sleutel, een project-ID of een organisatie-account. Wanneer een applicatie alle inkomende verzoeken via één enkele API-sleutel leidt, vormt die specifieke sleutel al snel een knelpunt (bottleneck). Dit gebeurt vaak lang voordat de onderliggende infrastructurele capaciteit van de API-aanbieder zelf is bereikt.
Bij een plotselinge piek in gelijktijdige verzoeken raakt de toegekende limiet van de sleutel binnen enkele seconden uitgeput. De API-aanbieder reageert in dat geval met een HTTP 429-statuscode (Too Many Requests). Als de infrastructuur vervolgens alle mislukte verzoeken direct opnieuw probeert uit te voeren via diezelfde sleutel, ontstaat er een zogeheten retry-storm. Hierdoor blijft de sleutel geblokkeerd gedurende het gehele herstelvenster van de provider. Het verdelen van de last over meerdere sleutels voorkomt dat één enkele sleutel de gehele doorvoer van de gateway blokkeert.
Waarom eenvoudige rotatie (Round-Robin) tekortschiet
De meest voor de hand liggende manier om verzoeken over een pool van API-sleutels te verdelen, is een statische Round-Robin-selectie. Hierbij krijgt elk inkomend verzoek achtereenvolgens de volgende sleutel uit de lijst toegewezen. In een omgeving met hoge gelijktijdigheid en variabele LLM-werkbelasting blijkt dit patroon echter onvoldoende effectief.
De oorzaak van deze ontoereikendheid ligt in de asymmetrische aard van LLM-verzoeken:
- Variabele verwerkingstijd: Een eenvoudig verzoek duurt wellicht 200 milliseconden, terwijl een gegenereerd antwoord met een lange context 15 seconden een verbinding bezet houdt.
- Scheve tokenconsumptie: Tien opeenvolgende verzoeken die via Round-Robin over tien sleutels worden verdeeld, kunnen willekeurig 50 tokens op de ene sleutel verbruiken en 80.000 tokens op een andere sleutel.
- Onzichtbaarheid van verzadiging: Round-Robin houdt geen rekening met de actuele status of resterende capaciteit van een sleutel. Een sleutel die zojuist een 429-fout heeft ontvangen, blijft simpelweg verzoeken toegewezen krijgen in de volgende cyclus.
Wanneer een Round-Robin-algoritme zware verzoeken toewijst aan een sleutel die toch al dicht tegen zijn TPM-limiet zit, leidt dit onherroepelijk tot fouten, terwijl andere sleutels in de pool onbenut blijven. Om een gelijkmatige belasting te realiseren, is een dynamisch algoritme noodzakelijk dat rekening houdt met de staat van de verzoeken en de response-headers van de aanbieder.
| Algoritme | Complexiteit | Rekening met Token-omvang | Geschiktheid bij Gelijktijdigheid |
|---|---|---|---|
| Round-Robin | Laag | Nee | Matig tot Slecht |
| Least In-Flight | Gemiddeld | Indirect (via verbindingstijd) | Goed |
| Header-Aware Dynamic | Hoog | Ja (via TP/RP headers) | Optimaal |
Geavanceerde verdeelstrategieën en hun complexiteit
Om een stabiele doorvoer te garanderen bij hoge gelijktijdigheid, worden in productieomgevingen complexere selectieregels toegepast. Deze methoden vereisen dat de gateway de status van elke sleutel actief bijhoudt.
Kiezen op basis van minste lopende aanroepen (Least In-Flight)
Bij het Least In-Flight-patroon houdt de gateway voor elke API-sleutel een teller bij van het aantal verzoeken dat op dat moment actief in behandeling is. Wanneer een nieuw verzoek binnenkomt, selecteert de gateway de sleutel met de laagste tellerwaarde op dat specifieke moment. Zodra het verzoek is afgerond (of is mislukt), wordt de teller van de betreffende sleutel weer verlaagd.
Dit patroon reageert automatisch op de latentie van verzoeken. Als een specifieke API-sleutel wordt gebruikt voor een trage, lange generatie, blijft de teller voor die sleutel hoger. Volgende verzoeken worden automatisch omgeleid naar sleutels die snelle responsen verwerken en daardoor sneller beschikbaar komen. Dit vermindert de opbouw van gelijktijdige wachtrijen per sleutel.
Kiezen op basis van dynamische capaciteit (Header-Aware)
Een nog nauwkeuriger methode koppelt het selectieproces aan het token-bucket-algoritme in de LLM-gateway. Hierbij schat of berekent de gateway de resterende capaciteit van elke sleutel op basis van historische gegevens en de headers van de provider. De gateway kiest telkens de sleutel die op dat specifieke moment de hoogste marge heeft tot aan de vastgestelde RPM- en TPM-limieten.
De complexiteit van deze benadering zit in het onderhouden van de geheugenstatus. Waar een Round-Robin-teller volstaat met een eenvoudige integer in het geheugen, vereist een dynamische capaciteitsverdeeller een datastructuur waarin wachttijden, actieve verbindingen en token-quota per sleutel synchroon worden bijgehouden.
Antwoordkoppen als bron van waarheid
Veel grote LLM-aanbieders sturen bij elk HTTP-antwoord specifieke koppen (response headers) mee die de actuele status van de rate limits weergeven. Voorbeelden van standaardkoppen zijn onder meer:
x-ratelimit-remaining-requests: Het aantal resterende toegestane verzoeken in het huidige tijdsvenster.x-ratelimit-remaining-tokens: Het aantal resterende toegestane tokens in het huidige tijdsvenster.x-ratelimit-reset-requests: De tijd (in seconden of milliseconden) totdat het verzoeken-quota wordt gereset.x-ratelimit-reset-tokens: De tijd totdat het token-quota wordt gereset.retry-after: De verplichte wachttijd indien een 429-fout is opgetreden.
Het is een cruciale ontwerpregel om deze antwoordkoppen te gebruiken als de absolute bron van waarheid voor het verdeelalgoritme, in plaats van uitsluitend te vertrouwen op de eigen tellingen van de applicatie. Lokale tellingen wijken in de praktijk af door verschillende factoren: de exacte wijze waarop de aanbieder tokens telt (bijvoorbeeld verschillende tokenizers), netwerk-timeouts, of verzoeken die door andere systemen met dezelfde sleutel worden uitgevoerd.
Bij het ontvangen van elke HTTP-respons leest de gateway de koppen uit en werkt hij de status van de gebruikte sleutel in het centrale geheugen bij. Als de kop x-ratelimit-remaining-tokens onder een kritische drempelwaarde zakt, kan de gateway die sleutel tijdelijk uitsluiten van de selectie totdat de reset-tijd is verstreken, nog voordat er daadwerkelijk een 429-fout optreedt.
Afhandeling van limietfouten en Quarantaine
Ondanks een nauwkeurige verdeling kunnen er door onverwachte pieken toch HTTP 429-fouten optreden. Hoe een gateway op zo'n fout reageert bepaalt de stabiliteit van de gehele keten.
Belangrijk: Gooi een API-sleutel die een 429-fout genereert nooit direct terug in de rotatiepool. Dit leidt tot een keten van opeenvolgende fouten op alle inkomende verzoeken.
Wanneer een sleutel een limietfout retourneert, dient de gateway het Quarantaine-patroon (of Circuit Breaker) toe te passen:
- Status wijzigen: De betreffende sleutel krijgt de status
Cooling DownofIn Quarantaine. - Wachttijd bepalen: De duur van de quarantaine wordt bij voorkeur uitgelezen uit de
retry-afterheader. Als deze ontbreekt, geldt een berekende aflopende wachttijd via een exponentieel backoff-schema. Zie voor de exacte uitwerking hiervan de richtlijnen over retries en backoff-strategieën. - Verzoek herhalen: Het mislukte verzoek wordt door de gateway onmiddellijk opnieuw aangeboden aan een *andere* sleutel die de status `Active` heeft en voldoende capaciteit bezit.
- Herstel: Pas wanneer de timer is verstreken, keert de sleutel terug naar de actieve pool, eventueel eerst in een `Half-Open` status waarin slechts één testverzoek wordt toegelaten.
Onderscheid tussen tijdelijke en permanente fouten
Niet elke foutcode vereist dezelfde reactie. Het verdeelmechanisme moet een strikt onderscheid maken tussen tijdelijke limietfouten en permanente sleutelfouten. Het verkeerd categoriseren van fouten kan leiden tot het onnodig uitschakelen van gezonde sleutels of het oneindig blijven proberen op een ongeldige sleutel.
Een HTTP 429-fout geeft aan dat de limiet van het tijdsvenster bereikt is; dit is een **tijdelijke fout**. De sleutel is over enkele seconden of minuten weer bruikbaar.
Foutcodes zoals HTTP 401 (Unauthorized) of HTTP 403 (Forbidden) wijzen op problemen met de sleutel zelf: de sleutel is ingetrokken, verlopen, of heeft geen rechten meer voor het opgevraagde model. Ook een melding van het type insufficient_quota (het pre-paid wauw- of credit-saldo van de organisatie is op) betekent dat de sleutel niet meer zal functioneren zonder menselijke tussenkomst.
Wanneer een **permanente fout** optreedt, geldt het volgende protocol:
- De sleutel wordt **onmiddellijk en permanent** uit de actieve rotatiepool verwijderd.
- De status van de sleutel wordt in de administratie gezet op
RevokedofDisabled. - Er wordt direct een geautomatiseerde alarmering (alert) verstuurd naar het beheerdersteam.
- Inkomende verzoeken worden zonder onderbreking omgeleid naar de overgebleven valide sleutels.
Gedistribueerde architectuur: Gedeelde toestand bij meerdere gateway-instanties
In moderne cloudinfrastructuur draait een API-gateway zelden op één enkele server. Om schaalbaarheid en hoge beschikbaarheid te bieden, worden meerdere instanties van de gateway naast elkaar uitgevoerd achter een netwerk load balancer.
Dit introduceert het probleem van **gescheiden toestand (split-brain status)**. Als elke gateway-instantie lokaal in zijn eigen geheugen de teller voor API-sleutels bijhoudt, hebben ze geen inzicht in de verzoeken die door andere instanties worden verwerkt. Vijf gateway-instanties die elk denken dat een sleutel nog 20% van zijn capaciteit over heeft, zullen gezamenlijk de limiet van de aanbieder ruimschoots overschrijden.
Om dit te voorkomen, moet de toestand van de sleutelpool worden gedeeld in een centrale, snelle datastore zoals Redis of KeyDB. Belangrijke elementen bij een gedistribueerde architectuur zijn:
- Atomaire operaties: Het verhogen van de teller voor actieve verzoeken en het controleren van de drempelwaarden moet atomair worden uitgevoerd (bijvoorbeeld met behulp van Redis Lua-scripts of
MULTI/EXECtransacties) om race conditions tussen gateway-nodes te voorkomen. - Centrale Quarantaine-status: Als instantie A een HTTP 429 ontvangt op sleutel X, moet instantie A een quarantaine-vlag zetten in het gedeelde geheugen. Instanties B, C en D lezen deze vlag en stoppen direct met het sturen van verkeer naar sleutel X.
- Lichte synchronisatie: Om netwerklatentie naar de datastore laag te houden, slaan gateway-instanties de responskoppen lokaal op voor snelle leesacties, maar valideren ze kritieke limietoverschrijdingen via de gedeelde staat.
Juridische kaders en gebruiksvoorwaarden van aanbieders
Bij het implementeren van sleutelverdeling is het essentieel om transparantie te bewaren ten opzichte van de servicevoorwaarden (Terms of Service, ToS) van de betreffende API-aanbieder.
Er bestaat een wezenlijk juridisch en operationeel verschil tussen twee situaties:
- Legitiem gebruik van meerdere sleutels: Een organisatie maakt meerdere API-sleutels aan binnen *één en hetzelfde* geverifieerde zakelijke organisatie-account. Dit wordt door aanbieders gefaciliteerd om verschillende projecten, teams of interne microservices te scheiden en om geaggregeerde quota binnen de organisatie te beheren.
- Omzeilen van limieten via meerdere accounts (Sybil-gedrag): Een ontwikkelaar maakt tientallen individuele gratis of proef-accounts aan bij een aanbieder met als doel de doorvoerbeperkingen van het platform te omzeilen zonder te betalen voor hogere tiers.
Het omzeilen van limieten via het aanmaken van gefingeerde accounts is een expliciete schending van de voorwaarden van vrijwel alle AI-aanbieders. Wanneer een aanbieder dit patroon detecteert (bijvoorbeeld op basis van IP-adressen, betalingsgegevens of verzoekpatronen), worden alle gerelateerde accounts en API-sleutels onmiddellijk geblokkeerd.
Voor organisaties die strikte doorvoergaranties nodig hebben, is de aangewezen weg het afsluiten van enterprise-overeenkomsten met gereserveerde capaciteit. Bekijk de juridische en operationele aspecten hiervan op onze pagina over AI-contracten en SLA-afspraken voor meer informatie over het vastleggen van verwerkingscapaciteit.
Beveiligingsrisico's en sleutelbeheer bij sleutelpools
Het beheren van een pool met meerdere API-sleutels verhoogt het beveiligingsrisico van de applicatie. Waar het uitlekken van één sleutel al schadelijk is, vergroot het opslaan en roteren van tien of twintig sleutels het mogelijke aanvalsoppervlak (blast radius) aanzienlijk.
Belangrijke beveiligingsmaatregelen bij het inzetten van sleutelpools zijn:
- Geen hardcoded sleutels: API-sleutels mogen nooit in de broncode of omgevingsvariabelen van de gateway-applicatie zelf worden opgeslagen.
- Centrale Secrets Manager: Gebruik een gespecialiseerde kluis (zoals HashiCorp Vault, AWS Secrets Manager of Azure Key Vault) om de pool van sleutels dynamisch in te laden bij het opstarten van de gateway-instantie.
- Minimale Rechten (Principle of Least Privilege): Zorg ervoor dat de sleutels in de pool alleen toegang hebben tot de specifieke modellen en endpoints die door de applicatie worden gebruikt.
Voor een gedetailleerde uitwerking van het beveiligen, opslaan en periodiek roteren van deze inloggegevens verwijzen wij naar ons artikel over API-sleutels veilig beheren.
Observability: Het valideren van de verdeelstrategie
Om te verifiëren of een ingestelde verdeelstrategie correct functioneert onder hoge gelijktijdigheid, is een goed ingerichte observability-stack noodzakelijk. Zonder concrete meetwaarden is het onmogelijk vast te stellen of de Last-Balancing efficiënt verloopt of dat bepaalde sleutels ongemerkt overbelast raken.
De belangrijkste metrieken die in een dashboard (zoals Prometheus/Grafana) moeten worden gemonitord zijn:
- Verzoekverdeling per sleutel: Een staafdiagram dat toont hoeveel procent van de inkomende aanroepen naar elke individuele API-sleutel wordt geleid. In een gezonde situatie bij identieke sleutel-quota moet deze verdeling evenredig zijn.
- Foutpercentage per sleutel (HTTP 429 vs 5xx): Het aantal foutmeldingen uitgedrukt als percentage van het totale verkeer per sleutel. Een stijging op één specifieke sleutel wijst op een verkeerd ingeschatte drempelwaarde.
- Wachttijd en Wachtrijlengte: De tijd die een inkomend verzoek in de gateway moet wachten voordat er een geschikte sleutel met beschikbare capaciteit is toegewezen. Een stijging van deze wachttijd is het eerste signaal van algehele verzadiging van de sleutelpool.
- Quarantaine-frequentie: Hoe vaak een sleutel naar de status
Cooling Downschakelt en hoe lang deze gemiddeld in Quarantaine blijft.
Door deze gegevens continu te analyseren en te vergelijken met de afspraken in de SLA en uptime-specificaties van LLM-providers, kan het infrastructuurteam de groottedimensie van de sleutelpool tijdig aanpassen aan het werkelijke gebruikspatroon.


