How to Build a Backpressure Generator Pause Producer Demo in Python

Demonstrates a producer–consumer pattern with a fixed-size buffer that pauses production when full, simulating backpressure.

Medium Python 3.9+ Aug 9, 2026 Comprehensions & generators 14 views 0 copies

Python code

27 lines
Python 3.9+
import time
import collections

def producer(buffer, max_size, items):
    """Adds items to the buffer until full, then pauses."""
    for item in items:
        while len(buffer) >= max_size:
            print(f"Buffer full ({len(buffer)}/{max_size}) — producer paused")
            time.sleep(0.1)
        buffer.append(item)
        print(f"Produced: {item} (buffer size: {len(buffer)})")

def consumer(buffer):
    """Consumes one item per call."""
    if buffer:
        item = buffer.popleft()
        print(f"Consumed: {item} (buffer size: {len(buffer)})")
        return item
    return None

if __name__ == "__main__":
    buffer = collections.deque(maxlen=3)
    items = ["a", "b", "c", "d", "e", "f"]
    producer(buffer, buffer.maxlen, items)

    for _ in range(len(items)):
        consumer(buffer)

Output

stdout
Produced: a (buffer size: 1)
Produced: b (buffer size: 2)
Produced: c (buffer size: 3)
Buffer full (3/3) — producer paused
Buffer full (3/3) — producer paused
Produced: d (buffer size: 3)
Buffer full (3/3) — producer paused
Buffer full (3/3) — producer paused
Produced: e (buffer size: 3)
Buffer full (3/3) — producer paused
Buffer full (3/3) — producer paused
Produced: f (buffer size: 3)
Consumed: a (buffer size: 2)
Consumed: b (buffer size: 1)
Consumed: c (buffer size: 0)
Consumed: d (buffer size: 2)
Consumed: e (buffer size: 1)
Consumed: f (buffer size: 0)

How it works

The producer function uses a while loop to check whether the buffer has reached max_size, pausing with time.sleep(0.1) when full. collections.deque(maxlen=3) enforces the buffer capacity, automatically dropping oldest items if you bypass the size check. The consumer pops items from the left side, simulating FIFO processing. This pattern mirrors real backpressure handling where a slow consumer forces the producer to wait.

Common mistakes

  • Using `deque(maxlen=3)` without checking fullness—silently drops items instead of pausing
  • Calling `len(buffer)` repeatedly in a tight loop without a sleep, causing high CPU usage
  • Not clearing the buffer before reuse, leading to unexpected state between runs

Variations

  1. Replace `time.sleep` with `asyncio.sleep` in an async producer for non-blocking backpressure
  2. Use a threading.Event or queue.Queue with `put` blocking to coordinate producer and consumer threads

Real-world use cases

  • Rate-limiting API requests when the response queue backs up during high-load bursts.
  • Building a video streaming pipeline where the encoder pauses when downstream decoder buffers fill.
  • Managing a job queue where producers wait until workers catch up to prevent memory exhaustion.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Comprehensions & generators

Related tutorials and quizzes for this topic.