Introduction
Many teams running Rust services on Kubernetes face a frustrating situation: monitoring dashboards show memory usage looks fine, yet the pod suddenly gets OOMKilled. This often happens without any clear warning and leads to confusion, restarts, and production incidents.
In simple terms, Kubernetes and Rust view memory very differently. Rust focuses on performance and memory reuse, while Kubernetes enforces hard memory limits. When these two perspectives meet, an app can be killed even though it appears healthy. This article explains why this happens, using real-world examples, simple language, and practical guidance.
What Developers Usually See in Production
Before diving into causes, here is what teams commonly report:
The Rust app runs at ~350 MB according to dashboards
The pod has a 512 MB memory limit
Traffic spikes slightly
The pod is OOMKilled
This leads to a common reaction: “But memory was under the limit.”
Wrong Assumption vs Reality
Wrong assumption: The app exceeded the memory limit only when dashboards show it exceeding the limit.
Reality: Kubernetes kills the container the moment it exceeds the limit, even briefly, and metrics often lag behind real usage.
Think of it like a speed camera: you may see your average speed is fine, but a short spike still triggers a ticket.
How Kubernetes Decides to OOMKill a Pod
Kubernetes enforces memory limits using Linux cgroups.
Key points:
Memory limits are strict, not flexible
Even a short spike can trigger a kill
There is no garbage collection grace period
Real-world analogy:
“Your app is allowed into a room with a strict headcount. Even if someone steps in for a few seconds, security throws everyone out immediately.”
Why Rust Memory Spikes Are Hard to See
Rust allocates memory aggressively for performance and reuses it.
What actually happens:
Memory is reserved quickly during spikes
The allocator keeps memory for reuse
Kubernetes counts reserved memory as fully used
What developers see:
“Memory looks stable, but the pod keeps dying.”
The spike already happened. The metrics just did not catch it in time.
Startup Spikes Are a Common Killer
Rust apps often allocate a lot of memory during startup:
Initializing caches
Loading configuration
Creating thread pools
Building internal buffers
Before vs After Story
Before:
“Our Rust service never even started in Kubernetes.”
Join the conversation! Your thoughts help the community grow.