Skip to content

JavaScript Tutorial Asynchronous JavaScript

Sequential vs Parallel Async Requests

Lesson 148 of 258 2 min read By Deepak Paswan Updated Oct 4, 2026

When you have several async tasks, you choose how to run them.

Sequential: one after another

Use this when each step needs the result of the previous one, or when the order matters, or when you must not overload a server.

script.js
JS
const wait = (ms, value) => new Promise(resolve => setTimeout(() => resolve(value), ms));

async function sequential() {
  const start = Date.now();
  const a = await wait(200, "A");
  const b = await wait(200, "B");
  const c = await wait(200, "C");
  console.log(a + b + c);                     // → ABC
  console.log("elapsed ms:", Date.now() - start);   // about 600
}
sequential();

Each await finishes before the next starts. Total time: about 600 ms (the sum).

Parallel: all at once

When tasks are independent, start them all first, then wait for all of them.

script.js
JS
const wait = (ms, value) => new Promise(resolve => setTimeout(() => resolve(value), ms));

async function parallel() {
  const start = Date.now();
  const [a, b, c] = await Promise.all([wait(200, "A"), wait(200, "B"), wait(200, "C")]);
  const elapsed = Date.now() - start;
  console.log(a + b + c);                     // → ABC
  console.log("elapsed ms:", elapsed);               // about 200
}
parallel();

Total time: about 200 ms, the slowest one.

The trap: await inside a loop

script.js
JS
const wait = (ms, value) => new Promise(resolve => setTimeout(() => resolve(value), ms));
const ids = [1, 2, 3];

async function slow() {
  const results = [];
  for (const id of ids) {
    results.push(await wait(100, "user " + id));   // each waits for the previous: sequential
  }
  console.log(results);
}
slow();

If the requests are independent, this wastes time. The parallel version:

script.js
JS
const wait = (ms, value) => new Promise(resolve => setTimeout(() => resolve(value), ms));
const ids = [1, 2, 3];

async function fast() {
  const results = await Promise.all(ids.map(id => wait(100, "user " + id)));
  console.log(results); // → ["user 1", "user 2", "user 3"]
}
fast();

ids.map(...) starts all three promises right away, and Promise.all waits for them.

Another way: start first, await later

script.js
JS
const wait = (ms, value) => new Promise(resolve => setTimeout(() => resolve(value), ms));

async function main() {
  const userPromise = wait(100, "user");      // started now
  const postsPromise = wait(100, "posts");    // started now, runs at the same time

  const user = await userPromise;
  const posts = await postsPromise;
  console.log(user, posts); // → user posts
}
main();

forEach does not wait

script.js
JS
// Does NOT wait for the awaits inside it
ids.forEach(async id => { await load(id); });

// Use for...of (sequential) or Promise.all with map (parallel)

Limiting concurrency

Firing 500 requests at once can overwhelm a server or your connection. Process them in batches (a few at a time), or with a small helper or library.

How to choose

SituationApproach
Step B needs the result of step Asequential (await each)
Independent tasks, all neededparallel with Promise.all
Many tasks, polite to the serverbatches of a limited size
Strict order of side effectssequential
lightbulb
A quick check
If you wrote await several times in a row and none of the calls uses the previous result, you can probably run them in parallel.