fix(docker): raise JVM direct memory above the app's baseline footprint - #1414
Merged
Conversation
Contributor
📝 WalkthroughWalkthroughDocker Compose application services now configure JVM direct memory through ChangesJVM Direct Memory Configuration
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
FelixTJDietrich
force-pushed
the
fix/jvm-direct-memory
branch
from
July 21, 2026 13:35
e7bd658 to
546bccc
Compare
The buildpack pins -XX:MaxDirectMemorySize=10M (an arbitrary Cloud Foundry inheritance), which sits just below the application server's steady off-heap NIO footprint (NATS + HTTP; measured ~14M, flat). Once it fills, Postgres can't allocate the direct buffer for its connection handshake, the Hikari pool drains, and every DB-backed request fails — including login. Not a leak or a load spike: the default is simply too low. Pin MaxDirectMemorySize to 128M (~9x the steady footprint; env-overridable via APP_MAX_DIRECT_MEMORY) on the server and worker roles, and on the preview app-server where it first surfaced. The buildpack re-budgets heap to stay within mem_limit, so the value is kept close to need rather than over-reserving heap. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012stCYrymLyX9VZ8PrPUs88
FelixTJDietrich
force-pushed
the
fix/jvm-direct-memory
branch
from
July 21, 2026 13:41
546bccc to
9bc760f
Compare
Contributor
📚 Documentation Preview
|
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.
Incident
Login (and every DB-backed request) failing. From the app-server logs:
Root cause (verified, not a bandaid)
NMT on staging shows the direct-buffer pool is ~14 MB and flat (two samples, 30s apart → no growth):
No leak, no unbounded spike — the app's steady off-heap footprint just sits above the buildpack's 10 MB default, so Postgres couldn't get the small buffer for its connection handshake and the pool drained. The 10 MB default is an arbitrary Cloud Foundry inheritance, not tuned for this app.
Sizing — why 128 MB (not 256)
On a container the memory calculator budgets direct memory against heap (
10M direct + 240M code + 250M stacks + metaspace + heap), so an oversized cap steals heap. Best practice is to size to actual usage + headroom, not a round large number (BellSoft JVM memory guide, GigaSpaces JVM tuning).Against ~14 MB steady, 128 MB is ~9× headroom — comfortably above the 10 MB that OOM'd and any observed level, with room for backfill bursts — while returning ~128 MB to heap versus a 256 MB cap. Env-overridable via
APP_MAX_DIRECT_MEMORYif a heavy backfill ever approaches it.Scope
docker/compose.app.yaml—application-server,application-workerdocker/preview/compose.app.yaml— the preview app-server (where it first surfaced, feat(webapp): practice surfaces with a focus queue and an area matrix #1347)webhook-server(core): a light publisher on a tight 1 GB limit that hasn't hit this — a conscious omission.Set via
JAVA_TOOL_OPTIONS, which the buildpack honors (detects the user flag, skips its own 10 MB, re-budgets heap withinmem_limit).Verification
Applied live on staging (that restored login): OOM/pool timeouts stopped, readiness
UP,GET /api/identity-providersreturns the provider list. This PR makes it durable.docker compose configvalidates.🤖 Generated with Claude Code