Files
atelier/domains/performance/backend.md
T
2026-08-05 00:30:31 +00:00

2.2 KiB

Backend Performance — Derived Rules

Derives from domains/performance/first-principles.md P1 (Measure First), P3 (Complexity Awareness), P4 (Resource Bounds).

Measure First (P1)

  • p50, p95, p99 latencies. The average hides the long tail.
  • Throughput (req/s) under load. Saturation point (where latency rises).
  • Resource utilization: CPU, memory, I/O, network. Each is a budget.

N+1 Queries (P3 Complexity Awareness)

  • A query in a loop is an N+1. It is O(N) queries instead of O(1).
  • Detect with a query counter in tests. A test that issues 100 queries is failing.
  • Fix with a JOIN, a batch load, or a dataloader. Never "we'll fix it later."

Caching (P5 Caching with Intent)

  • Cache what is: expensive to compute, stable, read often.
  • Invalidation is designed: TTL, event-based, or version-based. Never "we'll just clear it."
  • A cache without an invalidation strategy is a cache that serves stale data forever.
  • Multi-level: HTTP cache → CDN → app cache → DB. Each layer has its own rules.

Async and Concurrency (P7 Async When Independent, see domains/concurrency/)

  • I/O-bound work is async. Don't block a thread on a network call.
  • CPU-bound work is in a worker, not the request path.
  • Bounded queues everywhere (P9 Bounded Queues). Unbounded = OOM.

Database (P4 Resource Bounds, see domains/data/indexing.md)

  • Connection pool: bounded. The DB has a connection limit; the pool respects it.
  • Slow queries: logged, explained, fixed. A 10-second query is a bug.
  • Pagination on large tables: cursor, not offset. Offset scans rows.

Resource Bounds (P4)

  • Memory: bounded. A request that allocates unbounded memory is a DoS vector.
  • Timeouts: every external call has one. A call without a timeout is a call that can hang forever (P8 Timeout Discipline).
  • File handles, DB connections, HTTP connections: all bounded, all pooled.

What Violates Backend Performance

Violation Principle
N+1 query in a loop P3
No timeout on an HTTP call P4, P8 (concurrency)
Unbounded in-memory sort P4
Cache with no invalidation P5
SELECT * P4 (data P10)
Connection pool size = 1000 P4 (DB limit)