This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: fastapi-uvicorn-stream-backpressure-guardrail

FastAPI Uvicorn Multiplexed Stream Backpressure Guardrail

Enforces strict producer-consumer backpressure mechanisms and bounded concurrency queues for HTTP/2 multiplexed streams and Server-Sent Events (SSE) in FastAPI/Uvicorn deployments. Prevents unconstrained heap ballooning, event-loop starvation, and OOM terminations caused by fast upstream generators paired with slow network consumers.

Prohibited Anti-Pattern: Unbounded Async Generator Consumption and Zero-Backpressure Task Spawning on Multiplexed SSE/Streaming Endpoints

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: FastAPI Uvicorn Multiplexed Stream Backpressure Guardrail - Enforces strict producer-consumer backpressure mechanisms and bounded concurrency queues for HTTP/2 multiplexed streams and Server-Sent Events (SSE) in FastAPI/Uvicorn deployments. Prevents unconstrained heap ballooning, event-loop starvation, and OOM terminations caused by fast upstream generators paired with slow network consumers.
globs: **/*.py
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/fastapi-uvicorn-stream-backpressure-guardrail"
---

# FastAPI Uvicorn Multiplexed Stream Backpressure Guardrail

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Unbounded Async Generator Consumption and Zero-Backpressure Task Spawning on Multiplexed SSE/Streaming Endpoints

## System Constraints
You are a Principal Backend Architect enforcing strict asyncio event-loop backpressure and memory constraints on FastAPI and Uvicorn streaming endpoints. You mandate bounded queues, client-disconnect checks, and flow-controlled chunk emission across all HTTP/2 and SSE streams.

## Strict Guidelines
- Engineers MUST ALWAYS enforce bounded buffer sizes on `asyncio.Queue` (e.g., `maxsize=32` to `maxsize=128`) when piping upstream messages to `StreamingResponse` or SSE streams.
- Engineers MUST NOT spawn detached `asyncio.create_task` calls per incoming event or client chunk without passing through an explicit concurrency semaphore and bounded memory pool.
- Engineers MUST verify client connectivity status before and during heavy stream yields using `await request.is_disconnected()` to terminate abandoned upstream processing immediately.
- Streaming generators MUST employ cooperative yields using `await asyncio.sleep(0)` or explicitly await socket write availability to prevent monolithic CPU bursts from starving the single-threaded event loop.
- Engineers MUST configure Uvicorn worker limits (`--limit-concurrency`, `--timeout-keep-alive`) and apply global admission control (e.g., token-bucket or semaphore middleware) to prevent multiplexed stream descriptor exhaustion.

## Bad vs Good Implementations
### Multiplexed SSE Producer with Bounded Queue and Disconnect Detection

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: The generator executes without assessing downstream socket flow or client disconnections. If an HTTP/2 client throttles its TCP window or stalls consumption, Uvicorn's internal buffer balloons in the Python heap, leading to memory saturation and eventual OOM crash.
```python
import asyncio
from fastapi import FastAPI
from fastapi.responses import StreamingResponse

app = FastAPI()

async def unbounded_event_generator():
    # ANTI-PATTERN: Infinite unbounded generator pushing chunks without checking client status
    # or using unconstrained task accumulation, leading to memory bloat when client reads slowly.
    while True:
        data = await fetch_large_telemetry_payload()
        yield f"data: {data}\n\n"
        # Zero backpressure: if network socket is congested, Uvicorn buffers heap frames infinitely

@app.get("/stream")
async def stream_data():
    return StreamingResponse(unbounded_event_generator(), media_type="text/event-stream")
```

#### Production Standard (Correct)
> **Standard**: Implements an explicit bounded queue with `maxsize=64`, proactively monitors `request.is_disconnected()` to reclaim resources immediately on disconnect, bounds active streams via a global `Semaphore`, and ensures tasks are gracefully cancelled in a `finally` block.
```python
import asyncio
from typing import AsyncGenerator
from fastapi import FastAPI, Request, HTTPException, status
from fastapi.responses import StreamingResponse

app = FastAPI()
GLOBAL_STREAM_SEMAPHORE = asyncio.Semaphore(500)  # Constrain concurrent active streams

async def bounded_event_generator(request: Request) -> AsyncGenerator[str, None]:
    queue: asyncio.Queue[str] = asyncio.Queue(maxsize=64)  # Strict bounded backpressure

    async def upstream_producer():
        try:
            while not await request.is_disconnected():
                item = await fetch_telemetry_batch()
                # Puts block when consumer/network stalls, preventing heap ballooning
                await queue.put(f"data: {item}\n\n")
                await asyncio.sleep(0)  # Cooperative event loop yield
        finally:
            await queue.put("__DONE__")

    producer_task = asyncio.create_task(upstream_producer())
    try:
        while True:
            if await request.is_disconnected():
                break
            msg = await queue.get()
            if msg == "__DONE__":
                break
            yield msg
            queue.task_done()
    finally:
        producer_task.cancel()
        await asyncio.gather(producer_task, return_exceptions=True)

@app.get("/stream")
async def stream_data(request: Request):
    if GLOBAL_STREAM_SEMAPHORE.locked():
        raise HTTPException(status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Max streams exceeded")
    
    async def guarded_stream():
        async with GLOBAL_STREAM_SEMAPHORE:
            async for chunk in bounded_event_generator(request):
                yield chunk

    return StreamingResponse(guarded_stream(), media_type="text/event-stream")
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: FastAPI Uvicorn Multiplexed Stream Backpressure Guardrail

FastAPI Uvicorn Multiplexed Stream Backpressure Guardrail defines an industrial-grade behavioral standard for backend engineering. Enforces strict producer-consumer backpressure mechanisms and bounded concurrency queues for HTTP/2 multiplexed streams and Server-Sent Events (SSE) in FastAPI/Uvicorn deployments. Prevents unconstrained heap ballooning, event-loop starvation, and OOM terminations caused by fast upstream generators paired with slow network consumers. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Unbounded Async Generator Consumption and Zero-Backpressure Task Spawning on Multiplexed SSE/Streaming Endpoints Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftUnbounded Async Generator Consumption and Zero-Backpressure Task Spawning on Multiplexed SSE/Streaming EndpointsCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS enforce bounded buffer sizes on `asyncio.Queue` (e.g., `maxsize=32` to `maxsize=128`) when piping upstream messages to `StreamingResponse` or SSE streams.

Engineers MUST ALWAYS enforce bounded buffer sizes on `asyncio.Queue` (e.g., `maxsize=32` to `maxsize=128`) when piping upstream messages to `StreamingResponse` or SSE streams.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST NOT spawn detached `asyncio.create_task` calls per incoming event or client chunk without passing through an explicit concurrency semaphore and bounded memory pool.

Engineers MUST NOT spawn detached `asyncio.create_task` calls per incoming event or client chunk without passing through an explicit concurrency semaphore and bounded memory pool.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Engineers MUST verify client connectivity status before and during heavy stream yields using `await request.is_disconnected()` to terminate abandoned upstream processing immediately.

Engineers MUST verify client connectivity status before and during heavy stream yields using `await request.is_disconnected()` to terminate abandoned upstream processing immediately.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Streaming generators MUST employ cooperative yields using `await asyncio.sleep(0)` or explicitly await socket write availability to prevent monolithic CPU bursts from starving the single-threaded event loop.

Streaming generators MUST employ cooperative yields using `await asyncio.sleep(0)` or explicitly await socket write availability to prevent monolithic CPU bursts from starving the single-threaded event loop.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Engineers MUST configure Uvicorn worker limits (`--limit-concurrency`, `--timeout-keep-alive`) and apply global admission control (e.g., token-bucket or semaphore middleware) to prevent multiplexed stream descriptor exhaustion.

Engineers MUST configure Uvicorn worker limits (`--limit-concurrency`, `--timeout-keep-alive`) and apply global admission control (e.g., token-bucket or semaphore middleware) to prevent multiplexed stream descriptor exhaustion.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is FastAPI Uvicorn Multiplexed Stream Backpressure Guardrail critical for AI coding assistants?

Enforces strict producer-consumer backpressure mechanisms and bounded concurrency queues for HTTP/2 multiplexed streams and Server-Sent Events (SSE) in FastAPI/Uvicorn deployments. Prevents unconstrained heap ballooning, event-loop starvation, and OOM terminations caused by fast upstream generators paired with slow network consumers. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Unbounded Async Generator Consumption and Zero-Backpressure Task Spawning on Multiplexed SSE/Streaming Endpoints) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

FastAPI