<p>I dig into Kubernetes resource restrictions and have a hard time to understand what CPU <code>limits</code> are for. I know Kubernetes passes <code>requests</code> and <code>limits</code> down to the (in my case) Docker runtime.</p>

<p><strong>Example</strong>: I have 1 Node with 1 CPU and 2 Pods with CPU <code>requests: 500m</code> and <code>limits: 800m</code>. In Docker, this results in (<code>500m -&gt; 0.5 * 1024 = 512</code>) <code>--cpu-shares=512</code> and (<code>800m -&gt; 800 * 100</code>) <code>--cpu-quota=80000</code>. The pods get allocated by Kube scheduler because the <code>requests</code> sum does not exceed 100% of the node's capacity; in terms of <code>limits</code> the node is overcommited.</p>

<p>The above allows each container to get 80ms CPU time per 100ms period (the default). As soon as the CPU usage is 100%, the CPU time is shared between the containers based on their weight, expressed in CPU shares. Which would be 50% for each container according to the base value of 1024 and a 512 share fo each. At this point - in my understanding - the <code>limits</code> have no more relevance because none of the containers can get its 80ms anymore. They both would get 50ms. So no matter how much <code>limits</code> I define, when usage reaches critical 100%, it's partitioned by <code>requests</code> anyway.</p>

<p>This makes me wonder: Why should I define CPU <code>limits</code> in the first place, and does overcommitment make any difference at all? <code>requests</code> on the other hand in terms of "<em>how much share do I get when everything is in use</em>" is completely understandable.</p>

<p>One reason to set CPU limits is that, if you set CPU request == limit <em>and</em> memory request == limit, your pod is assigned a Quality of Service class = <code>Guaranteed</code>, <a href="https://kubernetes.io/docs/tasks/administer-cluster/out-of-resource/#node-oom-behavior" rel="nofollow noreferrer">which makes it less likely to be OOMKilled if the node runs out of memory</a>. Here I quote from the Kubernetes doc <a href="https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/" rel="nofollow noreferrer">Configure Quality of Service for Pods</a>:</p>
<blockquote>
<p>For a Pod to be given a QoS class of Guaranteed:</p>
<ul>
<li>Every Container in the Pod must have a memory limit and a memory request, and they must be the same.</li>
<li>Every Container in the Pod must have a CPU limit and a CPU request, and they must be the same.</li>
</ul>
</blockquote>
<p>Another benefit of using the <code>Guaranteed</code> QoS class is that it allows you to lock exclusive CPUs for the pod, which is critical for certain kinds of low-latency programs. Quote from <a href="https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/" rel="nofollow noreferrer">Control CPU Management Policies</a>:</p>
<blockquote>
<p>The <code>static</code> CPU management policy allows containers in <code>Guaranteed</code> pods with integer CPU <code>requests</code> access to exclusive CPUs on the node. ... Only containers that are both part of a <code>Guaranteed</code> pod and have integer CPU <code>requests</code> are assigned exclusive CPUs.</p>
</blockquote>
