infra(app): one nginx instance, concurrency 80 - #11829
Merged
Merged
Conversation
anyplot-app goes from max 3 / concurrency 15 to max 1 / concurrency 80; min stays 0. A static nginx never needed a second instance for capacity, yet every crawler burst filled the 15 slots and started one or two more instances (50 AUTOSCALING starts in the ten days to 2026-09-10), because nginx holds a proxied bot request open for as long as the API takes to answer. With the API on one warm instance those waits are milliseconds, and one nginx with 80 slots absorbs the burst without a cold start. Owner decision 2026-09-11: one instance per service in both projects. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CELiZYpFBQc5bncjWXYrue
Contributor
There was a problem hiding this comment.
🔵 Needs a closer look
The production capacity and deployment configuration change requires final human review.
Pull request overview
Caps the frontend Cloud Run service at one instance and raises concurrency to 80.
Changes:
- Sets
max-instancesto 1 and concurrency to 80. - Documents the operational rationale in configuration and changelog.
File summaries
| File | Description |
|---|---|
app/cloudbuild.yaml |
Updates Cloud Run scaling settings. |
changelog.d/app-single-instance.md |
Records the infrastructure change. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
2 tasks
MarkusNeusinger
added a commit
that referenced
this pull request
Sep 13, 2026
…11830) ## Summary - `docs/reference/performance.md`: the frontend row of the infrastructure table now says max-instances=1, concurrency 80, matching `app/cloudbuild.yaml` after #11829. #11828 and #11829 edited the same row from different branches, so this line was left behind on purpose to keep the two from conflicting. ## Plan N/A ## Test plan - [x] `uv run python -m tools.changelog check --base origin/main` passes - [x] Docs-only change; no code touched 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01CELiZYpFBQc5bncjWXYrue --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
anyplot-appruns as a single instance with concurrency 80 (was max 3, concurrency 15;min-instancesstays 0). A static nginx never needed a second instance for capacity — its files answer in milliseconds and it sits at 15 MiB p99 of 512Mi — yet every crawler burst filled the 15 slots and started one or two more instances (50 AUTOSCALING starts in the ten days to 2026-09-10), because nginx holds a proxied bot request open for as long as the API takes to answer. One forged-UA burst on 2026-09-09 filled the instance and started two more. With the API on one warm instance (infra(api): single instance, non-blocking prewarm, OG renders off the loop #11828) those waits are milliseconds, and one nginx with 80 slots absorbs the burst without a 0.26 s cold start.docs/reference/performance.mdstill says max 3 / concurrency 15 for the frontend after this PR: infra(api): single instance, non-blocking prewarm, OG renders off the loop #11828 edits the same table row, so the row is updated in a follow-up once both have merged, to keep the two PRs from conflicting.Plan
N/A — measurements in the Todoist task "Nachprüfen: merkt jemand, dass anyplot-app auf null skaliert?" (closed 2026-09-10 with the numbers) and in #11828.
Test plan
app/cloudbuild.yamlparses; the deploy step carries--min-instances 0 --max-instances 1 --concurrency 80uv run python -m tools.changelog check --base origin/mainpassesdeploy-appgreen;gcloud run revisions describeon the promoted revision showsmaxScale 1,containerConcurrency 80; then two weeks ofrun.googleapis.com/request_countby response_code (zero 429s expected) and instance-start logs (AUTOSCALING starts should stop)🤖 Generated with Claude Code
https://claude.ai/code/session_01CELiZYpFBQc5bncjWXYrue