MAC collapse: EDCA contention vs granted access

This is one offered load, seen from the receiver. 50 client stations transmit to one radio head; the head is the receiver and is not drawn. Everything below is what reaches it: a bundle received, a bundle missed, or nothing. Both strands run the same slot clock (120 ms), the same station count, and literally the same arrivals: one draw per station per slot feeds both, so the same station receives the same burst at the same instant on each and the only difference downstream is how the two systems handle it. Channel capacity is 1000 / SLOT_MS = 8.3 A-MPDU/s per strand, which at 8 packets an aggregate is 67 packets/s. The unit of work is the A-MPDU; the packets fill it in. Blue is the A-MPDU the next grant will open onto, still held in the client's stack and not yet released to its 802.11 driver: blue of a given length this slot becomes green of that length when the grant opens. The receive side has no queue of its own, and neither does the contention strand, because only a grant holds anything back. Green is in the 802.11 MAC: arbitrating or transmitting. Red is a miss: two bundles went at once and the head received neither, so both are drawn. One light is one packet and a bundle is one A-MPDU, which is the countable thing - exactly one bundle can be received in a slot, and red means two or more tried and none arrived. Yellow is a grant that opened onto nothing, one light because it carries no packets at all. Dark is nothing to send. The contention strand holds nothing back, so it is only ever green or red; blue and yellow are what a scheduler looks like. Those four colours are the whole palette. The contention window is reported as a number below rather than as a shade, so nothing competes with them.
Build guide — bill of materials, wiring and the Arduino sketch for the physical two-strand version.

Offered 0.0 A-MPDU/s  ·  probability 0.0000 per station per slot  ·  capacity 8.3 A-MPDU/s
Strand A: EDCA contention. Uniform backoff in [0, CW], freeze while the medium is busy, transmit at zero; colliders double CW and redraw.
Delivered 0/s  ·  collision slots 0/s  ·  mean CW of queued stations -
Strand B: granted access. One grant per slot, fixed round-robin over all lights, blind to queue state; CW stays pinned at 15.
Delivered 0/s  ·  grants to empty queues 0/s
Delivered vs offered load. Measured points fill in as load sweeps. The dashed line is the ideal demand-aware scheduler: delivered equals offered up to capacity, then capacity. Strand A rolls over as collisions double windows; strand B tracks offered on delivery but pays the yellow (unused grants) at low load. The crossover is the argument for demand-aware granting.
nothing to send held in the stack, awaiting its grant in the MAC: arbitrating or transmitting missed: two bundles collided grant with nothing to send