bcos.dev: no container memory limits — every JVM sizes its heap to 3.9GB, causing host-wide OOM cascades #6
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
All 56 containers on bcos.dev (
.251) run withMemLimit=0. Because the JVM'sUseContainerSupporthas no limit to detect, it falls back to host RAM and sizesMaxHeapSizeto 25% of 15.6GB = 3.9GB per service. With 26 JVM-class containers, that is ~100GB of theoretical heap entitlement on a 15.6GB box.They coexist only because they don't all claim it simultaneously. When one service takes sustained load it grows unbounded and drags the host into
global_oom, killing bystanders by OOM score.Impact (observed 2026-07-18)
guide.bcos.devreturned 502 for a period this morning. Root cause was a global OOM burst, not a Guide fault. Kernel log shows repeated kills roughly every 5 minutes:constraint=CONSTRAINT_NONE+global_oomconfirms host-wide exhaustion, not a per-cgroup limit.Cumulative restart counts show this is chronic, not a one-off:
Evidence
Inside
hiveiq-incident-blue(Temurin 21.0.11):Config tree
hiveiq-openmetal-dev/contains zero occurrences ofmem_limit,resources:,MaxRAMPercentage, orXmx.Current footprint
14.32 GiB used across 56 containers on a 15.61 GiB box, with zero swap. Largest consumers:
Proposed fix
Memory limits do not create capacity — they contain blast radius, converting a host-wide outage into a single-container restart, and they make each JVM size its heap correctly. Limits are ceilings, not reservations, so the sum may exceed physical RAM.
mem_limitto thex-*-baseanchors inhiveiq-openmetal-dev/hiveops/instances/dev/compose/*.yml.JAVA_TOOL_OPTIONS=-XX:MaxRAMPercentage=50so heap is bounded by the container limit.hiveiq-auth-green+hiveiq-devices-backend-green(~985MB reclaimed; blue/green does not need both hot on dev).hiveiq-ollama(672MB) is still in use on this box.Out of scope / follow-ups
hiveiq-incident-blueemits Spring SecurityDEBUGfor every heartbeat and journal-event POST despiteSPRING_PROFILES_ACTIVE=prod. Not set in compose, so it originates from Spring Cloud Config or the image default. Worth a separate ticket — it is significant allocation churn on a box with no headroom./data/hiveiq35%); ~31GB of dangling images is reclaimable but unrelated to this incident.Filed by session 1.
Phase 1 done + PR open
Reclaimed ~474Mi on
.251: stoppedhiveiq-devices-backend-green(available 408Mi -> 882Mi). Verified by behaviour, not status code — blue processed 320 heartbeat lines in the following 60s, devices API and SPA unaffected.PR: hiveiq-ops/hiveiq-openmetal-dev#10 —
mem_limit+MaxRAMPercentage=50on kafka, incident b/g, recon, auth b/g. Not yet merged, and merging does not deploy (the.251tree is a hand-managed copy, not a git checkout).Correction to this issue's framing
The original text called the green slots "idle standby". That is wrong, and it matters:
hiveiq-auth-greenis the active auth backend per the live nginx map, not blue. Stopping it would have taken down auth for all of bcos.dev.hiveiq-auth,hiveiq-devices-backend,hiveiq-incident), and Docker DNS round-robins across it. Measured:hiveiq-authresolved to blue 3/10 and green 7/10. The nginx$*_backendmap only governs traffic that passes through nginx; anything resolving the alias hits both colours regardless of which is "active".So
devices-backend-greenwas serving roughly half the alias-addressed internal traffic — including agent heartbeats — right up to being stopped. Blue absorbed it cleanly, but it was not a cold spare.Consequence for anyone acting on this issue: do not assume a colour is idle. Check the nginx map AND the shared alias before stopping anything.
Not done
auth-bluenot stopped (~506MB). It serves live internal traffic via the alias. Stopping it shifts all internal auth to green one day after cutover and removes the rollback slot..251. Separate change.Separate bug found
devices-bluelogsjava.net.UnknownHostException: kafka— consumers point atkafka:29092, container ishiveiq-kafka. Devices' Kafka consumers have never connected. Plausibly related to kafka's 127 restarts. Needs its own ticket.Not a factor
Disk. Root 38%,
/data/hiveiq35%. ~31GB of dangling images is reclaimable but irrelevant to this.