infra: provision proxy-aware throttling and the readiness probe - #91
Merged
Conversation
RateLimiting__TrustForwardedFor was set by hand on the live app, which meant the next provision run would produce an environment without it - and an environment without it throttles wrongly rather than obviously. App Service is a reverse proxy, so every request reaches the app carrying the proxy's address; left false, all callers collapse into a single partition and the per-caller limits become a global cap that the first busy minute trips for everybody. It goes in the block that runs on every provision rather than section 6, which -SkipInfra skips. It is a correctness setting, not an infrastructure one, and skipping infrastructure is not a reason to deploy an app that throttles all its traffic together. The app already warns when the setting and the traffic disagree; a provision run should not produce an environment that needs the warning. The health check path is set to /health/ready, which is the endpoint that answers whether the instance can actually serve. /health stays what the keep-warm schedule pings, and stays shallow: it is hit every few minutes, and waking a serverless database on that cadence costs far more than the free allowance. Health check needs Basic or higher, so on F1 or D1 the script says so instead of failing, and names the substitute - an external monitor against /health/ready every 30 to 60 minutes, with the reason for that interval rather than a shorter one. The manual deployment path in the handbook gains both, since anyone following it by hand would otherwise reproduce exactly the gap this closes. 518 backend tests pass; build clean under -warnaserror; dotnet format clean. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EA4mmpcb1rcvNntHR1iG6j
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.
RateLimiting__TrustForwardedForwas set by hand on the live app, which meant the next provision run would produce an environment without it — and an environment without it throttles wrongly rather than obviously.App Service is a reverse proxy, so every request reaches the app carrying the proxy's address. Left
false, all callers collapse into a single partition and the per-caller limits become a global cap that the first busy minute trips for everybody.Where it goes, and why that matters
It's in the block that runs on every provision, not section 6 — which
-SkipInfraskips.It's a correctness setting, not an infrastructure one, and skipping infrastructure isn't a reason to deploy an app that throttles all its traffic together. The app already warns when the setting and the traffic disagree; a provision run shouldn't produce an environment that needs the warning.
Health probe
Sets
--health-check-path /health/ready— the endpoint that answers whether the instance can actually serve./healthstays what the keep-warm schedule pings, and stays shallow. It's hit every few minutes, and waking a serverless database on that cadence costs far more than the free allowance.Health check needs Basic or higher, so on
F1/D1the script says so rather than failing, and names the substitute — an external monitor against/health/readyevery 30–60 minutes, with the reason for that interval rather than a shorter one:Manual path too
10-deploy-azure-free.mdgains both, since anyone following it by hand would otherwise reproduce exactly the gap this closes.Verification
-warnaserror;dotnet formatclean$ApiUrl(line 258) and$Sku(param) are both in scope where used, and the backtick continuations match the file's existing styleGenerated by Claude Code