Concurrency Backpressure

Pushing back on the producer when the consumer is overwhelmed.

The idea

In asynchronous systems (like message queues, event loops, or microservices), the producer might send data much faster than the consumer can process it. If left unchecked, the consumer's memory will blow up with queued tasks. Backpressure is a signaling mechanism where the consumer tells the producer to slow down or stop until it catches up.

Step 1: Producer is emitting events quickly. Consumer queue is filling up.

How it works (Bounded Queues)

The simplest way to implement backpressure within a single application is using a bounded queue. If the queue hits a maximum capacity, the producer thread blocks (or receives an error) when trying to add more.

import asyncio

async def producer(queue):
    for i in range(100):
        # If queue is full (maxsize=5), this blocks automatically!
        # This naturally slows down the producer (Backpressure).
        await queue.put(f"Task {i}")
        print(f"Produced Task {i}")

async def consumer(queue):
    while True:
        task = await queue.get()
        print(f"Consuming {task}")
        await asyncio.sleep(1) # Slow consumer
        queue.task_done()

async def main():
    queue = asyncio.Queue(maxsize=5) # Bounded queue creates backpressure
    await asyncio.gather(producer(queue), consumer(queue))

Cost

By preventing the producer from overwhelming the consumer, we trade latency (the producer has to wait) to protect availability (the consumer doesn't run out of memory and crash).

Watch out for