Batchgroottes en performance: waarom 10.000 records in één keer misgaat
Door Clen Mourik
Je hebt 10.000 orderregels, artikelmutaties of facturen. Lijkt logisch om ze in één keer te versturen, toch? In de praktijk loopt dit structureel mis. Hier lees je waarom API's haperen bij grote batches en hoe je het wél goed doet.
Je hebt een volledige dag orders verwerkt. 480 stuks. Aan het eind van de dag druk je op 'synchroniseer naar boekhouding' en… niets. De koppeling draait, draait, en na een kwartier: timeout. Nul orders zijn doorgekomen. Morgenochtend belt je accountant dat er gaten in de administratie zitten.
Of dit: een groothandel wil 18.000 artikelen syncen tussen webshop en ERP. In één keer, 's nachts. Lijkt efficiënt. Maar elke ochtend staat de voorraad niet geüpdatet. Klanten bestellen producten die allang uitverkocht zijn. De frustratie stapelt zich op.
Dit zijn geen uitzonderingen. Het is een patroon dat ik bij tientallen MKB-bedrijven zie: te grote batches breken koppelingen. Niet omdat de systemen slecht zijn, maar omdat niemand vertelde dat API's grenzen hebben. En die grenzen zijn harder dan je denkt.
Inhoudsopgave
- Belangrijkste punten
- Waarom grote batches structureel falen
- Concrete limieten van populaire systemen
- Wat er misgaat in de praktijk
- Veelgemaakte fouten bij batchverwerking
- Hoe los je het op: slimme batchstrategieën
- Alternatieve aanpakken vergeleken
- Technische achtergrond: wat gebeurt er onder de motorkap
- Veelgestelde vragen
Belangrijkste punten
| Punt | Details |
|---|---|
| API's hebben harde grenzen | AFAS time-out na 15 minuten, Exact Online max 60 records per pagina, Salesforce adviseert ~10.000 per batch |
| Grote batches = geen foutherstel | Bij een crash halverwege weet je niet welke records wel/niet verwerkt zijn, leidt tot datainconsistentie |
| Paginering is geen optie | Vergeten te pagineren werkt in test (50 records) maar faalt in productie (15.000 records) — klassieke stille fout |
| Rate limits worden overschreden | Te veel requests per minuut = HTTP 429 errors, geblokkeerde API-toegang, stilgevallen koppelingen |
| Optimale batchgrootte: 500-1.000 | Afhankelijk van systeem en complexiteit, met retry-logica en exponential backoff voor betrouwbaarheid |

Waarom grote batches structureel falen
De gedachte is begrijpelijk: je hebt 10.000 records, dus stuur je 10.000 records. Efficiënt toch? Maar API's werken niet zo. Ze zijn gebouwd voor snelheid en stabiliteit, niet voor enorme bulkoperaties zonder controle.
Het eerste probleem: timeouts. Een API-verbinding mag niet eindeloos open blijven. Bij AFAS bijvoorbeeld komt er een harde timeout als de verbinding langer dan ongeveer 15 minuten actief is. Stuur je 18.000 artikelmutaties in één keer, dan red je dat niet. De verbinding valt weg. Geen foutmelding, geen herstel, gewoon stilte.
Het tweede probleem: geheugen en processing. Een ERP-systeem moet elke record valideren, verwerken, wegschrijven. Bij duizenden tegelijk raakt het geheugen vol, ontstaan database-locks, en crasht de verwerking. Je server draait vast.
Het derde probleem: rate limits. Systemen als Exact Online hebben ingebouwde API-limieten om misbruik te voorkomen. Te veel requests achter elkaar en je krijgt HTTP 429-foutmeldingen: Too Many Requests. Je app wordt geblokkeerd. In sommige gevallen voor uren.
Wat ik vaak zie: een ondernemer bouwt een koppeling, test met 50 records, werkt perfect. Zet het live, 5.000 records, en alles valt om. Het verschil tussen test en productie is moordend.
Bij een productiebedrijf dat we hielpen, werden 80.000 historische artikelmutaties in één keer geïmporteerd tijdens een ERP-migratie. Na 12.000 records viel de import stil. Geen logging, geen foutmelding. Ze wisten niet hoeveel records wél waren verwerkt. Het resultaat: handmatig opschonen, dubbele records verwijderen, en drie dagen vertraging.
Concrete limieten van populaire systemen
Elk systeem heeft zijn eigen grenzen. Hier zijn de harde cijfers waar je tegenaan loopt:
| Systeem | Limiet per batch | Belangrijkste restrictie |
|---|---|---|
| Exact Online | 60 records per pagina (REST API) | Bulk-endpoints ondersteunen max 1.000 records per call (bron) |
| AFAS Profit | Max 75 MB per call | Timeout na ~15 minuten actieve verbinding (bron) |
| Salesforce | ~10.000 records aanbevolen | Grotere batches leiden tot performance-knelpunten (bron) |
| SAP SuccessFactors | Max 1.000 per pagina | Bij complexe transacties kleiner om timeouts te vermijden (bron) |
Voor AFAS geldt: bij data-extractie wordt een limiet van 10.000-50.000 records aanbevolen, afhankelijk van je dagelijkse volume. Verwacht je een paar duizend records per dag? Stel de limiet in op 10.000-20.000. Haal je dagelijks 50.000 records op? Dan kun je beter de upsert-schrijfmodus gebruiken om duplicaten te voorkomen.
Let op: deze limieten zijn geen verzoek. Het zijn harde grenzen. Overschrijd je ze, dan faalt je koppeling. Simpel.

Wat er misgaat in de praktijk
Laat me drie concrete voorbeelden geven waar het precies fout ging.
Voorbeeld 1: Groothandel met webshop en ERP-koppeling
Een technische groothandel had een WooCommerce-webshop gekoppeld aan AFAS Profit. Elke nacht draaide een volledige voorraadsync: alle 18.000 artikelen in één API-call naar AFAS. Omdat de verbinding langer dan 15 minuten actief was, viel de call steeds uit. 's Ochtends stonden voorraden niet gesynchroniseerd. Klanten bestelden producten die al uitverkocht waren.
De oplossing: de sync werd opgesplitst in batches van 500 artikelen per call, met een korte pauze tussen elke call. Door te filteren en skip/take met ORDER BY toe te passen, bleef de koppeling stabiel. Timeouts verdwenen.
Voorbeeld 2: Productiebedrijf met ERP-migratie
Een maakindustriebedrijf met 50 medewerkers stapte over van een oud systeem naar een nieuw ERP. Tijdens de migratie werden 80.000 historische artikelmutaties in één keer geïmporteerd. De import viel vast na 12.000 records. Er was geen foutlogging, dus ze wisten niet hoeveel records wél waren verwerkt. Het gevolg: handmatig opschonen en drie dagen vertraging.
De oplossing: de migratie werd opgesplitst in batches van 1.000 records, met tussentijdse logging van successen en fouten. Historische data werd in batches geladen met upsert-modus om duplicaten automatisch af te vangen.
Voorbeeld 3: Webshop met Exact Online-koppeling
Een mode-webshop verwerkte dagelijks 300-500 orders. Aan het eind van de dag werden alle orders in één batch naar Exact Online gepusht voor facturering. Soms 480+ records tegelijk. De API-limieten werden overschreden. Exact retourneerde HTTP 429-foutmeldingen. Omdat er geen retry-logica was, vielen tientallen orders weg uit de boekhouding. Pas dagen later ontdekt.
De oplossing: orders werden direct na plaatsing in kleine batches van 25-50 records doorgestuurd, met exponential backoff bij een 429-response. Een productie-waardige integratie probeert mislukte verzoeken opnieuw, met oplopende tussenpauzes.
Veelgemaakte fouten bij batchverwerking
Hier zijn de klassieke blunders die ik blijf zien:
Fout 1: Alles in één keer sturen
De big bang-aanpak. Je hebt 10.000 records, dus je stuurt 10.000 records. Lijkt logisch, gaat mis. API's hebben harde grenzen. Bij AFAS komt er een timeout na 15 minuten. Bij Exact Online is de limiet 60 records per pagina. Het resultaat: gedeeltelijk verwerkte data, zonder duidelijke foutmelding.
Fout 2: Vergeten te pagineren
In test staan 50 records. De API levert alles in één keer. Werkt perfect. In productie staan 15.000 records. Zonder paginering haal je alleen de eerste pagina op. Vergeten te pagineren is een klassieke reden waarom een integratie in test prima werkt maar bij echte volumes data mist. Stille datalekken: systemen lopen uit de pas terwijl niemand het merkt.
Fout 3: Geen retry-logica
Netwerken haperen. Servers gaan kort offline. Zonder retry-logica verdwijnen records geruisloos. Een productie-waardige integratie probeert mislukte verzoeken opnieuw, met oplopende tussenpauzes (exponential backoff), en bewaart wat er mislukte zodat het later alsnog verwerkt kan worden. Dit wordt stelselmatig vergeten omdat het 'later' wordt toegevoegd, en dat moment komt er nooit.
Fout 4: Dubbele verwerking door ontbrekende idempotentie
Een goed ontworpen API laat je hetzelfde verzoek meerdere keren versturen zonder dat het dubbel verwerkt wordt, door een unieke sleutel mee te geven per bestelling. Bij betalingen en orders is dat onmisbaar. Zonder idempotentie betaalt een klant in het slechtste geval twee keer of komt dezelfde factuur dubbel in de boekhouding.
Fout 5: Rate limits negeren
Koppelingen moeten worden ontworpen met monitoring, throttling, retrybeleid en API-beheer, zodat finance-, order- en backofficeprocessen ook bij piekbelasting blijven werken. In de praktijk bouwen MKB-ondernemers koppelingen zonder enige monitoring. Pas als de softwareleverancier meldt dat de app geblokkeerd is, wordt het probleem zichtbaar.
Bij een klant zagen we dat orders wekenlang stilletjes verdwenen omdat de retry-logica ontbrak. Niemand zag het tot de maandafsluiting. Toen was de chaos compleet.
Hoe los je het op: slimme batchstrategieën
De oplossing is niet ingewikkeld, maar vereist wel discipline. Hier zijn de stappen:
Stap 1: Split je data in behapbare chunks
Kies een batchgrootte tussen 500 en 1.000 records, afhankelijk van het systeem en de complexiteit van je data. Voor AFAS: 500-1.000 werkt goed. Voor Exact Online: 50-100 bij complexe transacties. Voor Salesforce: ~10.000 bij simpele inserts.
Een vuistregel: hoe complexer de validatie in het ontvangende systeem, hoe kleiner je batch.
Stap 2: Bouw paginering in vanaf dag één
Bij grote datasets levert een API niet alles in één keer. Je vraagt steeds een 'pagina' op (bijvoorbeeld 100 records per keer) totdat je het einde bereikt. Gebruik skip/take of cursor-based paginering. Test dit niet alleen met 50 records, maar met 5.000+.
Stap 3: Voeg retry-logica toe met exponential backoff
Als een call faalt, probeer opnieuw na 1 seconde. Faalt het weer? Probeer na 2 seconden. Dan 4, 8, 16. Dit voorkomt dat je het systeem overspoelt bij een tijdelijke storing. Bewaar mislukte records in een wachtrij zodat je ze later opnieuw kunt verwerken.
Stap 4: Log alles
Hou bij welke batches succesvol waren, welke faalden, en waarom. Zonder logging weet je bij een crash halverwege niet waar je gebleven bent. Dit hoeft geen fancy monitoring te zijn, een simpel logbestand met timestamps en record-ID's is al genoeg.
Stap 5: Monitor je API-gebruik
Houd in de gaten hoeveel calls je per minuut maakt. Blijf ruim onder de rate limits. Voor Exact Online: max 300 calls per 5 minuten. Voor AFAS: hou je totale call-omvang onder 75 MB. Bouw throttling in: pauzeer automatisch als je de limiet nadert.

Alternatieve aanpakken vergeleken
Er zijn meerdere manieren om grote hoeveelheden data te verwerken. Hier een eerlijke vergelijking:
| Aanpak | Voordelen | Nadelen | Geschikt voor |
|---|---|---|---|
| Grote batch in één keer | Eenvoudig te bouwen | Timeout-gevoelig, geen foutherstel, datainconsistentie | Niets (anti-patroon) |
| Kleine batches met retry | Betrouwbaar, schaalbaar, recoverbaar | Meer ontwikkeltijd, complexere logica | Vrijwel alle scenario's |
| Event-driven / realtime | Direct actuele data, geen nachtelijke batches | Hogere API-belasting bij piekvolumes | Orders, betalingen, voorraad |
| Middleware / iPaaS | Ingebouwde retry, throttling, monitoring | Abonnementskosten, vendor lock-in | Bedrijven zonder eigen ontwikkelcapaciteit |
| Asynchrone wachtrij | Minder piekbelasting, goedkoper bij grote volumes | Niet geschikt voor realtime processen | Rapportages, historische data, migraties |
Voor de meeste MKB-bedrijven is de combinatie van kleine batches (500-1.000 records) met retry-logica de beste keuze. Het is betrouwbaar, voorspelbaar en schaalbaar. Middleware zoals Make of Zapier kan handig zijn als je geen eigen ontwikkelcapaciteit hebt, maar let op de kosten: bij meer dan ~500 taken per maand wordt maatwerk vaak voordeliger.
Wil je meer weten over welke systemen we koppelen? Bekijk ons overzicht van 176+ integraties en 3300+ populaire combinaties.
Technische achtergrond: wat gebeurt er onder de motorkap
Voor wie het iets dieper wil begrijpen: wat gebeurt er eigenlijk als je 10.000 records in één keer stuurt?
Een API is een communicatiekanaal tussen twee systemen. Bij elke call moet het ontvangende systeem:
- De data ontvangen en valideren (klopt de structuur?)
- Controleren of de data mag worden verwerkt (rechten, business rules)
- De data wegschrijven in de database
- Een bevestiging terugsturen
Bij 10.000 records tegelijk duurt dit proces te lang. De HTTP-verbinding heeft een timeout (meestal 30-60 seconden voor webservers, bij AFAS circa 15 minuten). Als de verwerking langer duurt, wordt de verbinding verbroken. Het probleem: de server blijft vaak doorwerken op de achtergrond, zonder dat jij nog een response krijgt. Je weet niet hoeveel records wél zijn verwerkt.
Daarnaast: databases hebben locks. Als je 10.000 records in één transactie probeert weg te schrijven, blokkeert dat de hele tabel voor andere processen. Bij een webshop betekent dit: klanten kunnen tijdelijk geen orders plaatsen. Bij een productiebedrijf: magazijnmedewerkers kunnen geen mutaties registreren.
Door te werken met kleinere batches voorkom je dit. Elke batch is een aparte transactie. Faalt er één? Dan verlies je maximaal die 500 records, niet alle 10.000. En je weet precies waar je gebleven bent.
Delta-verwerking: alleen wat veranderd is
Een slimme optimalisatie: synchroniseer niet alles, maar alleen wat er veranderd is sinds de laatste sync. Dit heet delta-verwerking. In plaats van 18.000 artikelen elke nacht te syncen, sync je alleen de 200 artikelen waarvan de voorraad of prijs is gewijzigd.
Dit scheelt enorm in API-calls, verwerkingstijd en datagebruik. De meeste moderne API's ondersteunen dit via een 'modified_since' parameter of een change log. Het vereist wel dat je bijhoudt wanneer je voor het laatst gesynchroniseerd hebt.
Protocollen: REST vs SOAP
AFAS biedt twee API-types: REST API en SOAP API. REST communiceert in JSON en SOAP in XML. SOAP is de voorganger van REST, strakker gedefinieerd, en wordt in moderne contexten weinig nieuw gebouwd. Je komt het tegen in enterprise-omgevingen: oude bankensystemen, overheidsdiensten en grote ERP-pakketten.
Voor nieuwe koppelingen gebruik je vrijwel altijd REST. Het is eenvoudiger, sneller en beter gedocumenteerd. Maar bij legacy-systemen in de bouw, zorg of overheid kom je soms SOAP tegen. Dan heb je geen keuze.
Veelgestelde vragen
Wat is de optimale batchgrootte voor mijn systeem?
Dat hangt af van het ontvangende systeem en de complexiteit van je data. Voor AFAS: 500-1.000 records. Voor Exact Online: 50-100 bij complexe transacties, tot 1.000 bij simpele inserts via bulk-endpoints. Voor Salesforce: ~10.000. Test altijd met realistische volumes, niet alleen met testdata.
Waarom werkt mijn koppeling in test wel maar in productie niet?
Klassiek probleem: vergeten te pagineren. In test staan misschien 50 records, die krijg je in één keer. In productie staan 15.000 records. Zonder paginering haal je alleen de eerste pagina op. De rest verdwijnt stilletjes. Test daarom altijd met minimaal 5.000+ records.
Wat zijn de kosten van een mislukte batchverwerking?
Stel: een groothandel verwerkt 200 inkooporders per dag. Elk order handmatig invoeren kost 3 minuten. Dat is 600 minuten = 10 uur handwerk per dag. Bij een uurloon van €35 is dat €350 per dag, €7.000 per maand, €84.000 per jaar aan vermijdbare loonkosten. Eén mislukte sync betekent een dag extra handwerk.
Kan ik niet gewoon alles 's nachts in bulk draaien?
Kan, maar is risicovol. Als de batch faalt (en dat gebeurt vaker dan je denkt), start je dag met incomplete data. Beter: verwerk continu in kleine batches, of gebruik event-driven koppelingen die direct triggeren bij een wijziging. Dan heb je altijd actuele data en geen nachtelijke verrassingen.
Hoe voorkom ik dubbele records bij een mislukte batch?
Door idempotentie in te bouwen: geef elk record een unieke ID mee. Als je dezelfde batch opnieuw verstuurt, herkent het systeem de duplicaten en slaat het ze over. Dit voorkomt dat een klant twee keer betaalt of dezelfde factuur dubbel in je boekhouding komt. Essentieel bij betalingen en orders.
Wat moet ik doen als ik een HTTP 429-fout krijg?
HTTP 429 betekent 'Too Many Requests': je hebt de rate limit overschreden. Stop met calls versturen en wacht. Implementeer exponential backoff: probeer opnieuw na 1 seconde, dan 2, 4, 8, enzovoort. Bouw throttling in zodat je automatisch pauzeert als je de limiet nadert. Monitor je API-gebruik zodat je dit van tevoren ziet aankomen.
Conclusie: klein is betrouwbaar
Grote batches lijken efficiënt maar zijn broos. Ze falen bij timeouts, rate limits en geheugenoverloop. En als ze falen, weet je niet wat er verwerkt is en wat niet. Het resultaat: datainconsistentie, handmatig opschonen en gefrustreerde gebruikers.
De oplossing is simpel maar vereist discipline: werk met kleine batches (500-1.000 records), bouw paginering in vanaf dag één, voeg retry-logica toe met exponential backoff, en log alles. Test niet alleen met testdata maar met realistische volumes. En monitor je API-gebruik zodat je problemen ziet aankomen voordat ze optreden.
In de praktijk betekent dit: rust, grip en ritme. Je weet dat je data klopt. Je hebt overzicht op wat er mis kan gaan. En als er iets misgaat, weet je precies waar en kun je het herstellen.
Wil je weten hoe dit er in jouw situatie uitziet? Of loop je tegen problemen aan met een bestaande koppeling? We denken graag mee. Plan een vrijblijvend adviesgesprek en we kijken samen naar de beste aanpak voor jouw systemen en volumes. Geen verkooppraatje, gewoon eerlijk advies vanuit de praktijk.