{"slug": "adding-per-container-cpu-memory-limits-to-docker-compose-for-pgvector", "title": "Adding Per‑Container CPU & Memory Limits to Docker‑Compose for pgvector", "summary": "A developer fixed intermittent 502 errors and OOM kills in a local pgvector-based Docker Compose stack by adding per-container resource caps to the PostgreSQL service. The fix sets mem_limit: 512m and cpus: \"1\" on the pgvector/pgvector:pg16 container after discovering that the deploy.resources.limits block is silently ignored outside Swarm mode and that Compose file version 2.4 is required for the top-level keys to take effect. Docker inspect confirmed the 512 MiB memory and 1 CPU limits, and docker stats showed the container holding at roughly 210 MiB.", "body_md": "**TL;DR:** I added `mem_limit` and `cpus` to the PostgreSQL service in `docker‑compose.yml` to prevent the dev database from starving other containers. The change caps the container at 512 MiB RAM and 1 CPU, stabilizing the local environment without affecting production.\n\nRunning the **bienestar‑integral‑kb** stack locally on my MacBook Pro (M1, 16 GB RAM) started to feel flaky after I added a couple of AI‑powered micro‑services. The PostgreSQL container (`pgvector/pgvector:pg16`) would occasionally consume all available memory, causing the Docker daemon to kill other containers (e.g., the FastAPI inference service). Docker Desktop shows the following symptom:\n\n```\n[2026-10-10T14:32:12.345Z] container is out of memory: kill process 12 (postgres) score 999 or sacrifice child\n```\n\nThe error manifested as intermittent `502 Bad Gateway` responses from the API gateway because the dependent services were being OOM‑killed. The root cause was that Docker Compose, by default, gives each container unrestricted access to host resources. In a multi‑service dev environment that’s a recipe for “noisy neighbor” problems.\n\nMy first instinct was to use Docker Desktop’s **Resources → Advanced** UI to limit the whole Docker engine to, say, 8 GB RAM. While that prevented total exhaustion, it also throttled services that legitimately needed more memory (e.g., the embedding model). I needed a **per‑container** limit.\n\nI then tried the `deploy.resources.limits` block that Docker Compose supports:\n\n```\nservices:\n  postgres:\n    image: pgvector/pgvector:pg16\n    deploy:\n      resources:\n        limits:\n          cpus: \"1\"\n          memory: 512M\n```\n\nUnfortunately, the `deploy` key is ignored unless the Compose file is run in **Swarm mode** (`docker stack deploy`). Running `docker compose up` (the v2 CLI) silently ignored those limits, leaving the problem unchanged.\n\nThe next approach was to switch the Compose file version to `3.8` and use the `mem_limit` and `cpus` top‑level keys, which are supported in version 2.x files. After a quick read of the docs, I realized that **Compose file version 2.4** (or later) allows these fields without Swarm. That’s the path I took.\n\nThe original `docker-compose.yml` started with version `2`:\n\n```\nversion: \"2\"\nservices:\n  postgres:\n    image: pgvector/pgvector:pg16\n    container_name: ismerely_postgres\n    restart: unless-stopped\n    environment:\n      POSTGRES_USER: ...\n```\n\nI bumped it to `2.4` to guarantee support for resource constraints:\n\n```\nversion: \"2.4\"\nservices:\n```\n\n`mem_limit` and `cpus`\nThe diff from commit `00f0bbc2` shows the exact lines added:\n\n```\n@@ -4,6 +4,8 @@ services:\n   image: pgvector/pgvector:pg16\n   container_name: ismerely_postgres\n   restart: unless-stopped\n+  mem_limit: 512m\n+  cpus: \"1\"\n   environment:\n     POSTGRES_USER: ...\n```\n\n**Full updated service definition:**\n\n```\nservices:\n  postgres:\n    image: pgvector/pgvector:pg16\n    container_name: ismerely_postgres\n    restart: unless-stopped\n    mem_limit: 512m          # cap RAM at 512 MiB\n    cpus: \"1\"                # limit to a single logical CPU\n    environment:\n      POSTGRES_USER: ${POSTGRES_USER}\n      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}\n      POSTGRES_DB: ${POSTGRES_DB}\n    volumes:\n      - pg_data:/var/lib/postgresql/data\n    ports:\n      - \"5432:5432\"\n```\n\nAfter `docker compose up -d`, I inspected the container:\n\n``` bash\n$ docker inspect ismerely_postgres --format='{{json .HostConfig.Memory}}' | jq .\n536870912   # 512 MiB in bytes\n\n$ docker inspect ismerely_postgres --format='{{json .HostConfig.NanoCpus}}' | jq .\n1000000000   # 1 CPU (1e9 nanocpus)\n```\n\nRunning `docker stats ismerely_postgres` confirmed the caps:\n\n```\nCONTAINER ID   NAME                CPU %     MEM USAGE / LIMIT\nc1d2e3f4g5h6    ismerely_postgres   0.12%     210MiB / 512MiB\n```\n\nThe PostgreSQL container now stays comfortably under its limit, and the other services no longer get OOM‑killed.\n\n`mem_reservation`\nI considered using `mem_reservation` (soft limit) but opted for a hard cap (`mem_limit`) because the dev environment is already memory‑constrained. A soft limit would still allow the DB to balloon under load, re‑triggering the original issue.\n\n`docker stack deploy`). If the project ever migrates to Swarm or Kubernetes, you’ll need to translate the constraints to the respective platform’s syntax (`deploy.resources.limits` for Swarm, `resources.limits` in a K8s pod spec).\n**Per‑container resource constraints in Docker Compose are a lightweight, production‑agnostic way to prevent a single service from monopolizing host resources during local development.** Using `mem_limit` and `cpus` (available from Compose file version 2.4) gives you deterministic behavior without the overhead of Swarm or Kubernetes.\n\n`cAdvisor` or `Prometheus` to monitor actual usage trends over time.\n*Roberto Luna Osorio – Full Stack Developer & Project Lead*\n\nPlaya del Carmen, México  \n\n*Part of my [Build in Public](https://dev.to/zaerohell) series — sharing the real process of building Building Ismerely KB from Playa del Carmen, México.*\n\n*Repo: `zaerohell/bienestar-integral-kb` · 2026-10-11*\n\n#playadev #buildinpublic", "url": "https://wpnews.pro/news/adding-per-container-cpu-memory-limits-to-docker-compose-for-pgvector", "canonical_source": "https://dev.to/zaerohell/adding-per-container-cpu-memory-limits-to-docker-compose-for-pgvector-1nh9", "published_at": "2026-10-12 22:18:04+00:00", "updated_at": "2026-10-12 22:23:41.186425+00:00", "lang": "en", "topics": ["ai-infrastructure", "mlops", "developer-tools"], "entities": ["Docker Compose", "Docker Desktop", "pgvector", "PostgreSQL", "FastAPI"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/adding-per-container-cpu-memory-limits-to-docker-compose-for-pgvector", "markdown": "https://wpnews.pro/news/adding-per-container-cpu-memory-limits-to-docker-compose-for-pgvector.md", "text": "https://wpnews.pro/news/adding-per-container-cpu-memory-limits-to-docker-compose-for-pgvector.txt", "jsonld": "https://wpnews.pro/news/adding-per-container-cpu-memory-limits-to-docker-compose-for-pgvector.jsonld"}}