Free · Live · No API key

See why Promise.all is faster. Watch it happen.

Configure async tasks, pick a pattern — sequential, Promise.all, or Promise.allSettled — and watch an animated Gantt chart show exactly when each task runs. Add failures to see how each pattern responds.

  1. Configure tasks

    Set duration and whether each task fails

  2. Pick a pattern

    Sequential, Promise.all, allSettled, for...of

  3. Watch it run

    Animated bars show real elapsed time

Tasks

Task A
1000ms
Task B
1500ms
Task C
800ms
Sequential total3300ms
Parallel total (approx.)1500ms
Speedup2.2×

Execution Pattern

Equivalent JavaScript

javascript
// ✅ Promise.all — ~1500ms total
const [taska, taskb, taskc] = await Promise.all([
  fetchTaska(),
  fetchTaskb(),
  fetchTaskc(),
]);

When to use each pattern

Sequential await

Task B depends on Task A's result — fetch a user, then fetch their orders using the user ID.

const user = await fetchUser();
const orders = await fetchOrders(user.id);

Promise.all

Independent tasks where you need all results. One failure aborts everything.

const [user, posts] = await Promise.all([
  fetchUser(), fetchPosts()
]);

Promise.allSettled

Independent tasks where partial results are acceptable — a dashboard that shows what it can.

const results = await Promise.allSettled([
  fetchUser(), fetchPosts()
]);

for...of + await

Sequential processing of an array — each item must complete before the next begins.

for (const id of orderIds) {
  await processOrder(id);
}

Frequently asked questions

How does the simulation work?

Each task is a JavaScript Promise wrapping a setTimeout of the configured duration. Choosing 'sequential' awaits each task before starting the next. 'Promise.all' starts all tasks simultaneously with Promise.all. 'Promise.allSettled' does the same but collects all results even on failure. The animated bars track real wall-clock time using Date.now() — nothing is faked or pre-calculated.

What does the fail toggle on each task do?

When toggled, the task's Promise rejects instead of resolves when its timer fires. In Promise.all mode, one rejection causes the entire Promise.all to reject — you'll see the outcome is 'failed' even though other tasks completed. In Promise.allSettled mode, the rejection is collected alongside successes and the overall result is still 'partial' rather than a full failure.

What does 'compare with sequential' do?

It runs both your chosen pattern and a sequential simulation simultaneously, showing two timeline charts stacked on top of each other. This makes the timing difference between sequential and parallel execution immediately visible — the sequential bars stack one after another while the parallel bars all start at the same time.

Does this reflect real-world async performance?

Yes, for I/O-bound work like API calls and database queries. JavaScript is single-threaded, so Promise.all doesn't help with CPU-bound computation. But most async slowdowns in web applications are I/O — network requests that can genuinely run concurrently. The timing ratios you see in the simulator accurately represent what you'd see with real API calls of the same durations.

Why does for...of look the same as sequential?

Because it is. 'for...of with await' is sequential execution in a loop — each iteration awaits the previous before starting the next. The only difference from writing sequential awaits manually is syntax: for...of is cleaner when processing an array, but the timing behavior is identical.