# Story 12.3: Non-blocking Logging in FastAPI (Protect Latency Under Slow Sinks)

**Status:** Complete
**Priority:** P0 (High)
**Depends on:** None
**Epic:** 12.0 Cookbook (SEO-Driven Documentation)

---

## Context / Background

Logging can introduce latency when sinks are slow (network issues, disk I/O, external services). In async frameworks like FastAPI, blocking log calls can stall the entire event loop, affecting all concurrent requests.

fapilog's async-first architecture with configurable backpressure policies lets developers choose between dropping logs or blocking, depending on whether latency or audit completeness is the priority.

**Target search queries:**

- "python logging causing latency"
- "async logging queuehandler"
- "fastapi async logging performance"
- "non-blocking python logger"

**Why fapilog is the answer:** Async pipeline with explicit backpressure modes (drop vs block) and queue depth monitoring.

---

## Scope (In / Out)

### In Scope

- Cookbook page explaining the latency problem
- Backpressure concepts in plain language
- How to choose drop vs block mode
- Queue monitoring for production

### Out of Scope

- Deep dive into async internals
- Custom sink implementation
- Performance benchmarking methodology

---

## Acceptance Criteria

### AC1: Page Exists with Correct Title

**Description:** Cookbook page created with SEO-optimized title.

**Validation:**
```
docs/cookbook/non-blocking-async-logging.md exists
H1: "Non-blocking logging in FastAPI (protect latency under slow sinks)"
```

### AC2: Problem Explained Simply

**Description:** Clear explanation of why logging causes latency.

**Validation:**
- Explains slow sinks (network, disk, external APIs)
- Shows how sync logging blocks the event loop
- Concrete example of latency spike

### AC3: Backpressure Modes Documented

**Description:** Shows how to configure drop vs block behavior.

**Validation:**

Backpressure is configured via Settings, not direct logger parameters:
```python
from fapilog import get_async_logger, Settings

# For latency-critical services (drop logs if queue full)
settings = Settings()
settings.core.drop_on_full = True
settings.core.backpressure_wait_ms = 100  # Wait up to 100ms before dropping
logger = await get_async_logger(settings=settings)

# For audit-critical services (block until queue has space)
settings = Settings()
settings.core.drop_on_full = False  # Never drop, wait indefinitely
logger = await get_async_logger(settings=settings)
```

### AC4: Decision Framework Provided

**Description:** Helps reader choose the right mode.

**Validation:**
- Table or decision tree: latency vs completeness tradeoff
- Example use cases for each mode
- Default behavior explained

### AC5: Monitoring Mentioned

**Description:** How to observe backpressure in production.

**Validation:**
- Queue depth metric reference
- Dropped log counter reference

---

## Implementation Notes

### File Path

`docs/cookbook/non-blocking-async-logging.md`

### Page Structure

```markdown
# Non-blocking logging in FastAPI (protect latency under slow sinks)

Slow log sinks can stall your async application...

## The Problem: Slow Sinks Block Your App

{Diagram or explanation of event loop blocking}
{Concrete latency numbers}

## The Solution: Async Pipeline with Backpressure

{fapilog architecture overview}

## Choosing Drop vs Block Mode

| Mode | Use When | Tradeoff |
|------|----------|----------|
| drop | Latency critical | May lose logs |
| block | Audit critical | May add latency |

```python
# Configuration examples
```

## Monitoring Backpressure

{Queue depth, dropped counters}

## Going Deeper

- [Backpressure Architecture](/architecture/backpressure)
- [Performance Tuning Guide](/guides/performance)
```

---

## Tasks

- [ ] Create `docs/cookbook/non-blocking-async-logging.md`
- [ ] Write problem section with event loop explanation
- [ ] Write solution overview
- [ ] Create drop vs block decision table
- [ ] Add configuration examples
- [ ] Document monitoring options
- [ ] Add cross-links

---

## Tests

- Code examples work
- Links valid
- Technical accuracy reviewed

---

## Definition of Done

### Content Complete

- [x] All sections written
- [x] Decision framework clear
- [x] Code tested

### SEO Optimized

- [x] Keywords in H1 and first paragraph
- [x] Under 1000 words

### Integrated

- [x] Added to cookbook index
- [x] Linked from performance guide

---

## Risks / Rollback

### Risks

1. **Risk:** Backpressure API changes
   - **Mitigation:** Verify against current implementation

### Rollback Plan

Revert commit.

---

## Code Review

**Date:** 2026-01-21
**Reviewer:** Claude
**Verdict:** OK to PR

### Summary

Reviewed cookbook page for non-blocking async logging with backpressure configuration.

### AC Verification

| Criterion | Evidence |
|-----------|----------|
| AC1: Page exists with correct title | `docs/cookbook/non-blocking-async-logging.md:1` - H1 matches exactly |
| AC2: Problem explained simply | `:5-28` - Slow sinks, event loop blocking, 500ms latency example |
| AC3: Backpressure modes documented | `:49-95` - Drop/block via Settings API |
| AC4: Decision framework provided | `:97-108` - Table with 6 use cases |
| AC5: Monitoring mentioned | `:110-137` - queue_depth_high_watermark and fapilog_events_dropped_total |

### Quality Gates

- [x] All sections written (817 words)
- [x] Keywords in H1 and first paragraph
- [x] Added to cookbook index
- [x] Linked from performance guide

### Issues Addressed

- [P1] Missing cross-link from performance guide - Fixed in `docs/user-guide/performance-tuning.md:3`

---

## Change Log

| Date | Change | Author |
|------|--------|--------|
| 2026-01-21 | Initial draft | Claude |
