--- phase: quick-261001-qoa plan: 01 subsystem: docs tags: [docs, architecture, performance, scaling] status: complete requires: [] provides: - "docs/architecture/performance-and-scaling.md (Architecture section, order 50)" affects: - docs/index.md - docs/setup/coming-from-wintercms.md tech-stack: added: [] patterns: [] key-files: created: - docs/architecture/performance-and-scaling.md modified: - docs/index.md - docs/setup/coming-from-wintercms.md decisions: - "Rate-limit caveat states that serve always builds the throttle limiter on surf.MemoryStore with no way to supply another store; the page advises dividing limits by replica count or limiting at the load balancer" - "No pool-size or connection-limit config key is named, because lagoon has none (only database.dsn)" metrics: duration: 10 min completed: 2026-10-01 actuals: tokens: 2900 tasks: 2 commits: 1 plan_head_before: 2fc5eac6d5073f1ec0c6a9215193991d96352594 plan_head_after: 4103d95a1ac46796655eb87c392b937113d7f665 --- # Quick 261001-qoa Plan 01: Performance and scaling docs page Summary A new Architecture guide page compares a SummerCMS binary with WinterCMS on PHP-FPM: boot once versus per-request boot, memory, slow-I/O concurrency, the shared GORM+River pool and model hydration. It includes an expectations table under a NOTE saying the ranges are not measurements of SummerCMS, multi-replica caveats that match the code (including a WARNING on per-process rate limits), scaling and operations, and measuring with tide parity:record/parity:replay plus vegeta or k6. ## Tasks | Task | Name | Commit | Files | |------|------|--------|-------| | 1 | Tracer: page shell, intro, "Boot once, not per request", inbound links | 4103d95 (single commit, per plan) | docs/architecture/performance-and-scaling.md, docs/index.md, docs/setup/coming-from-wintercms.md | | 2 | Remaining sections, identifier checks, gates, commit | 4103d95 | docs/architecture/performance-and-scaling.md | The tracer gate ran before expansion: TestDocsTree and TestDocsBuildRealTree passed, `docs:build --check` reported no problems, and a scratch build wrote architecture/performance-and-scaling.html with the landing page linking it. ## Verification - Identifiers confirmed with go doc: surf.MemoryStore, surf.Store, surf.NewFixedWindowLimiter, surf.Assemble, bouncer.PostgresBlacklist, bouncer.NewPostgresBlacklist, lagoon.Publish, party.Activate, cabana.CompiledController, wire.WriteJSON, attach.File.Thumb. - Config keys checked by hand: queue.work_in_serve (modules/conga/client.go:55), database.dsn (modules/lagoon/connection.go:97), storage.uploads.bucket_url (modules/lagoon/attach/bucket.go). surf.BuildRouter always uses NewMemoryStore (modules/surf/router.go). Thumbnails use github.com/disintegration/imaging. `serve --addr` exists (modules/surf/serve.go). - `go vet ./...`: green. - `go test ./cmd/summer -run 'TestDocsTree|TestDocsBuildRealTree' -count=1`: ok. - `go run ./cmd/summer docs:build --check`: "docs:build: no problems found". - Scratch build: the sidebar order is introduction, go-modules-and-workspaces, application-lifecycle, request-lifecycle, performance-and-scaling. - Acceptance greps all pass. No max_open, max_idle or pool_size appears. The commit touches exactly the three docs files and has no co-author or session trailer. ## Deviations from Plan - Task 1 intro: the tracer pointed to "the measuring section at the end of this page" in plain text, because the `#measuring-it-yourself` anchor did not exist yet and the link checker would have failed. Task 2 turned it into a link once the section existed. The final content matches the plan. - The commit has no Co-Authored-By or session trailer, following the user's global CLAUDE.md and the orchestrator's constraints. Otherwise the plan was executed as written. ## Known Stubs None. ## Self-Check: PASSED - FOUND: docs/architecture/performance-and-scaling.md - FOUND: commit 4103d95