Waarom Loop Over Items Essentieel is voor Grote Datasets
Stel je voor: je hebt een lijst met 10.000 klanten die je wilt emailen, maar je email provider staat slechts 100 emails per minuut toe. Of je moet 5000 producten updaten in een externe API die maximaal 50 requests per seconde accepteert. Hier komt de Loop Over Items node (voorheen Split In Batches) als redder in nood.
Deze node is het Zwitserse zakmes voor batch processing in N8N. Het transformeert onmogelijke taken in beheersbare chunks, voorkomt rate limiting, en maakt complexe iteraties mogelijk die anders je workflow zouden crashen.
Core Functionaliteit: Hoe Werkt Loop Over Items?
Het Basis Principe
De Loop Over Items node splitst grote datasets in kleinere, beheersbare batches:
- Input: 1000 items
- Batch Size: 10
- Result: 100 loops van 10 items elk
Elke batch wordt sequentieel verwerkt, waardoor je controle houdt over resource gebruik en API limits respecteert.
De Drie Output Branches
| Output | Wanneer Actief | Data | Use Case |
|---|---|---|---|
| loop | Bij elke batch | Current batch items | Processing, API calls |
| done | Na alle batches | Alle verwerkte items | Final results, summary |
| reset (optioneel) | Bij reset trigger | Reset state | Dynamic pagination |
Parameters & Configuratie
1. Batch Size
// Voorbeelden van batch size configuratie:
// Klein batch voor heavy processing
Batch Size: 1
// Verwerkt items één voor één
// Gebruik voor: CPU-intensieve taken, single-item APIs
// Medium batch voor balans
Batch Size: 10
// Goede balans tussen performance en resource gebruik
// Gebruik voor: Standaard API calls, database updates
// Groot batch voor bulk operations
Batch Size: 100
// Maximale throughput
// Gebruik voor: Simpele transformaties, bulk inserts2. Reset Option
De reset optie is cruciaal voor dynamische loops waar de beslissing om door te gaan afhangt van de output binnen de loop:
// Reset configuratie voor API paginering
Reset: true
Reset When: {{ $json.hasNextPage === false }}
// De loop reset wanneer:
// - Er geen volgende pagina is
// - Een specifieke conditie is bereikt
// - Maximum aantal iteraties is bereikt3. Options
- Context Variables: Toegang tot loop metadata
- Error Handling: Continue on fail options
- Performance: Memory optimization settings
Context Variables: Loop Intelligence
De node biedt krachtige context variables voor loop tracking:
| Variable | Expression | Returns | Gebruik |
|---|---|---|---|
| noItemsLeft | {{$node["Loop Over Items"].context["noItemsLeft"]}} | Boolean | Check of er nog items zijn |
| currentRunIndex | {{$node["Loop Over Items"].context["currentRunIndex"]}} | Number | Huidige iteratie nummer |
| maxRunIndex | {{$node["Loop Over Items"].context["maxRunIndex"]}} | Number | Totaal aantal iteraties |
Praktijkvoorbeeld 1: API Rate Limiting
Een van de meest voorkomende use cases is het respecteren van API rate limits:
// Workflow configuratie voor email rate limiting:
1. Loop Over Items Node:
- Batch Size: 5
- Input: 100 email adressen
2. Send Email Node (binnen loop):
- Verwerkt 5 emails tegelijk
- Gebruikt batch data van Loop Over Items
3. Wait Node:
- Duration: 60000ms (1 minuut)
- Zorgt voor rate limit compliance
4. Done Output:
- Combineert alle resultaten
- Totaal: 100 emails in 20 minutenPraktijkvoorbeeld 2: API Paginering met Reset
Voor APIs met onbekend aantal pagina's gebruik je de reset functionaliteit:
// Paginering workflow met dynamische reset
// 1. Loop Over Items configuratie:
const loopConfig = {
batchSize: 1, // Process één pagina tegelijk
reset: true,
resetWhen: '{{ $json.hasMore === false }}'
};
// 2. HTTP Request node (binnen loop):
const apiRequest = {
method: 'GET',
url: 'https://api.example.com/products',
queryParameters: {
page: '{{ $node["Loop Over Items"].context["currentRunIndex"] + 1 }}',
limit: 100
}
};
// 3. IF Node check:
if ($json.data.length === 0 || !$json.pagination.hasNext) {
// Trigger reset - stop de loop
return { reset: true };
} else {
// Continue met volgende pagina
return { continue: true };
}
// 4. Aggregate Results:
// Done output bevat alle pagina's gecombineerdPraktijkvoorbeeld 3: Database Batch Updates
Voor het updaten van duizenden database records zonder de database te overbelasten:
// Database batch update configuratie
// 1. Get All Records (bijvoorbeeld 5000 items)
SELECT * FROM products WHERE needs_update = true;
// 2. Loop Over Items:
Batch Size: 50 // Update 50 records per keer
// 3. MySQL Update Query (binnen loop):
const batchUpdate = items.map(item => {
return `
UPDATE products
SET
price = ${item.new_price},
updated_at = NOW(),
status = 'updated'
WHERE id = ${item.id};
`;
}).join('');
// Execute als transaction voor consistency
START TRANSACTION;
${batchUpdate}
COMMIT;
// 4. Progress Tracking:
const progress = {
current: $node["Loop Over Items"].context["currentRunIndex"],
total: $node["Loop Over Items"].context["maxRunIndex"],
percentage: Math.round((current / total) * 100)
};
console.log(`Progress: ${progress.percentage}% (${progress.current}/${progress.total})`);Advanced Patterns & Techniques
1. Nested Loops Pattern
Voor complexe scenarios met meerdere loop levels:
// Nested loops voor category > products > variants
// Outer Loop: Categories
Loop Over Items (Categories)
Batch Size: 1
Input: All categories
// Inner Loop: Products per category
└─> Loop Over Items (Products)
Batch Size: 10
Input: Products van current category
// Deepest Loop: Variants per product
└─> Loop Over Items (Variants)
Batch Size: 5
Input: Variants van current product
└─> Process Variant
Update price
Update stock
Save to database2. Error Handling in Loops
// Robuuste error handling binnen loops
// Loop Over Items configuratie:
const loopSettings = {
batchSize: 10,
continueOnFail: true // Belangrijke setting!
};
// Try-Catch pattern binnen loop:
try {
// Process batch
const results = await processBatch($input.all());
// Track successful items
const successful = results.filter(r => r.success);
const failed = results.filter(r => !r.success);
// Log failures maar ga door
if (failed.length > 0) {
console.error(`Failed items in batch ${currentRunIndex}:`, failed);
// Store voor retry logic
$node.failedItems = [...($node.failedItems || []), ...failed];
}
return successful;
} catch (error) {
// Log error maar stop niet de hele workflow
console.error(`Batch ${currentRunIndex} failed:`, error);
// Return empty array om door te gaan
return [];
}3. Dynamic Batch Size
// Dynamische batch size based op conditions
// Bepaal batch size based op tijd van de dag
const hour = new Date().getHours();
let batchSize;
if (hour >= 9 && hour <= 17) {
// Business hours: kleinere batches
batchSize = 5;
} else if (hour >= 22 || hour <= 6) {
// Nacht: grote batches
batchSize = 100;
} else {
// Off-peak: medium batches
batchSize = 25;
}
// Of based op system load
const systemLoad = await getSystemMetrics();
if (systemLoad.cpu > 80) {
batchSize = 1; // Minimize load
} else if (systemLoad.cpu < 30) {
batchSize = 50; // Maximize throughput
} else {
batchSize = 10; // Balanced approach
}Performance Optimalisatie
Memory Management
| Dataset Size | Recommended Batch Size | Memory Impact | Processing Time |
|---|---|---|---|
| < 100 items | 10-50 | Minimal | Seconds |
| 100-1000 items | 10-25 | Low | Minutes |
| 1000-10000 items | 5-10 | Moderate | 10-30 min |
| > 10000 items | 1-5 | High | Hours |
Best Practices voor Performance
- ✅ Start klein: Begin met batch size 1, verhoog geleidelijk
- ✅ Monitor memory: Check N8N memory gebruik tijdens execution
- ✅ Use streaming: Voor zeer grote files, overweeg streaming approaches
- ✅ Clean up: Clear ongebruikte variables binnen loops
- ✅ Parallellisatie: Overweeg meerdere N8N instances voor echt grote jobs
Common Use Cases & Solutions
1. Email Marketing Campaigns
// Email campaign met personalisatie
Workflow:
1. Google Sheets: Get subscriber list (10,000 contacts)
2. Loop Over Items: Batch size 50
3. Merge data met personalisatie variabelen
4. SendGrid: Send batch emails
5. Wait: 30 seconds (rate limit: 100/minute)
6. Update Google Sheets met send status2. E-commerce Product Sync
// Shopify naar WooCommerce sync
Workflow:
1. Shopify: Get all products (pagination)
2. Loop Over Items: Batch size 20
3. Transform product data format
4. Check if product exists in WooCommerce
5. IF exists: Update | ELSE: Create new
6. Log sync results to database3. Social Media Posting
// Multi-platform social media scheduler
Workflow:
1. Airtable: Get scheduled posts for today
2. Loop Over Items: Batch size 1
3. Split by platform (Twitter, LinkedIn, Facebook)
4. Post to respective platform API
5. Wait: Platform-specific rate limit
6. Update Airtable: Mark as posted4. Data Migration
// Legacy system naar modern database
Workflow:
1. Legacy API: Export all records
2. Loop Over Items: Batch size 100
3. Data transformation & cleaning
4. Validation checks
5. Insert into new PostgreSQL database
6. Generate migration reportTroubleshooting & Common Issues
Issue 1: Loop Stopt Voortijdig
Probleem: Loop stopt voor alle items verwerkt zijn
Oplossingen:
- Check reset conditions - mogelijk te vroeg getriggerd
- Verifieer dat 'done' output correct verbonden is
- Controleer error handling settings
Issue 2: Memory Overflow
Probleem: N8N crasht bij grote datasets
Oplossingen:
- Verklein batch size
- Gebruik sub-workflows voor isolation
- Clear variables na gebruik:
delete $node.tempData - Verhoog N8N memory limit in Docker/settings
Issue 3: Infinite Loop
Probleem: Loop blijft oneindig doorgaan
Oplossingen:
// Implementeer altijd een exit condition:
const maxIterations = 1000;
const currentIteration = $node["Loop Over Items"].context["currentRunIndex"];
if (currentIteration >= maxIterations) {
throw new Error('Maximum iterations reached - preventing infinite loop');
}
// Of gebruik timeout:
const startTime = $workflow.startTime;
const maxDuration = 3600000; // 1 hour
if (Date.now() - startTime > maxDuration) {
return { done: true, reason: 'Timeout reached' };
}Issue 4: Context Variables Undefined
Probleem: Context variables returnen undefined
Oplossingen:
- Gebruik exacte node naam in expression
- Zorg dat je binnen de loop scope bent
- Check of node al minstens één keer uitgevoerd is
Loop Over Items vs Alternatives
| Method | Use Case | Pros | Cons |
|---|---|---|---|
| Loop Over Items | Large datasets, rate limiting | Memory efficient, flexible | Sequential only |
| HTTP Batching | API specific batching | Built-in, simple | HTTP only |
| Code Node Loop | Complex logic | Full control | Memory intensive |
| Sub-workflows | Isolation needed | Clean separation | Overhead |
2025 Updates & Improvements
Recent updates hebben de Loop Over Items node nog krachtiger gemaakt:
🆕 Nieuwe Features
- ✨ Verbeterde Reset Logic: Meer flexibele reset conditions met expressions
- ✨ Better Context Variables: Uitgebreide metadata beschikbaar
- ✨ Performance Updates: Tot 40% sneller bij grote datasets
- ✨ Enhanced Error Handling: Betere error recovery options
🔮 Toekomstige Ontwikkelingen
De N8N community werkt aan:
- Parallel batch processing
- Dynamic batch size adjustment
- Built-in retry mechanisms
- Advanced progress tracking
Best Practices Checklist
- ☑️ Start met kleine batch sizes en verhoog gradueel
- ☑️ Implementeer altijd error handling
- ☑️ Gebruik Wait nodes voor rate limiting
- ☑️ Monitor memory gebruik bij grote datasets
- ☑️ Test met subset voordat je full dataset verwerkt
- ☑️ Documenteer je batch size keuzes
- ☑️ Implementeer logging voor debugging
- ☑️ Gebruik context variables voor progress tracking
- ☑️ Overweeg sub-workflows voor isolation
- ☑️ Plan voor failure recovery
Conclusie
De Loop Over Items node is onmisbaar voor serieuze N8N automatisering. Het transformeert onmogelijke taken - zoals het verwerken van 100.000 records of het respecteren van strenge API limits - in beheersbare, betrouwbare workflows.
Of je nu email campaigns verstuurt, databases synchroniseert, of APIs scrapet, Loop Over Items geeft je de controle en flexibiliteit die je nodig hebt voor enterprise-grade automatisering.
💡 Pro Tip: Begin altijd met een test run op 10-20 items. Pas als alles werkt, schakel je op naar je volledige dataset. Dit bespaart tijd, voorkomt errors, en beschermt tegen rate limit bans!