From c380bfc0cff466ad05be2540650cfa6047448c3c Mon Sep 17 00:00:00 2001 From: Ruben Hensen Date: Wed, 28 Oct 2026 14:57:34 +0100 Subject: [PATCH 1/2] Memory limits from a day of measurements --- apps/templates/authentik-helm.yaml | 4 ++++ apps/templates/cert-manager-helm.yaml | 6 ++++++ apps/templates/cloudnativepg-helm.yaml | 2 ++ apps/templates/external-secrets-helm.yaml | 6 ++++++ apps/templates/plugin-barman-cloud-helm.yaml | 2 ++ argocd/overlays/resources.patch.yaml | 18 ++++++++++++++++-- authentik/postgresql-backup.yaml | 2 ++ authentik/postgresql-cluster.yaml | 2 ++ freshrss/freshrss-deployment.yaml | 2 ++ gitea/gitea-deployment.yaml | 2 ++ immich/helm-immich.yaml | 10 ++++++++-- immich/postgresql-backup.yaml | 2 ++ immich/postgresql-cluster-17.yaml | 2 ++ mariadb-operator/operator-helm.yaml | 6 ++++++ serpbear/serpbear-deployment.yaml | 2 ++ vault/overrides.yaml | 2 ++ velero/velero-helm.yaml | 2 ++ 17 files changed, 68 insertions(+), 4 deletions(-) diff --git a/apps/templates/authentik-helm.yaml b/apps/templates/authentik-helm.yaml index 004f6e3..1a6d7c2 100644 --- a/apps/templates/authentik-helm.yaml +++ b/apps/templates/authentik-helm.yaml @@ -103,6 +103,8 @@ spec: requests: cpu: 70m memory: 560Mi + limits: + memory: 1536Mi volumes: - name: patched-ca-bundle configMap: @@ -192,6 +194,8 @@ spec: requests: cpu: 100m memory: 336Mi + limits: + memory: 1Gi volumes: - name: patched-ca-bundle configMap: diff --git a/apps/templates/cert-manager-helm.yaml b/apps/templates/cert-manager-helm.yaml index 1db4c00..b5d883f 100644 --- a/apps/templates/cert-manager-helm.yaml +++ b/apps/templates/cert-manager-helm.yaml @@ -38,16 +38,22 @@ spec: requests: cpu: 10m memory: 48Mi + limits: + memory: 128Mi cainjector: resources: requests: cpu: 10m memory: 80Mi + limits: + memory: 256Mi webhook: resources: requests: cpu: 10m memory: 32Mi + limits: + memory: 128Mi syncPolicy: syncOptions: - CreateNamespace=true diff --git a/apps/templates/cloudnativepg-helm.yaml b/apps/templates/cloudnativepg-helm.yaml index a1553f3..4e522bd 100644 --- a/apps/templates/cloudnativepg-helm.yaml +++ b/apps/templates/cloudnativepg-helm.yaml @@ -28,6 +28,8 @@ spec: requests: cpu: 10m memory: 48Mi + limits: + memory: 128Mi destination: server: https://kubernetes.default.svc namespace: cnpg-system diff --git a/apps/templates/external-secrets-helm.yaml b/apps/templates/external-secrets-helm.yaml index be4b5cd..2ef91aa 100644 --- a/apps/templates/external-secrets-helm.yaml +++ b/apps/templates/external-secrets-helm.yaml @@ -24,16 +24,22 @@ spec: requests: cpu: 20m memory: 64Mi + limits: + memory: 128Mi certController: resources: requests: cpu: 10m memory: 64Mi + limits: + memory: 128Mi webhook: resources: requests: cpu: 10m memory: 32Mi + limits: + memory: 128Mi destination: server: https://kubernetes.default.svc namespace: external-secrets diff --git a/apps/templates/plugin-barman-cloud-helm.yaml b/apps/templates/plugin-barman-cloud-helm.yaml index 1d94bbe..2fbe8f3 100644 --- a/apps/templates/plugin-barman-cloud-helm.yaml +++ b/apps/templates/plugin-barman-cloud-helm.yaml @@ -21,6 +21,8 @@ spec: requests: cpu: 10m memory: 64Mi + limits: + memory: 128Mi destination: server: https://kubernetes.default.svc namespace: cnpg-system diff --git a/argocd/overlays/resources.patch.yaml b/argocd/overlays/resources.patch.yaml index 147e74d..a6afe48 100644 --- a/argocd/overlays/resources.patch.yaml +++ b/argocd/overlays/resources.patch.yaml @@ -1,6 +1,6 @@ # Requests from what the components used on 2026-10-25 (kubectl top every -# 5 minutes; highest value plus 10%). No limits until there are daytime -# numbers, see docs/roadmap.md. +# 5 minutes; highest value plus 10%). Memory limits at about twice the +# highest value seen then or on 2026-10-27, rounded up; no CPU limits. apiVersion: apps/v1 kind: StatefulSet metadata: @@ -14,6 +14,8 @@ spec: requests: cpu: 150m memory: 704Mi + limits: + memory: 2560Mi --- apiVersion: apps/v1 kind: Deployment @@ -28,6 +30,8 @@ spec: requests: cpu: 100m memory: 128Mi + limits: + memory: 512Mi --- apiVersion: apps/v1 kind: Deployment @@ -42,6 +46,8 @@ spec: requests: cpu: 10m memory: 64Mi + limits: + memory: 256Mi --- apiVersion: apps/v1 kind: Deployment @@ -56,6 +62,8 @@ spec: requests: cpu: 20m memory: 96Mi + limits: + memory: 256Mi --- apiVersion: apps/v1 kind: Deployment @@ -70,6 +78,8 @@ spec: requests: cpu: 10m memory: 48Mi + limits: + memory: 128Mi --- apiVersion: apps/v1 kind: Deployment @@ -84,6 +94,8 @@ spec: requests: cpu: 10m memory: 48Mi + limits: + memory: 128Mi --- apiVersion: apps/v1 kind: Deployment @@ -98,3 +110,5 @@ spec: requests: cpu: 10m memory: 32Mi + limits: + memory: 128Mi diff --git a/authentik/postgresql-backup.yaml b/authentik/postgresql-backup.yaml index f47b1c4..f491184 100644 --- a/authentik/postgresql-backup.yaml +++ b/authentik/postgresql-backup.yaml @@ -67,6 +67,8 @@ spec: requests: cpu: 10m memory: 64Mi + limits: + memory: 512Mi env: # Newer boto3 adds checksums that S3-compatible stores can reject; # the plugin's docs suggest sending them only when required. diff --git a/authentik/postgresql-cluster.yaml b/authentik/postgresql-cluster.yaml index d65f352..c52cadc 100644 --- a/authentik/postgresql-cluster.yaml +++ b/authentik/postgresql-cluster.yaml @@ -18,6 +18,8 @@ spec: requests: cpu: 50m memory: 256Mi + limits: + memory: 1Gi bootstrap: initdb: database: authentik diff --git a/freshrss/freshrss-deployment.yaml b/freshrss/freshrss-deployment.yaml index bc8797c..8e708a5 100644 --- a/freshrss/freshrss-deployment.yaml +++ b/freshrss/freshrss-deployment.yaml @@ -83,6 +83,8 @@ spec: requests: cpu: 50m memory: 176Mi + limits: + memory: 512Mi # TCP, because mod_auth_openidc answers 401 to anything that isn't a # browser. readinessProbe: diff --git a/gitea/gitea-deployment.yaml b/gitea/gitea-deployment.yaml index 15cacf9..60335fe 100644 --- a/gitea/gitea-deployment.yaml +++ b/gitea/gitea-deployment.yaml @@ -54,6 +54,8 @@ spec: requests: cpu: 20m memory: 336Mi + limits: + memory: 1Gi # /api/healthz checks the database and the cache. readinessProbe: httpGet: diff --git a/immich/helm-immich.yaml b/immich/helm-immich.yaml index a9ab83a..2aee557 100644 --- a/immich/helm-immich.yaml +++ b/immich/helm-immich.yaml @@ -67,6 +67,8 @@ spec: requests: cpu: 10m memory: 64Mi + limits: + memory: 256Mi image: repository: docker.io/valkey/valkey tag: 9.1.2-alpine@sha256:48332870af354a799964c0012ae1194a0bf2bf894eb508f945810596dc2d8d11 @@ -93,6 +95,8 @@ spec: requests: cpu: 100m memory: 1280Mi + limits: + memory: 3Gi # Node trusts its built-in roots, which still include the # ones above the compromised eMudhra intermediates. Use # patched-ca-bundle through OpenSSL until Node ships a fix. @@ -117,12 +121,14 @@ spec: image: repository: ghcr.io/immich-app/immich-machine-learning pullPolicy: IfNotPresent - # Idle at night (234Mi); the models take over a GiB when - # it works. + # Idle at 240Mi; 884Mi with CLIP, face recognition and + # OCR loaded (2026-10-28, a test image through each). resources: requests: cpu: 50m memory: 1Gi + limits: + memory: 2Gi env: TRANSFORMERS_CACHE: /cache HF_XET_CACHE: /cache/huggingface-xet diff --git a/immich/postgresql-backup.yaml b/immich/postgresql-backup.yaml index cbd42eb..3f15f26 100644 --- a/immich/postgresql-backup.yaml +++ b/immich/postgresql-backup.yaml @@ -71,6 +71,8 @@ spec: requests: cpu: 10m memory: 64Mi + limits: + memory: 512Mi env: # Newer boto3 adds checksums that S3-compatible stores can reject; # the plugin's docs suggest sending them only when required. diff --git a/immich/postgresql-cluster-17.yaml b/immich/postgresql-cluster-17.yaml index eb29418..de94ef3 100644 --- a/immich/postgresql-cluster-17.yaml +++ b/immich/postgresql-cluster-17.yaml @@ -13,6 +13,8 @@ spec: requests: cpu: 20m memory: 320Mi + limits: + memory: 1Gi postgresql: shared_preload_libraries: diff --git a/mariadb-operator/operator-helm.yaml b/mariadb-operator/operator-helm.yaml index d8c14e7..b4f048a 100644 --- a/mariadb-operator/operator-helm.yaml +++ b/mariadb-operator/operator-helm.yaml @@ -20,6 +20,8 @@ spec: requests: cpu: 10m memory: 48Mi + limits: + memory: 128Mi metrics: enabled: true serviceMonitor: @@ -29,6 +31,8 @@ spec: requests: cpu: 10m memory: 32Mi + limits: + memory: 128Mi serviceMonitor: enabled: false certController: @@ -36,6 +40,8 @@ spec: requests: cpu: 10m memory: 32Mi + limits: + memory: 128Mi serviceMonitor: enabled: false syncPolicy: diff --git a/serpbear/serpbear-deployment.yaml b/serpbear/serpbear-deployment.yaml index 46bae79..bb70434 100644 --- a/serpbear/serpbear-deployment.yaml +++ b/serpbear/serpbear-deployment.yaml @@ -60,6 +60,8 @@ spec: requests: cpu: 10m memory: 160Mi + limits: + memory: 512Mi readinessProbe: httpGet: path: /login diff --git a/vault/overrides.yaml b/vault/overrides.yaml index 0bc78b5..4047bee 100644 --- a/vault/overrides.yaml +++ b/vault/overrides.yaml @@ -7,6 +7,8 @@ injector: requests: cpu: 10m memory: 32Mi + limits: + memory: 128Mi # The chart's default anti-affinity forbids two injector pods on one # node, so on this single node a rolling update can never start the new # pod while the old one runs. Recreate removes the old pod first, which diff --git a/velero/velero-helm.yaml b/velero/velero-helm.yaml index c94c5fa..e8495c2 100644 --- a/velero/velero-helm.yaml +++ b/velero/velero-helm.yaml @@ -71,6 +71,8 @@ spec: requests: cpu: 10m memory: 64Mi + limits: + memory: 128Mi # 512Mi got the server OOMKilled 314 times, including halfway # through a backup of ~14.7k items. resources: From 1f894996e63bea75e5aa8ca5f927424392353321 Mon Sep 17 00:00:00 2001 From: Ruben Hensen Date: Wed, 28 Oct 2026 14:58:03 +0100 Subject: [PATCH 2/2] docs: memory limits on the roadmap --- docs/roadmap.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/roadmap.md b/docs/roadmap.md index ae3b7d9..e8d353e 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -341,8 +341,13 @@ Counted 2026-10-25 over the 73 running containers: requested. Still without requests: Longhorn (22 containers, its chart), the Vault servers, the LDAP outpost, immich's PG14 cluster and three in kube-system -- [ ] Memory limits, once there are daytime numbers: the night ones miss - immich's machine learning at work (it idles at 234Mi) +- [x] Memory limits: PR #58, for everything that got requests in #33. + About twice the highest memory from `kubectl top` every 5 minutes from + 2026-10-26 22:29 to 2026-10-27 21:55 UTC or the night of #33, rounded + up; no CPU limits. No OOM kills that day. immich's machine learning + sat idle all day (240Mi), so on 2026-10-28 a test image went through + CLIP, face recognition and OCR inside the container: 884Mi with all + three loaded, limit 2Gi - [x] WordPress (scoutingmbg.nl) was OOMKilled at 08:27:59 UTC on 2026-10-25, its third restart: a crawler asked for 88 pages and assets within a few seconds (normally ~6 a minute), Apache started a PHP worker