This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: axum-tower-cancellation-safety-drain

Axum 0.8 Tower Async Cancellation Safety & Graceful Drain Standard

Enforces asynchronous cancellation safety and deterministic graceful drain semantics across Axum 0.8 and Tower service layers. Eliminates dropped in-flight HTTP/3 QUIC streams and dangling database transactions during Kubernetes rolling updates by decoupling transactional side effects from raw client drop lifecycles.

Prohibited Anti-Pattern: Dangling Database Transactions and Abrupt QUIC Stream Termination via Unsafe tokio::select! in Axum Handlers

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Axum 0.8 Tower Async Cancellation Safety & Graceful Drain Standard - Enforces asynchronous cancellation safety and deterministic graceful drain semantics across Axum 0.8 and Tower service layers. Eliminates dropped in-flight HTTP/3 QUIC streams and dangling database transactions during Kubernetes rolling updates by decoupling transactional side effects from raw client drop lifecycles.
globs: src/**/*.rs, crates/**/*.rs
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/axum-tower-cancellation-safety-drain"
---

# Axum 0.8 Tower Async Cancellation Safety & Graceful Drain Standard

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Dangling Database Transactions and Abrupt QUIC Stream Termination via Unsafe tokio::select! in Axum Handlers

## System Constraints
You are a Principal Rust Distributed Systems Architect enforcing Axum 0.8 and Tower async cancellation safety and Kubernetes graceful draining. You must ensure all handlers maintain cancellation safety during sudden client disconnects and SIGTERM events. Reject any pattern where asynchronous database transactions or critical state modifications are executed across cancellation boundaries without non-cancellable worker decoupling or explicit CancellationToken coordination.

## Strict Guidelines
- Engineers MUST ALWAYS isolate state-mutating database transactions into decoupled tokio::spawn tasks or guarded transactional units when using tokio::select! or timeout wrappers.
- Engineers MUST NOT drop raw Axum request futures while holding open, uncommitted sqlx::Transaction or deadpool transactions without an explicit rollback or completion guarantee.
- Services MUST wire axum::serve with .with_graceful_shutdown() bound to tokio::signal listening for SIGINT and SIGTERM with a coordinated tokio_util::sync::CancellationToken.
- Components NEVER immediately abort active Tower layers during shutdown; they must propagate drain signals allowing existing HTTP/1.1, HTTP/2, and HTTP/3 QUIC connections to complete their active stream frames.
- Code SHOULD utilize tokio_util::sync::DropGuard or RAII transaction rollbacks to guarantee connection pool recycling and deterministic cleanup on client hang-ups.

## Bad vs Good Implementations
### Cancellation Unsafe Handler vs Decoupled Spawn with Token-Guarded Drain

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: If the client closes the HTTP connection or QUIC stream drops during the sleep, the future is dropped immediately. The transaction drops without a deterministic rollback log, and concurrent non-transactional downstream tasks leave dangling state.
```rust
use axum::{extract::State, Json, response::IntoResponse};
use sqlx::PgPool;
use serde::Deserialize;

#[derive(Deserialize)]
pub struct OrderPayload { pub id: i64, pub amount: i64 }

pub async fn create_order(
    State(pool): State<PgPool>,
    Json(payload): Json<OrderPayload>,
) -> impl IntoResponse {
    // ANTI-PATTERN: If the HTTP/3 stream cancels or a timeout future aborts here,
    // execution stops abruptly mid-flight. sqlx drops the transaction guard,
    // but external RPCs or secondary writes cause data inconsistency.
    let mut tx = pool.begin().await.unwrap();
    
    sqlx::query!("INSERT INTO orders (id, amount) VALUES ($1, $2)", payload.id, payload.amount)
        .execute(&mut *tx)
        .await
        .unwrap();

    // Simulated race condition: Client disconnect aborts here
    tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;

    tx.commit().await.unwrap();
    "Order Placed"
}
```

#### Production Standard (Correct)
> **Standard**: Critical writes are isolated from direct cancellation on the client socket. In-flight jobs observe server-side SIGTERM drain events via CancellationToken and perform atomic rollback rather than abrupt execution halting.
```rust
use axum::{extract::State, http::StatusCode, response::IntoResponse, Json};
use sqlx::PgPool;
use serde::Deserialize;
use tokio_util::sync::CancellationToken;
use std::sync::Arc;

#[derive(Clone)]
pub struct AppState {
    pub pool: PgPool,
    pub drain_token: CancellationToken,
}

#[derive(Deserialize)]
pub struct OrderPayload { pub id: i64, pub amount: i64 }

pub async fn create_order(
    State(state): State<Arc<AppState>>,
    Json(payload): Json<OrderPayload>,
) -> Result<impl IntoResponse, StatusCode> {
    let pool = state.pool.clone();
    
    // INVARIANT: Spawn critical multi-step transactional logic detached from
    // direct client cancel, using CancellationToken to respect server draining.
    let drain_token = state.drain_token.clone();
    let handle = tokio::spawn(async move {
        let mut tx = pool.begin().await.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
        
        sqlx::query!("INSERT INTO orders (id, amount) VALUES ($1, $2)", payload.id, payload.amount)
            .execute(&mut *tx)
            .await
            .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

        if drain_token.is_cancelled() {
            let _ = tx.rollback().await;
            return Err(StatusCode::SERVICE_UNAVAILABLE);
        }

        tx.commit().await.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
        Ok(())
    });

    handle.await.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
        .map(|_| (StatusCode::CREATED, "Order Placed"))
}
```

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 Tower Async Cancellation Safety & Graceful Drain Standard

Axum 0.8 Tower Async Cancellation Safety & Graceful Drain Standard defines an industrial-grade behavioral standard for backend engineering. Enforces asynchronous cancellation safety and deterministic graceful drain semantics across Axum 0.8 and Tower service layers. Eliminates dropped in-flight HTTP/3 QUIC streams and dangling database transactions during Kubernetes rolling updates by decoupling transactional side effects from raw client drop lifecycles. 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: Dangling Database Transactions and Abrupt QUIC Stream Termination via Unsafe tokio::select! in Axum Handlers 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 DriftDangling Database Transactions and Abrupt QUIC Stream Termination via Unsafe tokio::select! in Axum HandlersCritical
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 isolate state-mutating database transactions into decoupled tokio

Engineers MUST ALWAYS isolate state-mutating database transactions into decoupled tokio::spawn tasks or guarded transactional units when using tokio::select! or timeout wrappers.

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 drop raw Axum request futures while holding open, uncommitted sqlx

Engineers MUST NOT drop raw Axum request futures while holding open, uncommitted sqlx::Transaction or deadpool transactions without an explicit rollback or completion guarantee.

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

Services MUST wire axum

Services MUST wire axum::serve with .with_graceful_shutdown() bound to tokio::signal listening for SIGINT and SIGTERM with a coordinated tokio_util::sync::CancellationToken.

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

Components NEVER immediately abort active Tower layers during shutdown

Components NEVER immediately abort active Tower layers during shutdown; they must propagate drain signals allowing existing HTTP/1.1, HTTP/2, and HTTP/3 QUIC connections to complete their active stream frames.

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

Code SHOULD utilize tokio_util

Code SHOULD utilize tokio_util::sync::DropGuard or RAII transaction rollbacks to guarantee connection pool recycling and deterministic cleanup on client hang-ups.

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 Tower Async Cancellation Safety & Graceful Drain Standard critical for AI coding assistants?

Enforces asynchronous cancellation safety and deterministic graceful drain semantics across Axum 0.8 and Tower service layers. Eliminates dropped in-flight HTTP/3 QUIC streams and dangling database transactions during Kubernetes rolling updates by decoupling transactional side effects from raw client drop lifecycles. 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 (Dangling Database Transactions and Abrupt QUIC Stream Termination via Unsafe tokio::select! in Axum Handlers) 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