<p>the Kubernetes HPA works correctly when load of the pod increased but after the load decreased, the scale of deployment doesn't change. This is my HPA file:</p>
<pre><code>apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: baseinformationmanagement
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: baseinformationmanagement
  minReplicas: 1
  maxReplicas: 3
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 80
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
</code></pre>
<p>My kubernetes version:</p>
<pre><code>&gt; kubectl version
Client Version: version.Info{Major:&quot;1&quot;, Minor:&quot;16&quot;, GitVersion:&quot;v1.16.1&quot;, GitCommit:&quot;d647ddbd755faf07169599a625faf302ffc34458&quot;, GitTreeState:&quot;clean&quot;, BuildDate:&quot;2019-10-02T17:01:15Z&quot;, GoVersion:&quot;go1.12.10&quot;, Compiler:&quot;gc&quot;, Platform:&quot;linux/amd64&quot;}
Server Version: version.Info{Major:&quot;1&quot;, Minor:&quot;17&quot;, GitVersion:&quot;v1.17.2&quot;, GitCommit:&quot;59603c6e503c87169aea6106f57b9f242f64df89&quot;, GitTreeState:&quot;clean&quot;, BuildDate:&quot;2020-01-18T23:22:30Z&quot;, GoVersion:&quot;go1.13.5&quot;, Compiler:&quot;gc&quot;, Platform:&quot;linux/amd64&quot;}
</code></pre>
<p>And this is my HPA describe:</p>
<pre><code>&gt; kubectl describe hpa baseinformationmanagement
Name:                                                     baseinformationmanagement
Namespace:                                                default
Labels:                                                   &lt;none&gt;
Annotations:                                              kubectl.kubernetes.io/last-applied-configuration:
                                                            {&quot;apiVersion&quot;:&quot;autoscaling/v2beta2&quot;,&quot;kind&quot;:&quot;HorizontalPodAutoscaler&quot;,&quot;metadata&quot;:{&quot;annotations&quot;:{},&quot;name&quot;:&quot;baseinformationmanagement&quot;,&quot;name...
CreationTimestamp:                                        Sun, 27 Sep 2020 06:09:07 +0000
Reference:                                                Deployment/baseinformationmanagement
Metrics:                                                  ( current / target )
  resource memory on pods  (as a percentage of request):  49% (1337899008) / 70%
  resource cpu on pods  (as a percentage of request):     2% (13m) / 50%
Min replicas:                                             1
Max replicas:                                             3
Deployment pods:                                          2 current / 2 desired
Conditions:
  Type            Status  Reason              Message
  ----            ------  ------              -------
  AbleToScale     True    ReadyForNewScale    recommended size matches current size
  ScalingActive   True    ValidMetricFound    the HPA was able to successfully calculate a replica count from memory resource utilization (percentage of request)
  ScalingLimited  False   DesiredWithinRange  the desired count is within the acceptable range
Events:           &lt;none&gt;
</code></pre>

Amir Soleimani Borujerdi
<p>Your HPA specifies both memory and CPU targets.  The <a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#algorithm-details" rel="noreferrer">Horizontal Pod Autoscaler</a> documentation notes:</p>
<blockquote>
<p>If multiple metrics are specified in a HorizontalPodAutoscaler, this calculation is done for each metric, and then the largest of the desired replica counts is chosen.</p>
</blockquote>
<p>The actual replica target is a function of the current replica count and the current and target utilization (same link):</p>
<pre><code>desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
</code></pre>
<p>For memory in particular: <code>currentReplicas</code> is 2; <code>currentMetricValue</code> is 49; <code>desiredMetricValue</code> is 80.  So the target replica count is</p>
<pre><code>desiredReplicas = ceil[       2        * (         49        /         80         )]
desiredReplicas = ceil[       2        *                   0.61                    ]
desiredReplicas = ceil[                          1.26                              ]
desiredReplicas = 2
</code></pre>
<p>Even if your service is totally idle, this will cause there to be (at least) 2 replicas, unless the service chooses to release memory back to the OS; that's usually up to the language runtime and a little out of your control.</p>
<p>Just removing the memory target and autoscaling based only on CPU might match better what you expect.</p>
