Your loop yields every 500 items. It still freezes. Here's why (and a fix)
Description and use
A loop that yields every 500 items can still freeze when heavy items cluster. The time‑sliced approach yields based on elapsed time, keeping the event loop responsive while maintaining similar total runtime.
Problem
Long loops that yield every N items can still freeze the event loop when a cluster of heavy items appears, causing timers to fire late and requests to time out.
Outcome
time‑sliced achieves similar total runtime to a plain loop while keeping the longest event‑loop freeze down to 11 ms (vs 254 ms with every‑500 strategy) and remaining responsive during large imports.
Workflow
- Process rows one by one
- Measure elapsed time since last yield
- If elapsed time exceeds budget, await yieldToEventLoop() (setImmediate or setTimeout(0) depending on runtime)
- Reset budget timer and continue processing
Evidence
When items are cheap, you yield rarely, so overhead stays low. When items are slow, you yield often, so nothing freezes.
time‑sliced finishes in about the same time as the plain loop, and the event loop never freezes much longer than the budget.
A 1 ms heartbeat timer measures the longest event-loop freeze. Median of 3 runs, Node.js 24.
- Record date: 2026-10-26T05:11:21.189Z