Back to all use cases
RemediationSoftware / Digital PlatformsCloud / Kubernetes

The runtime sized itself for the host, then the cgroup killed it

OM
Online Marketplace Operator
DockerKubernetesPostgreSQLRedis
Result

The recurring OOMKills were eliminated, and memory limits are now derived from measured usage plus headroom instead of being incremented after each incident.

Overview

OOMKilled with no application-level out-of-memory error usually means the runtime inside the container never learned about the container's memory limit. A JVM on an old base image, or a Node process with a manually set max-old-space-size copied from a bigger host, will size itself against total host memory and get killed by the kernel long before it thinks it is under pressure.

Challenge

Several services were being OOMKilled multiple times per day with no heap dump and no application error — the kernel killed the process before the runtime could report anything. Some services ran a JVM on a base image predating reliable container awareness, and others ran Node with a heap ceiling set higher than the container's own limit. Raising the memory limits had been tried and simply moved the threshold.

Environment

Containerized JVM and Node services on Kubernetes, built from a mix of base images maintained by different teams.

Approach

AceMQ mapped each affected container's runtime memory configuration against its cgroup limit to identify which processes were unaware of the limit and which were simply misconfigured. Both classes were fixed at the image and manifest level rather than by raising limits until the killing stopped.

Solution

  • 1
    Compared each runtime's effective memory configuration against the container's actual cgroup limit
  • 2
    Updated base images to runtime versions that honor cgroup limits, with explicit percentage-based heap settings
  • 3
    Removed hardcoded heap ceilings that exceeded the container memory limit
  • 4
    Accounted for off-heap, metaspace, and thread stack memory in the limit rather than heap alone
  • 5
    Added container-level memory metrics and OOMKill alerting distinct from application error alerting
  • 6
    Load-tested each service to establish a limit from measured peak rather than from trial and error

Outcome

The recurring OOMKills were eliminated, and memory limits are now derived from measured usage plus headroom instead of being incremented after each incident.

Technologies

DockerKubernetesPostgreSQLRedis

Facing a Docker Production Issue?

AceMQ's senior Docker engineers have handled this exact type of engagement before. Whether you need architectural guidance, hands-on remediation, or an ongoing managed partnership, we're ready to help.