feat(deployment): make backend jvm options configurable - #7239
Conversation
|
Claude encountered an error after 3m 27s —— View job I'll analyze this and get back to you. |
|
Claude encountered an error after 3m 10s —— View job I'll analyze this and get back to you. |
|
Claude finished @clonder's task in 2m 39s —— View job Review:
|
| # Smaller backend heap, previews share one cluster | ||
| backendMaxRamPercentage: 25 |
There was a problem hiding this comment.
Preview resources.backend.limits.memory is 3Gi, so this drops the backend heap ceiling from ~2.25Gi to ~768Mi. Two things worth checking before merging:
MaxRAMPercentageis a ceiling, not a reservation. Combined with the already-setMaxHeapFreeRatio=5 -XX:MinHeapFreeRatio=2, the JVM already returns unused heap to the OS, so the steady-state RSS saving on the shared cluster may be near zero — the flag only bites once the heap actually needs to grow. What it does change is where the backend throwsOutOfMemoryError.- Previews are the main pre-merge test environment. With 25% here and 75% in prod, a preview can OOM on a workload (large submission, big seqSet export) that prod handles fine, and the failure will look like an app bug. If the goal is to bound what a preview can consume on the shared cluster, lowering
resources.backend.limits.memoryin this same file is the knob that actually caps the container footprint — and the heap then scales with it automatically at 75%.
Was the 25% figure validated against an actual preview run (e2e or a manual submission), or only via helm template? The PR checklist says manual testing was helm lint/template only, which doesn't cover the runtime effect that is the entire point of the change.
There was a problem hiding this comment.
If 25% is the default, I guess no validation is needed, since setting 25% is actually as if we wouldn't change anything, right? That's what I got from the PR description.
fhennig
left a comment
There was a problem hiding this comment.
Looks good to me!
I guess there could be more written about why we picked 75% as the default, but I'm also ok with just picking it now and running with it - as you said it's already configured like this on main. It's hard to pick good defaults.
Another choice would be 25%, the JVM default, if we really wanted to play it safe.
But I'm fine with 75%
I'm approving but maybe wait a few days to give Cornelius some time to have a look as well!
|
Claude finished @anna-parker's task in 2m 45s —— View job Review:
|
| "minimum": 1, | ||
| "maximum": 100, | ||
| "default": 75, | ||
| "description": "Share of the backend container memory limit the JVM may use as heap, passed as -XX:MaxRAMPercentage." |
There was a problem hiding this comment.
The generated docs table only renders Field / Type / Default / Description (docs/src/components/SchemaDocs.astro:130-145) — minimum and maximum are not emitted, so an operator reading the Helm chart config page has no idea 1–100 is the accepted range, or what the value is a percentage of. Worth putting both into the description:
| "description": "Share of the backend container memory limit the JVM may use as heap, passed as -XX:MaxRAMPercentage." | |
| "description": "Share of the backend container memory limit (`resources.backend.limits.memory`) the JVM may use as heap, passed as -XX:MaxRAMPercentage. Must be between 1 and 100." |
| # semantics, mirror it in the test task in backend/build.gradle | ||
| - name: JVM_OPTS | ||
| value: -XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+UseG1GC -XX:+UseCompactObjectHeaders -XX:MaxHeapFreeRatio=5 -XX:MinHeapFreeRatio=2 | ||
| value: -XX:+UseContainerSupport -XX:MaxRAMPercentage={{ .Values.backendMaxRamPercentage }} -XX:+UseG1GC -XX:+UseCompactObjectHeaders -XX:MaxHeapFreeRatio=5 -XX:MinHeapFreeRatio=2 |
There was a problem hiding this comment.
One gap the schema doesn't close: backendMaxRamPercentage is not in the schema's root required list (which is just ["name"], values.schema.json:1764). Helm's coalesce deletes keys set to null in an override file before validation runs, so backendMaxRamPercentage: null passes lint and renders -XX:MaxRAMPercentage= — the JVM then exits at startup with Improperly specified VM option and the pod crashloops with no hint that a values key caused it. A template-side fallback makes that impossible:
| value: -XX:+UseContainerSupport -XX:MaxRAMPercentage={{ .Values.backendMaxRamPercentage }} -XX:+UseG1GC -XX:+UseCompactObjectHeaders -XX:MaxHeapFreeRatio=5 -XX:MinHeapFreeRatio=2 | |
| value: -XX:+UseContainerSupport -XX:MaxRAMPercentage={{ .Values.backendMaxRamPercentage | default 75 }} -XX:+UseG1GC -XX:+UseCompactObjectHeaders -XX:MaxHeapFreeRatio=5 -XX:MinHeapFreeRatio=2 |
(Adding the key to the root required array instead is equally fine, and fails louder at install time rather than silently falling back.)
| # semantics, mirror it in the test task in backend/build.gradle | ||
| - name: JVM_OPTS | ||
| value: -XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+UseG1GC -XX:+UseCompactObjectHeaders -XX:MaxHeapFreeRatio=5 -XX:MinHeapFreeRatio=2 | ||
| value: -XX:+UseContainerSupport -XX:MaxRAMPercentage={{ .Values.backendMaxRamPercentage }} -XX:+UseG1GC -XX:+UseCompactObjectHeaders -XX:MaxHeapFreeRatio=5 -XX:MinHeapFreeRatio=2 |
There was a problem hiding this comment.
To avoid having to alter this again in the future for another arg that can be customized, I'd say we should just add an extra args placeholder that can be filled with whatever the maintainer wants to put in.
This should come last after all the other args so that one can override prior default args. Default should empty string if unset.
corneliusroemer
left a comment
There was a problem hiding this comment.
Thanks! I think there might have been a misunderstanding. By "We could make the JVM args configurable so that people can give as much RAM as they want." I meant to allow passing arbitrary JVM args through helm chart values rather than just the max ram percentage - this would avoid us having to do this for every arg one wants to override in the future.
follow up to #7077 (comment). the backend heap share becomes a
backendMaxRamPercentagevalue (default 75, same as main, the other jvm flags stay fixed in the template), andvalues_preview_server.yamlsets 25 so previews go back to the jvm default heap. checked withhelm lint --strictandhelm templatefor default, e2e and preview values, the only rendered difference to main isMaxRAMPercentage=75.0becoming=75. the new top level key changesvaluesHashon every deployment, so the first upgrade after this restarts all pods once. lapis keeps its own hardcodedJVM_OPTS, out of scope here.PR Checklist
The implemented feature is covered by appropriate, automated tests.🚀 Preview: Add
previewlabel to enable