Repository navigation
Recurrence: Orleans silo thread-pool stall (~25s) in memex-portal — continued from #4886, risk of missed heartbeats and cluster eviction #5388
Description
What is failing
The Orleans silo in the memex-portal deployment hit a full .NET Thread Pool execution stall of ~24.7s, detected by Orleans.Runtime.MembershipService.LocalSiloHealthMonitor. During such a stall the silo runs nothing — including timer callbacks — risking missed membership heartbeats and cluster eviction.
Probable cause
Cause unclear from the log alone (the monitor reports the symptom, not the trigger). Plausible candidates: a very long Gen2/LOH GC pause, thread-pool starvation with slow ramp-up under a tight container CPU limit, or CPU-quota cgroup throttling. This occurrence is notably longer (~24.7s) than the previously filed cluster of stalls (11.5–24.9s), suggesting the condition is not improving.
Impact
Low frequency — a single new occurrence on one pod, but it continues a pattern that has now hit six different memex-portal pods since 2026-09-15. No observed outage yet, but a stall of this length in a silo hosting grains causes transient request timeouts and, if it exceeds the membership death window, cluster eviction and grain migration churn.
Duplicate / related
This is a recurrence of the fingerprint already filed as #4886 (incident Admin/_LogIncident/1dbb05f503932ad3, filed 2026-09-20, stalls on five pods). This ticket tracks the newest occurrence; a human may prefer to fold it into #4886 rather than track separately.
Where to look
Orleans.Runtime.MembershipService.LocalSiloHealthMonitor(Orleans silo health watchdog) — the detection/logging site.- Deployment CPU/memory limits of the
memex-portalpods — check CPU throttling (container_cpu_cfs_throttled_periods_total) and GC stats at the stall timestamp.
Evidence
| Fingerprint | eda900bec4354ee0 |
| Category | Orleans.Runtime.MembershipService.LocalSiloHealthMonitor |
| Severity | Error |
| Namespace | memex-cloud |
| Pods | memex-portal-deployment-857546649-2c25b |
| Occurrences | 1 |
| First seen | 2026-09-22 18:47:10Z |
| Last seen | 2026-09-22 18:47:10Z |
| Routing | not determined — no configured route matches the category Orleans.Runtime.MembershipService.LocalSiloHealthMonitor. This repository is the configured fallback, not a finding about who owns the fault; the category names the LOGGER, which may not be the subject. |
Recent log lines
2026-09-22 18:47:10Z memex-portal-deployment-857546649-2c25b fail: Orleans.Runtime.MembershipService.LocalSiloHealthMonitor[86528487]
.NET Thread Pool execution stalled for 24.6915577s. This can indicate .NET Thread Pool starvation, very long .NET GC pauses, or other runtime or machine pauses.
Re-addressed by the current identity function: this incident inherited 3a7d53ee7da8a1b4 (Systemorph/MeshWeaver.Plugins#1796). Those nodes are superseded and will not fold, file or comment again.
Opened automatically from Admin/_LogIncident/eda900bec4354ee0. Recurrences are folded into this issue rather than opening new ones.
Activity
rbuergi commentedon Sep 23, 2026
Triage 2026-09-23: same site and discriminator as #4886. Its one occurrence predates the fix candidate, so only the post-roll read remains
Same root as #4886. Both have the same log site,
Orleans.Runtime.MembershipService.LocalSiloHealthMonitor[86528487](".NET Thread Pool execution stalled for …"), the same namespace (memex-cloud) and the same measured quantity. This ticket's body proposes folding it into #4886. It stays open for now only because its remaining step is verification rather than code.The occurrence predates the candidate fix on this namespace:
memex-portal-deployment-857546649-2c25b, 24.69 sec191c2b61, 1 h 40 min after the stall, so that pod cannot have carried it/api/version39f49494eb.git merge-base --is-ancestor ec191c2b61 39f49494ebholds, so it carries #5327/api/version3da3423c4b. It does not containec191c2b61, so readings frommemexsay nothing about #5327DrainLoopbounded at 64 turns,94689968ef)The read that closes or keeps this. It goes on the control instance, which answered 503 when I tried, so I did not take it:
{ "requestedAction": "Sample" }onDeployments/memex-cloud. Confirm that every replica runs39f49494ebor later, and note each pod'sstartedAt.{ "requestedAction": "Logs", "deployment": "Deployments/memex-cloud", "query": "Thread Pool execution stalled", "sinceMinutes": <minutes since the roll> }. Read the coverage the result reports (earliest row,cut). AsinceMinutesvalue is a request, not coverage.How to read it.
39f49494ebpod keeps Orleans silo thread-pool stalls (12–18s) across all memex-portal pods risk missed heartbeats and cluster eviction #4886 open and excludes that candidate.Not established: which of the three candidates (GC pause, pool starvation, CFS throttling) produced this 24.7 s stall. No GC, CPU-throttle or ThreadPool reading exists for 18:47Z.
systemorph-com commentedon Sep 23, 2026
Still occurring: 1 more since the last update (2 total).
memex-portal-deployment-857546649-2c25b,memex-portal-deployment-6bf5d7dcc8-jl5k8Recent log lines
Re-addressed by the current identity function: this incident inherited
3a7d53ee7da8a1b4(Systemorph/MeshWeaver.Plugins#1796). Those nodes are superseded and will not fold, file or comment again.systemorph-com commentedon Sep 23, 2026
Still occurring: 4 more since the last update (6 total).
memex-portal-deployment-857546649-2c25b,memex-portal-deployment-6bf5d7dcc8-jl5k8,memex-portal-deployment-79889596-47trv,memex-portal-deployment-777677694-p6hbnRecent log lines
Re-addressed by the current identity function: this incident inherited
3a7d53ee7da8a1b4(Systemorph/MeshWeaver.Plugins#1796). Those nodes are superseded and will not fold, file or comment again.rbuergi commentedon Sep 23, 2026
Canonical for the
LocalSiloHealthMonitorstall site — #4886 folded here#4886 (same site,
Orleans.Runtime.MembershipService.LocalSiloHealthMonitor[86528487], memex-cloud, 3 stalls 2026-09-15 → 09-19) is closed as a duplicate of this ticket, because this is the issue the live incident nodeAdmin/_LogIncident/eda900bec4354ee0folds recurrences onto. Its analysis still applies and is not repeated here: occurrence 2 (12.6 s,58dbb6d98d-8msww, 2026-09-19 06:29:21Z) was a full blocking GC inside #4824's OOM window (comment); the gauge is a symptom, not a trigger; grouping on #2480.Reading the recurrences above against the fix candidates (measured now):
/api/versionec191c2b61, compiles off the shared pool)?9a61fed964(merged 2026-09-23 10:02Z)git merge-base --is-ancestor)39f49494ebThe four 2026-09-23 stalls (12:30:53Z 15.1 s
6bf5d7dcc8-jl5k8, 12:32:10Z 10.1 s same pod, 13:13:23Z 11.4 s79889596-47trv, 14:51:41Z 10.2 s777677694-p6hbn) fall after9a61fed964existed, but I did not establish which image each of those pods ran (memex-cloud went through several ReplicaSets that day, and thesystemorphcontrol instance'sSample/Logswere not reachable from this session). If any of them ran an image containingec191c2b61, compile starvation is excluded as the (sole) trigger and the remaining candidates are GC pause (cf. #4824 / #5555) and CFS throttling.The read that decides it (owner / control instance):
{ "requestedAction": "Sample" }onDeployments/memex-cloudfor pod → image, then{ "requestedAction": "Logs", "query": "Thread Pool execution stalled", "sinceMinutes": … }and match each stall's pod to its image.rbuergi commentedon Sep 24, 2026
Post-roll reading 2026-09-24 ~06:51Z (memex-cloud): the Error-level stall is quiet, the starvation it gauges is not. Stays open
Image. Every memex-cloud pod that booted in the window ran core
9a61fed964, per the[PlatformStartup] version=lines (Ops/logs-memexcloud-20260924-verify-platformstartup, 38 boots). ReplicaSet786d86cf54is ci.9260,6688fb9488and7d7f4d84f9are ci.9262, and6f497dc9band76cf776847are ci.9263.9a61fed964contains #5327 (ec191c2b61).Readings, 900 min (2026-09-23 ~15:45Z to 2026-09-24 06:51Z):
Ops/logs-memexcloud-20260924-verify-5388-10s,|~ "(?i)Thread Pool execution stalled for [1-9][0-9]+\.", which is this ticket's ≥10 s Error-level shape: 0 lines.Ops/logs-memexcloud-20260924-verify-5388-stall,|~ "(?i)Thread Pool execution stalled|Grain placement operation timed out": cut at 200. The landed sample holds dozens of sub-10 s stalls on ci.9262 and ci.9263 pods, for example:6f497dc9b-r4nkg6f497dc9b-j9vq86f497dc9b-hd5jg7d7f4d84f9-mvzb576cf776847-9p7z4(19:02Z)Reading. The fingerprint as filed (≥10 s, Error) has not recurred in 15 h. That is not a clean reading, though. The same gauge fires at 1–9 s, many times, on the fixed image, and the separate placement query counts 177
Grain placement operation timed outlines in the same window (#5037). This ticket says the gauge is a symptom, and the symptom has only dropped below the Error threshold. Not closing on a threshold.Not established. The cause of the residual stalls: GC (#4824 / #5555) or CFS throttling. Nor whether ci.9287 (core
bf5ac85526, which carries #5635's removal of the same-silo deep copy) changes the rate. ci.9287 has been handed to the control lane but has not rolled.rbuergi commentedon Sep 25, 2026
Stall readings vs GC on memex-cloud, and two blockers removed in #5678
I ran
LogsInstanceActions on memex.meshweaver.cloud (Ops/logs-memexcloud-20260925-5388-*). Each stall writes 2 lines: the stall line andSelf-monitoring … degraded.1. Rate per image
9a61fed964)…-stalls-48h) was CUT at 1000 lines inside this window. I parsed 204 of them; 21 were ≥ 5 s76cf776847) and the next ReplicaSets…-stalls-from-0645)140c5fb7ae, 4/4 replicas perOps/Status/memex-cloudv3788)…-stalls-all, not cut)The ">200 per ~15 h of 1–9 s" family belongs to the
9a61fed964images. The current image logs about one sub-1.5 s reading every 5 h.2. GC or blocking on the current image
The
[LIVENESS]heartbeat runs on a dedicated thread, so a GC or a machine pause shows up in it asOVERRAN.…-overran(last 20 h): 0 OVERRAN ticks on any pod.…-overran-48h) finds 21.For the three stalls on
589ff8f895-ghgjt(…-liveness-ghgjt-windows), GC pause measured in the 10 s tick that holds each stall:3. Static sweep: what can block pool threads
Core and Plugins (
origin/main) contain no.Result,.Wait(),.GetAwaiter().GetResult()orThread.Sleepon a hot path. The existing ratchets holdsrc/at zero, apart from the tool-only allow entries. What the sweep did find is structural.IIoPool'sInvokeBlockingleaves ran on borrowed ThreadPool workers.FileSystem256,Blob128,Http16, and the core count forCompileand the default pool. The pool minimum is 6.gitwaits or prebuilt reads could therefore hold every worker.CompileCpuhad threads of its own.Compile-pool leaf withConcurrentBuildon, which is the fix(compiler): keep NodeType compiles off the silo's shared ThreadPool #5327 shape.#5678 fixes both.
mw-io-lane, with the same cap and the same queue.ScriptSession.Compileis now a CPU-lane leaf withConcurrentBuildoff.BlockingLeavesStayOffTheThreadPoolTest,KernelCellCompileStaysOffTheThreadPoolTest.Doc/Architecture/BlockingLeavesOffTheThreadPool.Candidates in Plugins, not fixed here:
MeshWeaver.Blazor/Pages/ContentPage.razordoes a synchronousCopyTo/ReadToEndof a content stream during render.MeshWeaver.Azure.Blob/BlobNuGetPackageCacherunsZipArchiveover a blob stream inside an asyncRunlane.MeshWeaver.Import/ImportBuilderparses Excel synchronously inside an asyncRunlane.All three are user- or Azure-triggered. None of them was observed in these windows.
Not established
9a61fed964and140c5fb7aeproduced the drop. Candidates: fix(mesh): a subscriber's own release is not announced back; a same-silo grain call shares the immutable delivery envelope #5635 (no same-silo JSON deep copy), fix(compile): stop dual-writing the compile-state satellite nobody reads (#5389) #5571, fix(query): a live query re-reads once per burst of changes, not once per change #5615 and Plugins#2329. The windows also differ in load: 09-23 was a day of rolls and heap steps.What closes this
After a roll carrying #5678: the same stall query per pod over ≥ 24 h, with each reading checked against its tick's
gcPause. Any remaining stall with gcPause ≪ stall is starvation that still needs a name. A GC-paired stall belongs with #5555.Claude Opus 5.5. The only production writes were
LogsInstanceActions underOps/logs-memexcloud-20260925-5388-*on memex-cloud.review: the cell's execute leaf returns the task directly; the IoPool…
rbuergi commentedon Sep 25, 2026
#5678 merged to
main(96acfe24a6, 2026-09-25 07:05Z). It is not live until a roll carries it. The verification after that roll is in the comment above. This issue stays open until that reading is taken.rbuergi commentedon Sep 26, 2026
Deploy status, 2026-09-26 ~06:10Z:
96acfe24a6) is not live on memex. memex runs4028fd6468(ci.9332), and that image does not contain it.7bc7ab26f0), which does contain it. Three generations were running andconverged: falseat 06:01Z.The verification defined in the 09-25 comment applies once that roll converges.
Separate finding, so it is not read as this issue. Since ~09-25 18:00Z, memex pods have been dying abruptly (tracked on #5704). There are SIGABRT/SIGSEGV dumps, and there are also deaths with no log line at ~3.03 h of uptime. Their last
[LIVENESS]ticks are on time (gap=10.00s) withpoolPending=0, so those deaths are not ThreadPool stalls.systemorph-com commentedon Oct 5, 2026
Still occurring: 1 more since the last update (7 total).
memex-portal-deployment-857546649-2c25b,memex-portal-deployment-6bf5d7dcc8-jl5k8,memex-portal-deployment-79889596-47trv,memex-portal-deployment-777677694-p6hbn,memex-portal-deployment-6d8c9665cc-jltncRecent log lines
Re-addressed by the current identity function: this incident inherited
3a7d53ee7da8a1b4(Systemorph/MeshWeaver.Plugins#1796). Those nodes are superseded and will not fold, file or comment again.systemorph-com commentedon Oct 5, 2026
Still occurring: 1 more since the last update (8 total).
memex-portal-deployment-857546649-2c25b,memex-portal-deployment-6bf5d7dcc8-jl5k8,memex-portal-deployment-79889596-47trv,memex-portal-deployment-777677694-p6hbn,memex-portal-deployment-6d8c9665cc-jltnc,memex-portal-deployment-6cfcf78898-gkkdvRecent log lines
Re-addressed by the current identity function: this incident inherited
3a7d53ee7da8a1b4(Systemorph/MeshWeaver.Plugins#1796). Those nodes are superseded and will not fold, file or comment again.rbuergi commentedon Oct 8, 2026
Heartbeat reading for each named occurrence: 09-22 18:47 2c25b, 09-23 12:30 jl5k8, 13:13 47trv, 14:51 p6hbn, and 10-05 07:43 jltnc / 16:19 gkkdv. All six are on GC-thrash pods: heap 10.2–11.6 GiB, GC 86–97 % of wall time, except 47trv, where the stall tick held a single 11.7 s GC. The
Thread Pool execution stalledsignal here is the GC, not a scheduler defect. This closes with the retention fix (#6261 + Plugins#3109, not yet rolled). I did not read the comment-only timestamps (09-19 06:29, 09-23 10:02, 09-24 06:51, 09-25 07:05), because their pods are not named. Table: #5315 (comment)rbuergi commentedon Oct 10, 2026
Post-roll reading, 2026-10-10 ~05:20Z. All three portals serve core
479c9b72d5(/api/version), which carries #6261 (merged 2026-10-07 17:06Z). Plugins#3109 merged 2026-10-07 17:57Z, before any image in the windows below was built.Governed
Logsreads on the control instance (Ops/Actions/logs-*-20261010-*):warm-up complete)Thread Pool execution stalledThread Pool execution stalled for NN(≥ 10 s)DISPOSAL DEADLOCK DETECTED(MessageHub[7316]/[7317])MessageHub[73xx]or[DISPOSE-*[LIVENESS]tick with heap ≥ 6 GiB on the CURRENT ReplicaSetd9cd97, since 22:34Z; its[HEAPSTEP]lines peak at 5.06 GiB)477bf6, since ~23:00Z;[HEAPSTEP]peak 3.83 GiB)For comparison, the stall band this issue tracked ran at heap 10.2–11.6 GiB with GC at 86–98 % of wall time. The heaviest tick on a #6261 image in either window is memex
cfb58787b-b6kljon 10-09 14:35Z: heap 8.09 GiB, butgcPause +0.19 sper 10 s tick (~2 %) andpoolPending=0. The heap is high there, but the GC is not thrashing.Positive controls. (1) The pool-stall instrument fires in the window: 18 sub-3 s lines, so a ≥ 10 s stall would have printed. (2)
[LIVENESS]/[HEAPSTEP]are ingested from the current pods. (3) The same heap regex returns 255 ≥ 6 GiB ticks from the pre-#62616548d4pods (booted ~10-07 13:15Z, before the merge) up to 10-09 17:58Z. That control separates the images.Not established. Loki keeps under ~4.5 days. A probe for any line from the 10-05 pod
6cfcf78898-kss8qreturned 0, so the 10-05 episode itself cannot be re-read as an in-window control for theDISPOSAL DEADLOCKregex. That regex is the literal text atMessageHub.cs:3084/3116/3145. The windows are 12 h and 24 h of ordinary traffic plus frequent rolls. They are not a reproduction of the 10-05 surge.Closing. The stated closing condition was "closes with the retention fix (#6261 + Plugins#3109)". The ~25 s and 10–17 s
LocalSiloHealthMonitorstalls are gone from both portals. The only stalls left are 1–2.4 s, mostly in a pod's first half hour, which is warm-up compilation, not GC thrash. Reopen if a stall of 5 s or more recurs on a pod whose[LIVENESS]line shows heap under 6 GiB.sev:M sweep, Claude Opus 5.5 (agent session).