Skip to content

Marten.ScaleTesting: daemonload — running-daemon connection-footprint scenario (jasperfx#486 WS2)#4875

Merged
jeremydmiller merged 2 commits into
masterfrom
feat/ws2-daemon-connection-scenario
Jul 7, 2026
Merged

Marten.ScaleTesting: daemonload — running-daemon connection-footprint scenario (jasperfx#486 WS2)#4875
jeremydmiller merged 2 commits into
masterfrom
feat/ws2-daemon-connection-scenario

Conversation

@jeremydmiller

Copy link
Copy Markdown
Member

Part of the #486 epic — the WS2 (connection conservation at ~100 tenants) measurement primitive. Dev-tool only: no product code, not packaged, not in CI.

What

Everything else in Marten.ScaleTesting measures rebuilds; daemonload measures the steady-state running daemon. It builds an isolated UseTenantPartitionedEvents store (own schema, dedicated Application Name), registers --tenants tenants, starts the daemon (per-tenant agent fan-out via StartAllAsync), appends continuously across every tenant, and samples pg_stat_activity throughout. Reports peak/mean total+busy connections and per-tenant catch-up coverage (min per-tenant projection progression vs that tenant's own sequence ceiling, requiring the full per-projection row count so a never-started agent reads as stalled). --max-connections turns the report into a pass/fail regression gate; --metrics/--trace emit JSON + CSV.

First numbers (dev box, 100 tenants × 2 projections = 200 agents, 120s @ ~190 events/s)

JasperFx 2.21.0 + #493 (local pack)
Peak connections 47 79
Peak busy connections 5 5
Tenants caught up 35/100 100/100

Two findings:

  1. The 65 stalled tenants were each exactly one append-batch (5 events) short of their ceiling — an empirical, at-scale demonstration of Session SET ROLE #492 (per-tenant HWM polls fired only on store-global mark changes, so each tenant's tail batch was never re-polled once appends stopped). Integrate support for Sqitch into the command line support #493 fixes it: same scenario, 100/100 caught up.
  2. The connection footprint is idle-pool retention, not query pressure: peak busy connections never exceeded 5 while the pool held ~47–79 open connections for 200 agents. The WS2 batching/multiplexing work should target EventLoader.LoadAsync's session-per-call shape plus pool shaping, and this scenario is the before/after gate for it.

🤖 Generated with Claude Code

jeremydmiller and others added 2 commits July 7, 2026 06:48
…asurement (#486)

Everything else in Marten.ScaleTesting measures rebuilds; WS2's concern is the
steady-state RUNNING daemon at ~100 tenants. daemonload builds an isolated
UseTenantPartitionedEvents store with N async projections, registers
--tenants tenants, starts the daemon (per-tenant agent fan-out via
StartAllAsync), appends continuously across every tenant, and samples
pg_stat_activity throughout — attributing connections precisely via a
dedicated Application Name on the store's connection string.

Reports peak/mean total+busy connections, sustained append rate, and
per-tenant catch-up coverage (each tenant's min projection progression vs its
own per-tenant sequence ceiling, requiring the full per-projection row count
so a never-started agent reads as stalled, not vacuously caught up).
--max-connections turns the report into a pass/fail regression gate;
--metrics/--trace emit JSON + per-sample CSV.

Smoke-verified: 10 tenants x 2 projections = 20 agents, all caught up, ~23
steady connections — already O(agents), which is exactly the WS2 problem this
scenario exists to quantify before and after daemon command batching.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant