# FastAPI service: OOM kills (status=9/KILL) on 2GB RAM

## What you see

```text
fastapi.service: Main process exited, code=killed, status=9/KILL
fastapi.service: Failed with result 'signal'.
```

The process is being killed by the Linux **OOM (out-of-memory) killer** (signal 9 = SIGKILL). This is common when running Gunicorn with **4 workers** on a **2GB** droplet: each worker loads the full FastAPI app and dependencies, so total RAM can exceed 2GB.

## Fix: fewer workers + preload

1. **Use the included Gunicorn config** (2 workers, preload):
   - Project root: `gunicorn.conf.py` (workers=2, preload=True, bind 127.0.0.1:8001).

2. **Use the included systemd unit** that points at this config:
   - `scripts/fastapi.service` runs: `gunicorn -c gunicorn.conf.py aumentum_api:app`

### On the server

```bash
cd /var/www/boundary-fastapiandnextjs
git pull

# Replace the unit (if you were using -w 4 before)
sudo cp scripts/fastapi.service /etc/systemd/system/fastapi.service
sudo systemctl daemon-reload
sudo systemctl restart fastapi
```

### If it still gets killed

- Set **1 worker**:
  ```bash
  sudo systemctl set-environment GUNICORN_WORKERS=1
  sudo systemctl restart fastapi
  ```
  Or in the unit add: `Environment=GUNICORN_WORKERS=1`
- Or **cap memory** so this service is killed first and restarted instead of the whole box locking up:
  - In `[Service]`: `MemoryMax=1536M` (uncomment in `scripts/fastapi.service` if needed).

## Optional: enforce config from the unit

To always use the repo’s config and bind without editing the file:

```ini
Environment=GUNICORN_WORKERS=2
Environment=GUNICORN_BIND=127.0.0.1:8001
ExecStart=/var/www/boundary-fastapiandnextjs/venv/bin/gunicorn -c gunicorn.conf.py aumentum_api:app
```

`gunicorn.conf.py` reads `GUNICORN_WORKERS` and `GUNICORN_BIND` from the environment.
