Parallel Async Operations
HardBy default, async/await runs operations sequentially. To run operations in parallel, use Promise.all() with await. This is one of the most common performance optimizations in JavaScript. Understanding when to parallelize and when to sequence is essential for writing efficient async code.
Interactive Visualization
Sequential Execution
0s2.0s4.0s
fetchUser()
pending
fetchPosts()
idle
Elapsed:0.0s
Awaiting:fetchUser()
Sequential
1async function sequential() {2 const user = await fetchUser(); // 2s3 const posts = await fetchPosts(); // 2s4 return { user, posts };5}6// Total: 4 seconds (2 + 2)
Parallel
1async function parallel() {2 const [user, posts] = await Promise.all([3 fetchUser(), // 2s4 fetchPosts(), // 2s (runs at same time!)5 ]);6 return { user, posts };7}8// Total: 2 seconds (max of 2, 2)
Sequential: We start fetchUser() and WAIT for it to complete before starting anything else.
1 / 5
Key Insight: Sequential: 4s (2+2). Parallel: 2s (max). When operations are independent, use Promise.all!
Key Points
- await runs sequentially by default
- Use Promise.all() to run operations in parallel
- Start operations before awaiting to run in parallel
- Do NOT use await in a loop for independent operations
- Promise.all() fails fast on first rejection
- Use Promise.allSettled() when partial success is acceptable
Code Examples
Sequential vs Parallel
// ❌ SEQUENTIAL (slow) async function sequential() { const user = await fetchUser(); // 100ms const posts = await fetchPosts(); // 100ms const comments = await fetchComments(); // 100ms // Total: 300ms return { user, posts, comments }; } // ✅ PARALLEL (fast) async function parallel() { const [user, posts, comments] = await Promise.all([ fetchUser(), // Start immediately fetchPosts(), // Start immediately fetchComments() // Start immediately ]); // Total: ~100ms (max of all) return { user, posts, comments }; }
Promise.all() runs all Promises simultaneously, waiting for all to complete.
The Loop Anti-Pattern
// ❌ WRONG: Sequential in loop async function fetchUsers(ids) { const users = []; for (const id of ids) { const user = await fetchUser(id); // Waits each iteration! users.push(user); } return users; // Slow: ids.length × fetch time } // ✅ CORRECT: Parallel with map async function fetchUsers(ids) { const promises = ids.map(id => fetchUser(id)); const users = await Promise.all(promises); return users; // Fast: ~single fetch time } // Alternative with Promise.all() async function fetchUsers(ids) { return Promise.all(ids.map(id => fetchUser(id))); }
Never use await inside a loop for independent operations. Use map + Promise.all().
Start Before Await
// ✅ Good: Start operations, then await async function fetchDashboard() { // Start all operations immediately const userPromise = fetchUser(); const postsPromise = fetchPosts(); const statsPromise = fetchStats(); // Now await results (already running in parallel!) const user = await userPromise; const posts = await postsPromise; const stats = await statsPromise; return { user, posts, stats }; } // Same as Promise.all() but more flexible
Start Promises before awaiting to run them in parallel. Then await results.
Partial Success with allSettled
// When some can fail but you want the rest async function fetchWithFallbacks(urls) { const results = await Promise.allSettled( urls.map(url => fetch(url)) ); const successes = results .filter(r => r.status === 'fulfilled') .map(r => r.value); const failures = results .filter(r => r.status === 'rejected') .map(r => r.reason); console.log('Loaded:', successes.length); console.log('Failed:', failures.length); return successes; // Return what worked }
Use Promise.allSettled() when you need all results regardless of individual failures.
Common Mistakes
- Using await inside loops for independent operations
- Not realizing sequential is the default
- Using Promise.all() when operations depend on each other
- Not handling partial failures appropriately
Interview Tips
- Know how to parallelize with Promise.all()
- Know the "await in loop" anti-pattern
- Understand when to use all() vs allSettled()
- Be able to optimize slow sequential code