fix: give the vector log collector a 512 MiB memory limit #4

Merged
igor merged 1 commits from fix/vector-memory-limit into main 2026-09-19 09:56:36 +00:00
4 changed files with 24 additions and 18 deletions
Showing only changes of commit b86863e6f0 - Show all commits
+11 -8
View File
@@ -1,6 +1,6 @@
# supaspin # supaspin
Version 1.1.1 Version 1.1.2
Create, list, show and delete throwaway [Supabase](https://supabase.com) instances on a Create, list, show and delete throwaway [Supabase](https://supabase.com) instances on a
single-node [microk8s](https://microk8s.io) server, from a terminal menu. single-node [microk8s](https://microk8s.io) server, from a terminal menu.
@@ -17,7 +17,7 @@ endangering them. Nothing in it is specific to any one app.
| Postgres | `<LAN IP>:544N` (instance 1 → 5441, 2 → 5442, …), bound on the LAN address only | | Postgres | `<LAN IP>:544N` (instance 1 → 5441, 2 → 5442, …), bound on the LAN address only |
| Studio (admin UI) | `http://<LAN IP>:300N` (3001, 3002, …), not on the public hostname | | Studio (admin UI) | `http://<LAN IP>:300N` (3001, 3002, …), not on the public hostname |
| Disk | fixed-size ext4 image files, mounted at boot: **db 2 GB, storage 1 GB, every other volume 256 MB** | | Disk | fixed-size ext4 image files, mounted at boot: **db 2 GB, storage 1 GB, every other volume 256 MB** |
| Memory | limits add up to **5.625 GiB** per instance, requests to 1.875 GiB (table below) | | Memory | limits add up to **5.875 GiB** per instance, requests to 1.875 GiB (table below) |
| Priority | pods run at priority -100 (`supaspin-low`); when the server runs short of memory they are evicted first and never evict anyone else | | Priority | pods run at priority -100 (`supaspin-low`); when the server runs short of memory they are evicted first and never evict anyone else |
| Secrets | generated fresh per instance: JWT secret, anon and service keys, Postgres password, Studio password, and the internal keys | | Secrets | generated fresh per instance: JWT secret, anon and service keys, Postgres password, Studio password, and the internal keys |
| Uploads | stored in the instance's own storage image (no MinIO); deleted with the instance | | Uploads | stored in the instance's own storage image (no MinIO); deleted with the instance |
@@ -108,7 +108,7 @@ sudo supaspin push-env N TARGET [--port P] [--key FILE] [--dry-run] # see "Cop
sudo supaspin delete N [--yes] sudo supaspin delete N [--yes]
sudo supaspin mail # change the saved default mail settings sudo supaspin mail # change the saved default mail settings
sudo supaspin setup # change settings sudo supaspin setup # change settings
supaspin --version # prints "supaspin 1.1.1" supaspin --version # prints "supaspin 1.1.2"
``` ```
### Connecting your app ### Connecting your app
@@ -215,12 +215,15 @@ run `supaspin delete N` to clean up.
| analytics | 128 MiB | 768 MiB | | analytics | 128 MiB | 768 MiB |
| kong | 128 MiB | 512 MiB | | kong | 128 MiB | 512 MiB |
| realtime | 128 MiB | 384 MiB | | realtime | 128 MiB | 384 MiB |
| auth, functions, imgproxy, meta, rest, storage, studio, vector | 128 MiB each | 256 MiB each | | vector | 128 MiB | 512 MiB |
| **Total** | **1.875 GiB** | **5.625 GiB** | | auth, functions, imgproxy, meta, rest, storage, studio | 128 MiB each | 256 MiB each |
| **Total** | **1.875 GiB** | **5.875 GiB** |
Most limits are half of what a production setup would use. Analytics and realtime are higher: at Most limits are half of what a production setup would use. Analytics, realtime and vector are higher:
half of production they were killed for running out of memory in a loop (measured on a fresh at half of production they were killed for running out of memory in a loop (measured on a fresh
instance: analytics peaks at 624 MiB, realtime at 280 MiB). Image resizing (imgproxy) reads the instance: analytics peaks at 624 MiB, realtime at 280 MiB). Vector is the log collector: it reads the
log files of every pod on the server, not only its own instance's, so its memory need follows the
server's total log volume; at 256 MiB it was killed in a loop on one instance and used 89% on another. Image resizing (imgproxy) reads the
uploads from the storage volume, so it has no image of its own. uploads from the storage volume, so it has no image of its own.
## Troubleshooting ## Troubleshooting
+1 -1
View File
@@ -1 +1 @@
1.1.1 1.1.2
+7 -5
View File
@@ -32,7 +32,7 @@ import tty
import yaml import yaml
VERSION = "1.1.1" VERSION = "1.1.2"
CONFIG_PATH = os.environ.get("SUPASPIN_CONFIG", "/etc/supaspin/config.yaml") CONFIG_PATH = os.environ.get("SUPASPIN_CONFIG", "/etc/supaspin/config.yaml")
STATE_DIR = os.environ.get("SUPASPIN_STATE", "/var/lib/supaspin") STATE_DIR = os.environ.get("SUPASPIN_STATE", "/var/lib/supaspin")
CHART_REPO = "https://supabase-community.github.io/supabase-kubernetes" CHART_REPO = "https://supabase-community.github.io/supabase-kubernetes"
@@ -53,12 +53,14 @@ VOLUMES = {"db": 2048, "storage": 1024, "functions": 256,
DB_OWNED = ("db", "pgsodium") DB_OWNED = ("db", "pgsodium")
DB_UID, DB_GID = 100, 101 DB_UID, DB_GID = 100, 101
# Memory per service: (request MiB, limit MiB). Half of maralago.ru production, except analytics # Memory per service: (request MiB, limit MiB). Half of maralago.ru production, except analytics,
# and realtime: at half of production they were killed for running out of memory in a loop # realtime and vector: at half of production they were killed for running out of memory in a loop
# (measured on a fresh instance: analytics peaks at 624 MiB, realtime at 280 MiB). # (measured on a fresh instance: analytics peaks at 624 MiB, realtime at 280 MiB; vector reads the log
# files of every pod on the node, not only its own instance's, and was killed at 256 MiB on 2026-09-19).
SERVICES = ["db", "analytics", "kong", "auth", "functions", "imgproxy", "meta", SERVICES = ["db", "analytics", "kong", "auth", "functions", "imgproxy", "meta",
"realtime", "rest", "storage", "studio", "vector"] "realtime", "rest", "storage", "studio", "vector"]
MEMORY = {"db": (512, 2048), "analytics": (128, 768), "kong": (128, 512), "realtime": (128, 384)} MEMORY = {"db": (512, 2048), "analytics": (128, 768), "kong": (128, 512), "realtime": (128, 384),
"vector": (128, 512)}
DEFAULT_MEMORY = (128, 256) DEFAULT_MEMORY = (128, 256)
DEFAULT_MAIL = {"host": "smtp.example.com", "port": 587, "user": "", "password": "", DEFAULT_MAIL = {"host": "smtp.example.com", "port": 587, "user": "", "password": "",
+5 -4
View File
@@ -90,13 +90,14 @@ class Values(unittest.TestCase):
def test_memory_caps_add_up(self): def test_memory_caps_add_up(self):
req, lim = sp.total_memory_mib() req, lim = sp.total_memory_mib()
# db 2048, analytics 768, kong 512, realtime 384, the other eight 256 each # db 2048, analytics 768, kong 512, realtime 384, vector 512, the other seven 256 each
self.assertEqual(lim, 2048 + 768 + 512 + 384 + 8 * 256) self.assertEqual(lim, 2048 + 768 + 512 + 384 + 512 + 7 * 256)
self.assertEqual(lim / 1024, 5.625) self.assertEqual(lim / 1024, 5.875)
self.assertEqual(req, 512 + 11 * 128) # 1.875 GiB self.assertEqual(req, 512 + 11 * 128) # 1.875 GiB
# analytics and realtime were killed for running out of memory at half of production # analytics, realtime and vector were killed for running out of memory at half of production
self.assertGreaterEqual(sp.MEMORY["analytics"][1], 768) self.assertGreaterEqual(sp.MEMORY["analytics"][1], 768)
self.assertGreaterEqual(sp.MEMORY["realtime"][1], 384) self.assertGreaterEqual(sp.MEMORY["realtime"][1], 384)
self.assertGreaterEqual(sp.MEMORY["vector"][1], 512)
self.assertEqual(req / 1024, 1.875) self.assertEqual(req / 1024, 1.875)
for svc in sp.SERVICES: for svc in sp.SERVICES:
self.assertEqual(self.v["deployment"][svc]["priorityClassName"], "supaspin-low") self.assertEqual(self.v["deployment"][svc]["priorityClassName"], "supaspin-low")