Pushing back on the producer when the consumer is overwhelmed.
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.
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))
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).