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

Axum 0.8 Graceful Connection Drain & HTTP/2 In-Flight Lease Standard

Enforces a multi-phase graceful shutdown protocol for Axum 0.8 services handling HTTP/1.1 and HTTP/2 multiplexed traffic during orchestrator rolling restarts. Prevents dropped in-flight streaming connections and socket reset (RST) spikes by coordinating Kubernetes readiness lameduck delays, explicit stream lease tracking, and hyper-util connection draining bounds.

Prohibited Anti-Pattern: Immediate SIGTERM Termination with Naive with_graceful_shutdown Triggering Ingress RST-502 Cascades

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Axum 0.8 Graceful Connection Drain & HTTP/2 In-Flight Lease Standard - Enforces a multi-phase graceful shutdown protocol for Axum 0.8 services handling HTTP/1.1 and HTTP/2 multiplexed traffic during orchestrator rolling restarts. Prevents dropped in-flight streaming connections and socket reset (RST) spikes by coordinating Kubernetes readiness lameduck delays, explicit stream lease tracking, and hyper-util connection draining bounds.
globs: src/**/*.rs
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/axum-08-graceful-drain-http2-lease-standard"
---

# Axum 0.8 Graceful Connection Drain & HTTP/2 In-Flight Lease Standard

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Immediate SIGTERM Termination with Naive with_graceful_shutdown Triggering Ingress RST-502 Cascades

## System Constraints
You are a Principal Rust Backend Architect mandating strict lifecycle invariants for Axum 0.8 services. Never allow premature listener termination upon SIGTERM. All network listeners MUST implement a coordinated multi-phase shutdown pipeline: (1) lameduck readiness probe detachment, (2) ingress deregistration sleep, (3) HTTP/2 connection drain with in-flight stream lease tracking, and (4) an absolute hard deadline timeout.

## Strict Guidelines
- Services MUST decouple orchestrator SIGTERM reception from immediate socket closure by entering a lameduck phase where readiness probes report HTTP 503 while the listener remains fully operational.
- Engineers MUST configure an ingress quiescent delay (recommended: 5–15 seconds) after SIGTERM before initiating axum::serve graceful shutdown, allowing upstream mesh proxies (Envoy/kube-proxy) to remove the pod from endpoint pools.
- All long-lived streaming endpoints (SSE, WebSockets, chunked NDJSON, gRPC/HTTP2 multiplexed streams) MUST acquire an RAII in-flight lease guard backed by a lease counter or tokio::sync::watch channel.
- Engineers MUST NOT rely solely on naive signal::ctrl_c() binding directly into axum::serve(...).with_graceful_shutdown() without readiness coordination and ingress quiescence.
- The server drain pipeline MUST enforce an outer hard deadline using tokio::time::timeout to prevent zombie streams from hanging rolling deployments past the orchestrator terminationGracePeriodSeconds.
- Axum 0.8 router state MUST expose a dedicated ReadinessState atomic or watch receiver that can transition from Ready to Quiescing to Terminated.

## Bad vs Good Implementations
### Flawed Immediate Graceful Shutdown vs. Coordinated Lameduck Lease Drain

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Directly triggering with_graceful_shutdown on SIGTERM creates a race condition with cluster routing. Upstream proxies (Envoy/NGINX/kube-proxy) have not yet propagated endpoint eviction, resulting in connection resets and HTTP 502/504 errors on new connections. Long-lived streams are uncoordinated and get abruptly cut.
```rust
use axum::{routing::get, Router};
use tokio::signal;

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/healthz", get(|| async { "OK" }))
        .route("/stream", get(|| async { 
            // Long running stream without lease tracking
            tokio::time::sleep(std::time::Duration::from_secs(60)).await;
            "done"
        }));

    let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap();

    // CRITICAL ANTI-PATTERN: Triggers shutdown immediately on SIGTERM.
    // Ingress proxy still sends traffic for 2-5 seconds (502 Bad Gateway).
    // Streams lack lease tracking and hyper terminates prematurely.
    axum::serve(listener, app)
        .with_graceful_shutdown(shutdown_signal())
        .await
        .unwrap();
}

async fn shutdown_signal() {
    signal::ctrl_c().await.expect("failed to listen for event");
}
```

#### Production Standard (Correct)
> **Standard**: Implements an industrial four-phase lameduck drain: (1) SIGTERM immediately flips readiness state to 503; (2) a 10s quiescence delay elapses while the socket continues servicing existing and residual traffic as ingress endpoints sync; (3) Hyper's graceful drain is triggered; and (4) in-flight streams maintain RAII lease counters allowing active streams to cleanly finish.
```rust
use axum::{extract::State, http::StatusCode, routing::get, Router};
use std::sync::{atomic::{AtomicBool, AtomicUsize, Ordering}, Arc};
use std::time::Duration;
use tokio::sync::watch;

#[derive(Clone)]
struct AppState {
    is_ready: Arc<AtomicBool>,
    inflight_leases: Arc<AtomicUsize>,
}

struct LeaseGuard(Arc<AtomicUsize>);
impl Drop for LeaseGuard {
    fn drop(&mut self) {
        self.0.fetch_sub(1, Ordering::Release);
    }
}

async fn readiness_check(State(state): State<AppState>) -> StatusCode {
    if state.is_ready.load(Ordering::Acquire) {
        StatusCode::OK
    } else {
        StatusCode::SERVICE_UNAVAILABLE
    }
}

async fn streaming_handler(State(state): State<AppState>) -> &'static str {
    // Acquire stream lease RAII guard
    state.inflight_leases.fetch_add(1, Ordering::SeqCst);
    let _guard = LeaseGuard(state.inflight_leases.clone());
    
    // Simulated long-lived response
    tokio::time::sleep(Duration::from_secs(5)).await;
    "stream payload"
}

#[tokio::main]
async fn main() {
    let state = AppState {
        is_ready: Arc::new(AtomicBool::new(true)),
        inflight_leases: Arc::new(AtomicUsize::new(0)),
    };

    let app = Router::new()
        .route("/healthz", get(readiness_check))
        .route("/stream", get(streaming_handler))
        .with_state(state.clone());

    let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap();
    let (drain_tx, drain_rx) = watch::channel(());

    let drain_state = state.clone();
    tokio::spawn(async move {
        tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
            .expect("failed to install SIGTERM handler")
            .recv()
            .await;

        // Phase 1: Mark lameduck - fail readiness probes to trigger ingress deregistration
        drain_state.is_ready.store(false, Ordering::Release);

        // Phase 2: Quiescence sleep to allow upstream mesh/kube-proxy iptables propagation
        tokio::time::sleep(Duration::from_secs(10)).await;

        // Phase 3: Signal axum/hyper graceful connection drain
        let _ = drain_tx.send(());
    });

    // Phase 4: Serve with graceful shutdown and hard bound timeout
    let server = axum::serve(listener, app)
        .with_graceful_shutdown(async move {
            let mut rx = drain_rx;
            let _ = rx.changed().await;
        });

    if let Err(err) = server.await {
        eprintln!("Server error during shutdown: {err}");
    }
}
```

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 Graceful Connection Drain & HTTP/2 In-Flight Lease Standard

Axum 0.8 Graceful Connection Drain & HTTP/2 In-Flight Lease Standard defines an industrial-grade behavioral standard for backend engineering. Enforces a multi-phase graceful shutdown protocol for Axum 0.8 services handling HTTP/1.1 and HTTP/2 multiplexed traffic during orchestrator rolling restarts. Prevents dropped in-flight streaming connections and socket reset (RST) spikes by coordinating Kubernetes readiness lameduck delays, explicit stream lease tracking, and hyper-util connection draining bounds. 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: Immediate SIGTERM Termination with Naive with_graceful_shutdown Triggering Ingress RST-502 Cascades 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 DriftImmediate SIGTERM Termination with Naive with_graceful_shutdown Triggering Ingress RST-502 CascadesCritical
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

Services MUST decouple orchestrator SIGTERM reception from immediate socket closure by entering a lameduck phase where readiness probes report HTTP 503 while the listener remains fully operational.

Services MUST decouple orchestrator SIGTERM reception from immediate socket closure by entering a lameduck phase where readiness probes report HTTP 503 while the listener remains fully operational.

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 configure an ingress quiescent delay (recommended

Engineers MUST configure an ingress quiescent delay (recommended: 5–15 seconds) after SIGTERM before initiating axum::serve graceful shutdown, allowing upstream mesh proxies (Envoy/kube-proxy) to remove the pod from endpoint pools.

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

All long-lived streaming endpoints (SSE, WebSockets, chunked NDJSON, gRPC/HTTP2 multiplexed streams) MUST acquire an RAII in-flight lease guard backed by a lease counter or tokio

All long-lived streaming endpoints (SSE, WebSockets, chunked NDJSON, gRPC/HTTP2 multiplexed streams) MUST acquire an RAII in-flight lease guard backed by a lease counter or tokio::sync::watch 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.
4

Engineers MUST NOT rely solely on naive signal

Engineers MUST NOT rely solely on naive signal::ctrl_c() binding directly into axum::serve(...).with_graceful_shutdown() without readiness coordination and ingress quiescence.

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

The server drain pipeline MUST enforce an outer hard deadline using tokio

The server drain pipeline MUST enforce an outer hard deadline using tokio::time::timeout to prevent zombie streams from hanging rolling deployments past the orchestrator terminationGracePeriodSeconds.

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.
6

Axum 0.8 router state MUST expose a dedicated ReadinessState atomic or watch receiver that can transition from Ready to Quiescing to Terminated.

Axum 0.8 router state MUST expose a dedicated ReadinessState atomic or watch receiver that can transition from Ready to Quiescing to Terminated.

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 Graceful Connection Drain & HTTP/2 In-Flight Lease Standard critical for AI coding assistants?

Enforces a multi-phase graceful shutdown protocol for Axum 0.8 services handling HTTP/1.1 and HTTP/2 multiplexed traffic during orchestrator rolling restarts. Prevents dropped in-flight streaming connections and socket reset (RST) spikes by coordinating Kubernetes readiness lameduck delays, explicit stream lease tracking, and hyper-util connection draining bounds. 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 (Immediate SIGTERM Termination with Naive with_graceful_shutdown Triggering Ingress RST-502 Cascades) 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