This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: axum-bounded-zero-copy-streaming-multipart-boundary

Axum 0.8 Bounded Zero-Copy Streaming Multipart Boundary

Protects Tokio async runtimes from memory exhaustion (OOM) and Slowloris-style degradation by enforcing bounded, zero-copy streaming multipart ingestion. Replaces unbounded memory accumulation (e.g., to_bytes, Vec<u8> collection) with fixed chunk backpressure, explicit per-field byte limits, and strict read timeouts.

Prohibited Anti-Pattern: Unbounded In-Memory Multipart Buffering and Unconstrained Chunk Allocation

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Axum 0.8 Bounded Zero-Copy Streaming Multipart Boundary - Protects Tokio async runtimes from memory exhaustion (OOM) and Slowloris-style degradation by enforcing bounded, zero-copy streaming multipart ingestion. Replaces unbounded memory accumulation (e.g., to_bytes, Vec<u8> collection) with fixed chunk backpressure, explicit per-field byte limits, and strict read timeouts.
globs: src/**/*.rs, crates/**/*.rs
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/axum-bounded-zero-copy-streaming-multipart-boundary"
---

# Axum 0.8 Bounded Zero-Copy Streaming Multipart Boundary

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Unbounded In-Memory Multipart Buffering and Unconstrained Chunk Allocation

## System Constraints
You are a Principal Rust Architect enforcing production invariants for Axum 0.8 high-throughput body ingestion. Mandate zero-copy stream processing via tokio::io::AsyncWriteExt, explicit limit middleware (DefaultBodyLimit::disable combined with per-field strict limits), and tokio::time::timeout wrapping every chunk poll to eliminate Slowloris and allocation exhaustion vulnerabilities.

## Strict Guidelines
- Engineers MUST ALWAYS process `axum::extract::Multipart` fields as a bounded `Stream` or by reading discrete `Bytes` chunks directly into an `AsyncWrite` destination (e.g., `tokio::fs::File`).
- Engineers MUST NOT call `field.bytes().await` or collect chunks into an unbounded `Vec<u8>` without an explicit compile-time or runtime capacity fence.
- Handlers MUST wrap individual stream chunk acquisitions (`field.chunk().await`) in `tokio::time::timeout` to abort connections stalling the Tokio runtime worker threads.
- Services MUST disable global monolithic buffers (`DefaultBodyLimit::disable()`) only when replacing them with strict per-field streaming counters that reject payloads exceeding the allocated threshold.
- Components NEVER hold intermediate raw chunk references across cancellation points unless zero-copy slices are borrowed directly from pinned memory buffers.

## Bad vs Good Implementations
### Unbounded Field Buffering vs. Bounded Zero-Copy Streaming Chunk Consumer

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Calling `field.bytes().await` allocates an unbounded buffer on the heap for the entire field size. If an attacker streams 5GB of data or concurrently opens multiple connections that stream slowly without terminating, the Tokio runtime runs out of memory or blocks workers, resulting in complete service denial (OOM/Slowloris).
```rust
use axum::{extract::Multipart, http::StatusCode, response::IntoResponse};

// VULNERABLE: Buffers entire upload into heap memory, triggering OOM on large payloads
// and vulnerable to Slowloris chunk delivery.
pub async fn upload_handler(mut multipart: Multipart) -> Result<impl IntoResponse, StatusCode> {
    while let Some(field) = multipart.next_field().await.map_err(|_| StatusCode::BAD_REQUEST)? {
        // Catastrophic: Loads entire field into an unbounded Vec<u8> in RAM
        let data = field.bytes().await.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
        tokio::fs::write("/tmp/uploaded_file.bin", &data)
            .await
            .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
    }
    Ok(StatusCode::OK)
}
```

#### Production Standard (Correct)
> **Standard**: Processes uploads in discrete, bounded chunks using `field.chunk()`. Enforces an explicit byte boundary check per chunk, bounds read intervals with `tokio::time::timeout` against Slowloris degradation, and flushes chunks directly to storage without unbounded in-memory collection.
```rust
use axum::{extract::Multipart, http::StatusCode, response::IntoResponse};
use tokio::{fs::File, io::AsyncWriteExt, time::{timeout, Duration}};

const MAX_FIELD_BYTES: usize = 100 * 1024 * 1024; // 100 MiB limit
const CHUNK_TIMEOUT: Duration = Duration::from_secs(10);

pub async fn upload_handler(mut multipart: Multipart) -> Result<impl IntoResponse, StatusCode> {
    while let Some(mut field) = multipart.next_field().await.map_err(|_| StatusCode::BAD_REQUEST)? {
        let mut file = File::create("/tmp/uploaded_file.bin").await.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
        let mut total_bytes = 0usize;

        // Zero-copy stream consumption with fixed bounds and timeouts
        loop {
            let chunk_opt = timeout(CHUNK_TIMEOUT, field.chunk())
                .await
                .map_err(|_| StatusCode::REQUEST_TIMEOUT)?
                .map_err(|_| StatusCode::BAD_REQUEST)?;

            match chunk_opt {
                Some(chunk) => {
                    total_bytes += chunk.len();
                    if total_bytes > MAX_FIELD_BYTES {
                        return Err(StatusCode::PAYLOAD_TOO_LARGE);
                    }
                    // Stream directly to disk/sink without intermediate reallocation
                    file.write_all(&chunk).await.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
                }
                None => break,
            }
        }
        file.flush().await.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
    }
    Ok(StatusCode::OK)
}
```

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 Bounded Zero-Copy Streaming Multipart Boundary

Axum 0.8 Bounded Zero-Copy Streaming Multipart Boundary defines an industrial-grade behavioral standard for backend engineering. Protects Tokio async runtimes from memory exhaustion (OOM) and Slowloris-style degradation by enforcing bounded, zero-copy streaming multipart ingestion. Replaces unbounded memory accumulation (e.g., to_bytes, Vec<u8> collection) with fixed chunk backpressure, explicit per-field byte limits, and strict read timeouts. 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 In-Memory Multipart Buffering and Unconstrained Chunk Allocation 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 In-Memory Multipart Buffering and Unconstrained Chunk AllocationCritical
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 process `axum

Engineers MUST ALWAYS process `axum::extract::Multipart` fields as a bounded `Stream` or by reading discrete `Bytes` chunks directly into an `AsyncWrite` destination (e.g., `tokio::fs::File`).

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 call `field.bytes().await` or collect chunks into an unbounded `Vec<u8>` without an explicit compile-time or runtime capacity fence.

Engineers MUST NOT call `field.bytes().await` or collect chunks into an unbounded `Vec<u8>` without an explicit compile-time or runtime capacity fence.

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

Handlers MUST wrap individual stream chunk acquisitions (`field.chunk().await`) in `tokio

Handlers MUST wrap individual stream chunk acquisitions (`field.chunk().await`) in `tokio::time::timeout` to abort connections stalling the Tokio runtime worker threads.

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 disable global monolithic buffers (`DefaultBodyLimit

Services MUST disable global monolithic buffers (`DefaultBodyLimit::disable()`) only when replacing them with strict per-field streaming counters that reject payloads exceeding the allocated threshold.

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 hold intermediate raw chunk references across cancellation points unless zero-copy slices are borrowed directly from pinned memory buffers.

Components NEVER hold intermediate raw chunk references across cancellation points unless zero-copy slices are borrowed directly from pinned memory buffers.

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 Bounded Zero-Copy Streaming Multipart Boundary critical for AI coding assistants?

Protects Tokio async runtimes from memory exhaustion (OOM) and Slowloris-style degradation by enforcing bounded, zero-copy streaming multipart ingestion. Replaces unbounded memory accumulation (e.g., to_bytes, Vec<u8> collection) with fixed chunk backpressure, explicit per-field byte limits, and strict read timeouts. 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 In-Memory Multipart Buffering and Unconstrained Chunk Allocation) 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