This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: fastapi-free-threaded-cpython-313-native-thread-isolation

FastAPI Free-Threaded CPython 3.13 Native Thread Isolation Standard

Enforces strict native memory isolation and thread-safe shared state primitives for high-throughput ASGI applications running on GIL-disabled CPython 3.13 (PEP 703). Prevents race conditions, data corruption, and GC allocator thrashing when handling concurrent ASGI requests across shared native OS threads without process boundaries.

Prohibited Anti-Pattern: Global Mutability and Thread-Unsafe In-Memory State in GIL-Free ASGI Runtimes

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: FastAPI Free-Threaded CPython 3.13 Native Thread Isolation Standard - Enforces strict native memory isolation and thread-safe shared state primitives for high-throughput ASGI applications running on GIL-disabled CPython 3.13 (PEP 703). Prevents race conditions, data corruption, and GC allocator thrashing when handling concurrent ASGI requests across shared native OS threads without process boundaries.
globs: app/**/*.py, src/**/*.py, api/**/*.py, services/**/*.py
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/fastapi-free-threaded-cpython-313-native-thread-isolation"
---

# FastAPI Free-Threaded CPython 3.13 Native Thread Isolation Standard

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Global Mutability and Thread-Unsafe In-Memory State in GIL-Free ASGI Runtimes

## System Constraints
You are a Principal Engineer enforcing FastAPI Free-Threaded CPython 3.13 Native Thread Isolation. Under CPython 3.13t (free-threaded mode), the Global Interpreter Lock (GIL) is disabled, meaning native Python opcodes and object mutations execute concurrently across OS threads without atomic protection. You must eliminate all unguarded module-level mutable collections, prohibit non-reentrant global state modifications, enforce context-local state isolation using `contextvars`, and mandate atomic concurrency primitives (e.g., Reader-Writer locks, `threading.Lock`) around any necessary cross-thread state. Ensure all C-extensions and third-party bindings declare Py_MOD_GIL_NOT_USED compatibility.

## Strict Guidelines
- Engineers MUST ALWAYS isolate request-scoped state using `contextvars.ContextVar` instead of module-level variables, thread-local storage (`threading.local`), or mutable dependency objects.
- Engineers MUST NOT mutate raw Python built-in collections (dict, list, set) concurrently across threads without explicit synchronization via `threading.Lock` or lock-free immutable copy-on-write patterns.
- Code MUST initialize shared singletons (e.g., database connection pools, HTTP client sessions, configuration maps) during lifespan startup before concurrent native worker threads spawn.
- Services MUST verify that all native extension dependencies support free-threading by checking `sys._is_gil_enabled()` during runtime initialization and logging invariant telemetry.
- Components NEVER store mutable business state, active transaction references, or request-specific caches inside singleton dependency classes resolved through `fastapi.Depends`.

## Bad vs Good Implementations
### Module-Level Mutable State vs. Thread-Safe Context Isolation

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Under CPython 3.13t without the GIL, Python dictionary mutations are not atomic. Multiple ASGI worker threads will interleave execution during `get` and item assignment, causing lost updates, corrupted dict structures, and nondeterministic crashes without worker-process boundary isolation.
```python
from fastapi import FastAPI, Request

app = FastAPI()

# CRITICAL BUG: Under CPython 3.13 free-threaded mode (PYTHON_GIL=0),
# concurrent native OS threads running requests will concurrently mutate
# this raw dictionary, causing race conditions and internal memory corruption.
request_metrics: dict[str, int] = {}

@app.post("/process")
async def process_payload(request: Request) -> dict[str, str]:
    client_ip = request.client.host if request.client else "unknown"
    # Non-atomic read-modify-write without GIL protection
    current_count = request_metrics.get(client_ip, 0)
    request_metrics[client_ip] = current_count + 1
    return {"status": "processed", "hits": str(request_metrics[client_ip])}
```

#### Production Standard (Correct)
> **Standard**: Protects concurrent shared state with an explicit `threading.Lock()` barrier, ensuring atomic mutations across OS native threads in a free-threaded runtime. Request-isolated values are kept in reentrant `contextvars` contexts.
```python
import contextvars
import threading
from collections import defaultdict
from fastapi import FastAPI, Request

app = FastAPI()

class SynchronizedMetricsRegistry:
    def __init__(self) -> None:
        self._lock = threading.Lock()
        self._metrics: dict[str, int] = defaultdict(int)

    def increment(self, key: str) -> int:
        with self._lock:
            self._metrics[key] += 1
            return self._metrics[key]

# Safe singleton with explicit OS thread synchronization
registry = SynchronizedMetricsRegistry()
request_id_ctx: contextvars.ContextVar[str] = contextvars.ContextVar("request_id", default="")

@app.post("/process")
async def process_payload(request: Request) -> dict[str, str]:
    client_ip = request.client.host if request.client else "unknown"
    count = registry.increment(client_ip)
    return {"status": "processed", "hits": str(count)}
```

### Stateful FastAPI Dependency vs. Immutable Factory with Lifespan Registration

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Reusing an un-synchronized mutable dependency instance across ASGI requests under free-threaded CPython leads to unsynchronized list appends across threads, causing race conditions in memory reallocation and internal slice tracking.
```python
from fastapi import FastAPI, Depends

app = FastAPI()

class UnsafeSessionRegistry:
    def __init__(self) -> None:
        # Stored state shared across calls via dependency injection
        self.active_sessions: list[str] = []

    def register(self, session_id: str) -> None:
        # Multiple native threads executing this concurrently will corrupt internal list pointers
        self.active_sessions.append(session_id)

singleton_registry = UnsafeSessionRegistry()

@app.post("/login/{session_id}")
def login(session_id: str, reg: UnsafeSessionRegistry = Depends(lambda: singleton_registry)) -> dict[str, int]:
    reg.register(session_id)
    return {"active_count": len(reg.active_sessions)}
```

#### Production Standard (Correct)
> **Standard**: Initializes thread-safe singletons within FastAPI's lifespan context before thread execution begins, validates the runtime GIL state via `sys._is_gil_enabled()`, and enforces atomic mutations with `threading.Lock` within a dedicated registry class.
```python
from contextlib import asynccontextmanager
from dataclasses import dataclass
import sys
import threading
from typing import AsyncGenerator
from fastapi import FastAPI, Depends

@dataclass(frozen=True, slots=True)
class EngineRuntimeConfig:
    is_gil_disabled: bool

class SafeSessionRegistry:
    def __init__(self) -> None:
        self._lock = threading.Lock()
        self._sessions: set[str] = set()

    def register(self, session_id: str) -> int:
        with self._lock:
            self._sessions.add(session_id)
            return len(self._sessions)

@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
    # Verify free-threaded runtime status during bootstrap
    gil_enabled = getattr(sys, "_is_gil_enabled", lambda: True)()
    app.state.runtime_config = EngineRuntimeConfig(is_gil_disabled=not gil_enabled)
    app.state.session_registry = SafeSessionRegistry()
    yield

app = FastAPI(lifespan=lifespan)

def get_session_registry() -> SafeSessionRegistry:
    return app.state.session_registry

@app.post("/login/{session_id}")
def login(session_id: str, reg: SafeSessionRegistry = Depends(get_session_registry)) -> dict[str, int]:
    count = reg.register(session_id)
    return {"active_count": count}
```

Recommended MCP Servers (mcp-serverlist.com)

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

Architectural Specification & Invariant Rationale

Architectural Invariant Design: FastAPI Free-Threaded CPython 3.13 Native Thread Isolation Standard

FastAPI Free-Threaded CPython 3.13 Native Thread Isolation Standard defines an industrial-grade behavioral standard for backend engineering. Enforces strict native memory isolation and thread-safe shared state primitives for high-throughput ASGI applications running on GIL-disabled CPython 3.13 (PEP 703). Prevents race conditions, data corruption, and GC allocator thrashing when handling concurrent ASGI requests across shared native OS threads without process boundaries. 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: Global Mutability and Thread-Unsafe In-Memory State in GIL-Free ASGI Runtimes 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 DriftGlobal Mutability and Thread-Unsafe In-Memory State in GIL-Free ASGI RuntimesCritical
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 request-scoped state using `contextvars.ContextVar` instead of module-level variables, thread-local storage (`threading.local`), or mutable dependency objects.

Engineers MUST ALWAYS isolate request-scoped state using `contextvars.ContextVar` instead of module-level variables, thread-local storage (`threading.local`), or mutable dependency objects.

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 mutate raw Python built-in collections (dict, list, set) concurrently across threads without explicit synchronization via `threading.Lock` or lock-free immutable copy-on-write patterns.

Engineers MUST NOT mutate raw Python built-in collections (dict, list, set) concurrently across threads without explicit synchronization via `threading.Lock` or lock-free immutable copy-on-write patterns.

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 MUST initialize shared singletons (e.g., database connection pools, HTTP client sessions, configuration maps) during lifespan startup before concurrent native worker threads spawn.

Code MUST initialize shared singletons (e.g., database connection pools, HTTP client sessions, configuration maps) during lifespan startup before concurrent native worker threads spawn.

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 verify that all native extension dependencies support free-threading by checking `sys._is_gil_enabled()` during runtime initialization and logging invariant telemetry.

Services MUST verify that all native extension dependencies support free-threading by checking `sys._is_gil_enabled()` during runtime initialization and logging invariant telemetry.

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 store mutable business state, active transaction references, or request-specific caches inside singleton dependency classes resolved through `fastapi.Depends`.

Components NEVER store mutable business state, active transaction references, or request-specific caches inside singleton dependency classes resolved through `fastapi.Depends`.

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 Free-Threaded CPython 3.13 Native Thread Isolation Standard critical for AI coding assistants?

Enforces strict native memory isolation and thread-safe shared state primitives for high-throughput ASGI applications running on GIL-disabled CPython 3.13 (PEP 703). Prevents race conditions, data corruption, and GC allocator thrashing when handling concurrent ASGI requests across shared native OS threads without process boundaries. 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 (Global Mutability and Thread-Unsafe In-Memory State in GIL-Free ASGI Runtimes) 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