<p>I have a java application running on K8s with min:2 and max:6 pods in a deployment.
heap min:256Mb, heap max: 512Mb. request and limit memory is 1Gi
Here is the hpa spec:</p>
<pre class="lang-yaml prettyprint-override"><code>  spec:
  scaleTargetRef:
    apiVersion: extensions/v1beta1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 6
  metrics:
    - type: Resource
      resource:
        name: cpu
        targetAverageUtilization: 60
    - type: Resource
      resource:
        name: memory
        targetAverageUtilization: 60
</code></pre>
<p>During the performance test, I have noticed that the deployment is trying to scale up very aggressively.</p>
<p>When there is no load, the memory utilization is around 33%, and according to this link <a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/" rel="nofollow noreferrer">https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/</a>
the formula to get a rough idea of the desired pods is <code>desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]</code></p>
<p>From the K8s monitoring, I have noticed that it tries to scale up when memory utilization increase to around 40%. if i understand correctly how the above formula works, <code>desiredReplicas = ceil[2*(0.4/0.6)] = 2</code>, then it should not scale up.</p>
<p>Do I understand it correctly?</p>

<p>That looks correct but I'm taking a while guess because you didn't share the output of <code>kubectl top pods</code>. It could be that your deployment is not scaling because of memory utilization but because of CPU utilization first.</p>
<p>If you see the <a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-multiple-metrics" rel="nofollow noreferrer">docs</a> the first metrics that hits the target starts the autoscaling process:</p>
<blockquote>
<p>Kubernetes 1.6 adds support for scaling based on multiple metrics. You can use the autoscaling/v2beta2 API version to specify multiple metrics for the Horizontal Pod Autoscaler to scale on. Then, the Horizontal Pod Autoscaler controller will evaluate each metric, and propose a new scale based on that metric. The largest of the proposed scales will be used as the new scale</p>
</blockquote>
<p>You could also try a Value metric for your memory target to troubleshoot:</p>
<pre class="lang-yaml prettyprint-override"><code>  metrics:
    - type: Resource
      resource:
        name: cpu
        targetAverageUtilization: 60
    - type: Resource
      resource:
        name: memory
        targetAverageValue: 700M
</code></pre>
<p>A good way to see the current metrics is to just get the status on a full output on the HPA:</p>
<pre class="lang-sh prettyprint-override"><code>$ kubectl get hpa &lt;hpa-name&gt; -o=yaml
</code></pre>
