Files
atelier/domains/performance/backend.md
T
Jon Chery 496303471d docs(milestone): complete v0.1 — initial framework
---ci---
project: atelier
phase: 7
milestone: v0.1
status: complete
phase_role: final
milestone_complete: true
requirements:
  covered: [ATELIER-01, ATELIER-02, ATELIER-03, ATELIER-04, ATELIER-05, ATELIER-06, ATELIER-07, ATELIER-08, ATELIER-09, ATELIER-10, ATELIER-11, ATELIER-12, ATELIER-13, ATELIER-14, ATELIER-15, ATELIER-16, ATELIER-17, ATELIER-18, ATELIER-19, ATELIER-20, ATELIER-21, ATELIER-22, ATELIER-23, ATELIER-24, ATELIER-25, ATELIER-26, ATELIER-27, ATELIER-28, ATELIER-29, ATELIER-30, ATELIER-31, ATELIER-32, ATELIER-33, ATELIER-34, ATELIER-35]
  partial: []
ship:
  milestone: v0.1
  type: NFR
  tag: v0.0.7
  merge: milestone/v0.1-atelier -> main
  release: https://git.cloudinit.dev/cloudinit-bot/atelier/releases/tag/v0.0.7
---/ci---

Milestone v0.1 — Initial Framework (NFR, complete).
8 core principles (C1-C8), 11 domains, 110 domain principles, 27 derived docs, 4 good + 3 bad examples, 4 language docs, full matrix, 3 review docs.
All 35 requirements covered. 7 patches (v0.0.0 pre-execution through v0.0.7 final). v0.0.7 IS the v0.1.0 milestone release.
2026-08-05 00:36:55 +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)