Skip to content

infra: provision proxy-aware throttling and the readiness probe - #91

Merged
bgard68 merged 1 commit into
mainfrom
claude/provision-settings
Aug 26, 2026
Merged

infra: provision proxy-aware throttling and the readiness probe#91
bgard68 merged 1 commit into
mainfrom
claude/provision-settings

Conversation

@bgard68

@bgard68 bgard68 commented Aug 26, 2026

Copy link
Copy Markdown
Owner

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.

Where it goes, and why that matters

It's in the block that runs on every provision, not section 6 — which -SkipInfra skips.

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.

/health stays 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/D1 the script says so rather than failing, and names the substitute — an external monitor against /health/ready every 30–60 minutes, with the reason for that interval rather than a shorter one:

==> Health check path
  !   Health check is not available on the F1 tier - skipping.
      Substitute: point an external monitor (or a scheduled workflow) at
      https://…/health/ready on a 30-60 minute interval. Not more often:
      a readiness check wakes the database, which is what /health avoids.

Manual path too

10-deploy-azure-free.md gains both, since anyone following it by hand would otherwise reproduce exactly the gap this closes.

Verification

  • 518 backend tests pass locally against real PostgreSQL 16
  • Build clean under -warnaserror; dotnet format clean
  • No pwsh in this container, so the script change is reviewed by reading, not by executing — $ApiUrl (line 258) and $Sku (param) are both in scope where used, and the backtick continuations match the file's existing style

Generated by Claude Code

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
@bgard68
bgard68 merged commit 2a9a9a4 into main Aug 26, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants