Skip to content

Commit 12e2998

Browse files
committed
ingest(infrastructure): host-to-pod memory-limit sizing (folded from #2, dedup)
1 parent 7044cb3 commit 12e2998

1 file changed

Lines changed: 3 additions & 0 deletions

File tree

wiki/infrastructure/containers/resource-limits-and-probes.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ storm; traffic reaches pods that are not ready to serve.
6868
| Runtime OOMKilled while its configured heap is below the limit | Non-heap memory (metaspace, thread stacks, direct buffers) pushed the total over: [backend-java-runtime-threads-and-memory] |
6969
| Pod evicted rather than OOMKilled | Node memory pressure evicting by QoS order — set memory request = limit to move the workload to Guaranteed |
7070
| App has no HTTP server to probe | Use an exec or TCP probe against the process itself; the process-only rule for liveness is unchanged |
71+
| Process moved from a host/VM into a pod is OOMKilled at a limit that "should be plenty" | "Ran fine on the host" is not evidence — the host enforced no limit. Measure the real workload's peak (`kubectl top`, `container_memory_working_set_bytes`) before sizing. If memory scales with input size (e.g. a default client-side DB cursor buffers the whole result set on execute), bound the working set (server-side/streaming cursor, chunked `fetchmany`) or size the limit to the measured peak of the largest real input |
7172

7273
## Instead of
7374

@@ -77,9 +78,11 @@ storm; traffic reaches pods that are not ready to serve.
7778
| Copy resource limits from a blog post or another service | Measure this service's usage; set requests from p99 + headroom | Limits sized for someone else's workload produce OOMKills or throttling for yours |
7879
| Leave requests unset "for flexibility" | Set requests on every container | Unset requests = BestEffort: first evicted, and the scheduler overcommits the node |
7980
| Stretch liveness timeouts so the app survives boot | Add a startup probe sized for worst-case boot; keep liveness at steady-state timing | Boot-sized liveness leaves real steady-state hangs undetected for the whole boot window |
81+
| Size a migrated workload's memory limit from "it ran fine on the host" | Measure the workload's actual peak in-container on real data, then set limit = peak + headroom | The host never enforced a limit, so its success carries no information about the peak; data-proportional consumers (whole-result-set DB cursors, in-memory file builds) only reveal their peak under the real input |
8082

8183
## Sources
8284

8385
- https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ — probe purposes, failureThreshold/periodSeconds, startup probes protecting slow boots, readiness removes from endpoints without restart
8486
- https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ — requests drive scheduling, limits enforced at runtime; memory over limit = OOM kill, CPU over limit = throttling
8587
- https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/ — Guaranteed/Burstable/BestEffort assignment and eviction order
88+
- https://www.psycopg.org/docs/usage.html#server-side-cursors — a default (client-side) cursor loads the whole result set client-side; server-side cursors transfer data in controlled amounts

0 commit comments

Comments
 (0)