Skew & Shuffle Lab
A distributed job finishes when its slowest task finishes. That single sentence explains why one key holding most of the rows makes a cluster twice the size run at exactly the same speed, and why the profile of a slow job is usually an idle CPU.
Partition loads, task counts and stage timings come from models in this repository. They reproduce the mechanism — how work is distributed, and what a shuffle costs relative to a scan — not any engine's measured behaviour, which varies by version, configuration and how much memory a task was given.
These two are on one page because they are the same underlying fact seen twice. A shuffle is where data moves between tasks according to a key; skew is what happens when that key is unevenly distributed. The shuffle is what makes distributed processing possible, and the key distribution is what decides whether it is fast.
Skew
One key holds most of the rows, so one task holds most of the work. Add workers and watch nothing happen.
The first thing to try is adding capacity, because it is the thing that works everywhere else. Watch it not work here, then salt the hot key and watch the runtime move.
- —One task is still running long after the rest finished, and the stage is waiting on exactly one of them.
- —Adding executors changes the bill and not the runtime.
- —The job got slow the week a large customer onboarded, with no code change involved.
- —Retrying the failed task fails again in the same place, because the data has not changed.
- —Salt the hot key only. Salting every key multiplies partitions and the mean by the same factor and moves nothing.
- —Reconsider whether that key should be the partition key at all — the fix is often upstream of the job.
- —Broadcast the small side of a join so no shuffle happens for it in the first place.
- —Handle the hot key separately, as its own job, when it is genuinely one tenant rather than a distribution.