This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: axum-08-backpressure-sse-drain-standard

Axum 0.8 Zero-Allocation Backpressure & SSE Connection Drain Standard

Mandates asynchronous stream cancellation invariants, bounded backpressure pipelines, and zero-allocation socket teardowns for Server-Sent Events (SSE) in Axum 0.8. Eliminates heap fragmentation and OS socket starvation by guaranteeing task drop semantics propagate upstream during client disconnection cascades.

Prohibited Anti-Pattern: Unbounded Channel Buffering and Detached Producer Tasks During High-Concurrency SSE Disconnects

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Axum 0.8 Zero-Allocation Backpressure & SSE Connection Drain Standard - Mandates asynchronous stream cancellation invariants, bounded backpressure pipelines, and zero-allocation socket teardowns for Server-Sent Events (SSE) in Axum 0.8. Eliminates heap fragmentation and OS socket starvation by guaranteeing task drop semantics propagate upstream during client disconnection cascades.
globs: src/**/*.rs, crates/**/*.rs
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/axum-08-backpressure-sse-drain-standard"
---

# Axum 0.8 Zero-Allocation Backpressure & SSE Connection Drain Standard

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Unbounded Channel Buffering and Detached Producer Tasks During High-Concurrency SSE Disconnects

## System Constraints
You are a Principal Systems Engineer enforcing the Axum 0.8 Strict Zero-Allocation Backpressure & SSE Drain Standard. Mandate explicit backpressure bounds, immediate socket release upon client drops, and strict zero-allocation stream guarantees across all streaming Axum routes.

## Strict Guidelines
- Engineers MUST ALWAYS bound streaming channel depths using explicit capacity limits (e.g., `tokio::sync::mpsc::channel(capacity)`) rather than unbounded variants (`unbounded_channel`).
- Engineers MUST NOT decouple long-running producer tasks using unmonitored `tokio::spawn` calls without attaching cancellation triggers tied directly to the HTTP request drop lifecycle.
- Code SHOULD utilize `tokio_util::sync::CancellationToken` or RAII drop guards to abruptly terminate upstream message ingestion as soon as Axum drops the client response stream.
- Services MUST configure zero-allocation SSE keep-alive intervals via `axum::response::sse::KeepAlive::new()` using static byte slices rather than dynamically allocated string payloads.
- Components NEVER re-allocate or clone formatted message strings per active subscriber; stream payloads MUST share immutable reference-counted buffers (`bytes::Bytes` or `Arc<str>`).

## Bad vs Good Implementations
### SSE Connection Handler with Bounded Backpressure and Drop Propagation

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Uses an unbounded channel that leads to unbounded memory growth if the client is slow. The background task is detached without cancellation synchronization, causing it to retain memory and CPU ticks long after the client has disconnected.
```rust
use axum::{response::sse::{Event, Sse}, extract::State};
use tokio::sync::mpsc;
use tokio_stream::wrappers::UnboundedReceiverStream;
use std::{convert::Infallible, time::Duration};

pub async fn bad_sse_handler(
    State(broadcaster): State<Broadcaster>,
) -> Sse<UnboundedReceiverStream<Result<Event, Infallible>>> {
    // ANTI-PATTERN: Unbounded channel creates memory leaks when client throttles
    let (tx, rx) = mpsc::unbounded_channel();

    // ANTI-PATTERN: Detached task without cancellation link; survives client disconnect
    tokio::spawn(async move {
        loop {
            tokio::time::sleep(Duration::from_millis(500)).await;
            // Allocates new strings repeatedly per event
            let msg = format!("{{\"timestamp\": {}}}", std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_millis());
            if tx.send(Ok(Event::default().data(msg))).is_err() {
                break;
            }
        }
    });

    Sse::new(UnboundedReceiverStream::new(rx))
}
```

#### Production Standard (Correct)
> **Standard**: Implements an explicit bounded capacity channel (64 slots), zero-allocation byte buffers (`Bytes::from_static`), an RAII drop guard tied to a `CancellationToken` that abruptly terminates the producer task when Axum detects the peer disconnect, and static keep-alive framing.
```rust
use axum::{
    extract::State,
    response::sse::{Event, KeepAlive, Sse},
};
use bytes::Bytes;
use futures_util::stream::Stream;
use std::{convert::Infallible, sync::Arc, time::Duration};
use tokio::sync::mpsc;
use tokio_stream::wrappers::ReceiverStream;
use tokio_util::sync::CancellationToken;

const SSE_BUFFER_BOUND: usize = 64;

pub async fn good_sse_handler(
    State(app_state): State<Arc<AppState>>,
) -> Sse<impl Stream<Item = Result<Event, Infallible>> + Send + 'static> {
    let (tx, rx) = mpsc::channel::<Result<Event, Infallible>>(SSE_BUFFER_BOUND);
    let cancel_token = CancellationToken::new();
    let child_token = cancel_token.child_token();

    tokio::spawn(async move {
        let mut ticker = tokio::time::interval(Duration::from_millis(500));
        loop {
            tokio::select! {
                _ = child_token.cancelled() => {
                    break;
                }
                _ = ticker.tick() => {
                    // Zero-copy reference-counted byte buffer
                    let payload = Bytes::from_static(b"{\"status\":\"alive\"}");
                    let event = Event::default().data(payload);
                    if tx.send(Ok(event)).await.is_err() {
                        // Receiver dropped; socket connection severed
                        break;
                    }
                }
            }
        }
    });

    let drop_guard_stream = ReceiverStream::new(rx);
    
    // Sse wrapper reclaims socket and triggers cancel_token via RAII Guard on client drop
    Sse::new(DropGuard::new(drop_guard_stream, cancel_token))
        .keep_alive(
            KeepAlive::new()
                .interval(Duration::from_secs(15))
                .text("keep-alive-ping"),
        )
}

struct DropGuard<S> {
    inner: S,
    token: CancellationToken,
}

impl<S> DropGuard<S> {
    fn new(inner: S, token: CancellationToken) -> Self {
        Self { inner, token }
    }
}

impl<S: Stream + Unpin> Stream for DropGuard<S> {
    type Item = S::Item;
    fn poll_next(
        mut self: std::pin::Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Option<Self::Item>> {
        std::pin::Pin::new(&mut self.inner).poll_next(cx)
    }
}

impl<S> Drop for DropGuard<S> {
    fn drop(&mut self) {
        self.token.cancel();
    }
}
```

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: Axum 0.8 Zero-Allocation Backpressure & SSE Connection Drain Standard

Axum 0.8 Zero-Allocation Backpressure & SSE Connection Drain Standard defines an industrial-grade behavioral standard for backend engineering. Mandates asynchronous stream cancellation invariants, bounded backpressure pipelines, and zero-allocation socket teardowns for Server-Sent Events (SSE) in Axum 0.8. Eliminates heap fragmentation and OS socket starvation by guaranteeing task drop semantics propagate upstream during client disconnection cascades. 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 Channel Buffering and Detached Producer Tasks During High-Concurrency SSE Disconnects 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 Channel Buffering and Detached Producer Tasks During High-Concurrency SSE DisconnectsCritical
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 bound streaming channel depths using explicit capacity limits (e.g., `tokio

Engineers MUST ALWAYS bound streaming channel depths using explicit capacity limits (e.g., `tokio::sync::mpsc::channel(capacity)`) rather than unbounded variants (`unbounded_channel`).

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 decouple long-running producer tasks using unmonitored `tokio

Engineers MUST NOT decouple long-running producer tasks using unmonitored `tokio::spawn` calls without attaching cancellation triggers tied directly to the HTTP request drop lifecycle.

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

Code SHOULD utilize `tokio_util

Code SHOULD utilize `tokio_util::sync::CancellationToken` or RAII drop guards to abruptly terminate upstream message ingestion as soon as Axum drops the client response stream.

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

Services MUST configure zero-allocation SSE keep-alive intervals via `axum

Services MUST configure zero-allocation SSE keep-alive intervals via `axum::response::sse::KeepAlive::new()` using static byte slices rather than dynamically allocated string payloads.

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

Components NEVER re-allocate or clone formatted message strings per active subscriber

Components NEVER re-allocate or clone formatted message strings per active subscriber; stream payloads MUST share immutable reference-counted buffers (`bytes::Bytes` or `Arc<str>`).

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 Axum 0.8 Zero-Allocation Backpressure & SSE Connection Drain Standard critical for AI coding assistants?

Mandates asynchronous stream cancellation invariants, bounded backpressure pipelines, and zero-allocation socket teardowns for Server-Sent Events (SSE) in Axum 0.8. Eliminates heap fragmentation and OS socket starvation by guaranteeing task drop semantics propagate upstream during client disconnection cascades. 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 Channel Buffering and Detached Producer Tasks During High-Concurrency SSE Disconnects) 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

Axum