What Concurrency Actually Means
Concurrency is not parallelism wearing a different name. It means two higher-level tasks progressing within the same timeframe, one tiny piece at a time, on a single thread that never lets anyone cut in line.
The last post drew a hard line between parallelism (the same instant, needs separate hardware) and whatever JavaScript actually does on its one thread. That "whatever it does" has a name.
Concurrency means two higher-level tasks making progress within the same timeframe, not the same instant. Small distinction, but it changes how you should picture a single-threaded program behaving.
Breaking a Task Into Pieces
A higher-level task, a macro task, is usually made of smaller pieces, micro tasks. Say a page needs to do two: loading a profile picture (four small chunks) and rendering a live search dropdown (three small chunks).
Assume each chunk takes one second. Seven chunks, seven seconds total, no matter the order, since one thread only ever does one chunk at a time.
The interesting part isn't the total time. It's the order those seven chunks run in, and that order changes what the person using the page actually experiences.
Two Ways to Schedule the Same Seven Seconds
Play with both schedules below. Same two tasks, same seven seconds, very different experience.
Concurrency Visualizer, one thread, two tasks
Single Thread, running right now
A1
Task A: profile picture
1 / 4 done
Task B: search dropdown
0 / 3 done
Elapsed: 1s of 7s total
Task A (loading a profile picture) starts. On a single thread, nothing else can run until A is entirely done.
The blocking schedule finishes all four picture chunks before touching the dropdown at all. For four seconds, anyone typing sees nothing happen, then it suddenly catches up.
That's not hypothetical. It's exactly what synchronous XHR used to do, an old way of making network requests that froze the whole page until the response came back. It got deprecated and removed for exactly this reason: freezing the UI is a bad experience even when the total time never changes.
The interleaved schedule takes turns instead, one picture chunk, one dropdown chunk, back and forth. Neither finishes first, both make visible progress the whole time, and nothing freezes.
That second schedule, taking turns instead of finishing one task before starting the other, is what concurrency actually looks like.
Why Everything Shares One Line, Not Just Your Code
Here's the part that surprised me: it's not just your JavaScript callbacks waiting in that line. The browser's garbage collector, its style engine, its layout and paint work, all of it takes turns on that same thread as your code.
That thread is a strict first-come-first-served queue. A network response ready to run does not get to interrupt whatever's currently running, it goes to the back of the line, same as a garbage collection pass or a repaint waiting its turn.
That's also the real explanation for animation jank. A repaint needs its turn 60 times a second to stay smooth, and if something else is occupying the thread right then, the repaint waits, and the animation stutters. Nothing's broken, the thread is just busy.
Why This Motivates the Rest of This Course
None of this scheduling is fully in your control, timing varies run to run, and coordinating several in-progress tasks gets complicated fast once one depends on two or three others finishing first.
Every pattern this course covers, callbacks, thunks, promises, generators, observables, CSP, is a different tool for managing that same complexity. None of them removes the single thread or its queue. They only change how readable your code stays while you coordinate work across it.
The Essentials
- Concurrency means two tasks progressing within the same timeframe, broken into small pieces that take turns, not two things at the exact same instant.
- Total time is identical whether work is blocking or interleaved. What changes is whether unrelated work looks frozen while it waits.
- A blocking schedule is what synchronous XHR did, and it's exactly why that API got removed from the web platform.
- The single thread is shared by more than your JavaScript. Garbage collection, style, layout, and paint all compete for the same first-come-first-served queue, which is also what causes animation jank.
- Every async pattern ahead in this course manages this same complexity, not the single thread itself, that never goes away.
Callbacks are the most fundamental way JavaScript expresses "do this, then later do that." The next post starts there, and starts showing exactly where callbacks stop being enough.
Keep reading