# Resources (CPU & memory limits)
URL: https://synquic.tech/docs/guides/sleep-mode-resources.md

Cap how much CPU and memory a project's containers may use, per project or per service, and what the sleep mode setting does on your own servers.

import { Step, Steps } from 'fumadocs-ui/components/steps';

On your own server, a container can use the whole machine unless you say otherwise. That's usually what you
want: it's your hardware. **Resources** is where you set a ceiling, so that one project can't take all the
memory and push the others out, or so a small box doesn't fall over during a heavy job.

Resources decide **how much** a project may use. To decide **where** it runs (dedicated cores, CPU priority,
a memory guarantee), see [Dedicated CPU cores & reservations](/docs/guides/cpu-reservation).

<Callout title="What you need first">
- A project that runs a container (a static site has none, so it has no Resources entry).
- Permission to change the project's settings.
</Callout>

## Where it is

Open the project and choose **Resources** in the project menu. The **Machine Power** card is at the top, with
**CPU & memory placement** and [**Replicas**](/docs/guides/replicas) under it. The same **Machine Power** card is also on the **Configuration** tab of a
single app and on the **Apps & Services** tab of a project with services.

The card's header shows the target machine's size, for example **Machine: 8 vCPU · 16 GB**, read from its
Docker daemon.

## Set a limit

<Steps>

<Step>

### Pick a tier

| Tier | CPU | Memory | Good for |
| --- | --- | --- | --- |
| **No limits** (default) | Machine capacity | Machine capacity | Most apps on your own server. |
| **Micro** | 0.25 vCPU | 256 MB | Tiny sidecars and workers. |
| **Low** | 0.5 vCPU | 512 MB | Small apps. |
| **Medium** | 1 vCPU | 1 GB | Most web applications. |
| **High** | 2 vCPU | 2 GB | Busy applications. |
| **Extra large** | 4 vCPU | 8 GB | Databases and heavy workloads. |
| **Custom** | You choose | You choose | Anything else. |

A tier bigger than the machine is greyed out (**Exceeds this machine**). Clicking a tier saves it; the toast
says **Machine power updated**.

</Step>

<Step>

### Or set your own numbers

Choose **Custom** and fill in **CPU cores** (fractions allowed, such as `1.5`) and **Memory (MB)**. `0` in a
field means no limit for that one, so you can cap memory and leave CPU free. Press **Save**.

</Step>

<Step>

### Redeploy

Limits apply when the container is created, and the card reminds you to redeploy for a change to take
effect. Every deploy log also states the limits it used, for
example `Resource limits: 2 vCPU · 4 GB`, or `no limits (machine capacity)`.

</Step>

</Steps>

### What the limits do

- **CPU** is a share of processor time. A container limited to `0.5` vCPU gets at most half a core, even on an
  idle server; it slows down rather than failing.
- **Memory** is a hard cap. A container that tries to use more is stopped by the kernel (an "out of memory"
  kill) and restarted according to its [restart policy](/docs/guides/container-settings#restart-policy). If an
  app keeps restarting after you set a memory cap, raise it.
- The value is checked against the machine: `Memory limit 8192 MB exceeds the machine's 2048 MB`. A non-zero
  value must be at least `0.25` cores and `128` MB. If Synq can't reach the machine to read its size, it
  accepts the value without a ceiling.
- The limits are **per container**. An app running [replicas](/docs/guides/replicas) gives each replica the
  full limit, so three replicas of a 1 GB app can use 3 GB together.

## Per-service limits

In a project with services, the project value applies to **each** container on its own (it's a cap per
container, not a budget shared between them).

A service can override it. Synq reads a Compose file's own limits in either spelling and applies them over
the project value **field by field**, so a service that sets only memory keeps the project's CPU value:

```yaml
services:
  api:
    image: my/api
    mem_limit: 4g          # short form
    cpus: 2
  worker:
    image: my/worker
    deploy:                # long form, also read
      resources:
        limits:
          memory: 8G
          cpus: "1.5"
```

The same override is available in `synq.json` under
[`services[].resources`](/docs/reference/synq-json#services-compose).

<Callout title="Adopted containers keep their limits" type="info">
Importing an existing Docker container reads the limits it's actually running with, including one you set by
hand with `docker update --memory`, so adopting it doesn't reset them.
</Callout>

## Build limits

Builds are uncapped too. On a small server, an unbounded production build can take the whole machine for a
few minutes; to prevent that, cap the build separately through the API (below). There is no build setting in
the panel.

## From the API

```bash
# Read the current values, the machine's capacity, and whether a limit is required
curl -H "Authorization: Bearer $SYNQ_TOKEN" \
  "$SYNQ_URL/api/projects/$PROJECT_ID/resources"

# Use a tier for the app
curl -X PATCH -H "Authorization: Bearer $SYNQ_TOKEN" -H "Content-Type: application/json" \
  -d '{"production":{"tier":"medium"}}' \
  "$SYNQ_URL/api/projects/$PROJECT_ID/resources"

# Custom values for the app, and a cap for its builds
curl -X PATCH -H "Authorization: Bearer $SYNQ_TOKEN" -H "Content-Type: application/json" \
  -d '{"production":{"cpuCores":1.5,"memoryMb":3072},"build":{"cpuCores":2,"memoryMb":2048}}' \
  "$SYNQ_URL/api/projects/$PROJECT_ID/resources"

# Remove the caps again
curl -X PATCH -H "Authorization: Bearer $SYNQ_TOKEN" -H "Content-Type: application/json" \
  -d '{"production":{"tier":"unlimited"}}' \
  "$SYNQ_URL/api/projects/$PROJECT_ID/resources"
```

`SYNQ_URL` is your panel address (for example `https://app.example.com`). Tiers are `unlimited`, `micro`,
`low`, `medium`, `high` and `xlarge`; explicit numbers use `cpuCores`, `memoryMb` and `diskMb` (disk is not
enforced on your own servers). Every field is optional.

## Sleep mode

Projects also carry a **sleep mode** setting, `auto_sleep` (the default) or `always_on`, which you can set
with the CLI or the API:

```bash
synq project sleep-mode <project-id> always_on
```

On your own servers this setting is stored but **has no effect**: containers run continuously and are never
put to sleep when idle, whichever value you choose. There is no idle-stop or wake-on-request on a Synq
server. To stop an app, stop it (or disable the project); to take it offline for visitors while it keeps
running, use [maintenance mode](/docs/guides/maintenance-mode).

## Troubleshooting

<Callout title="A value is rejected" type="error">
A cap larger than the machine is refused with the real numbers. Lower it, or choose **No limits** (`0` or the
`unlimited` tier) to remove the cap. Values below `0.25` cores or `128` MB are refused too.
</Callout>

<Callout title="I changed the tier but nothing happened" type="warn">
Limits apply to new containers. Redeploy the project, then check the first lines of the deploy log for
`Resource limits: ...`.
</Callout>

<Callout title="The app keeps restarting after I set a memory cap" type="warn">
It is running out of memory and being killed. Check the project's **Logs** and **Monitoring**, then raise the
memory or pick a bigger tier.
</Callout>

## Related guides

<Cards>
  <Card title="Dedicated CPU cores & reservations" href="/docs/guides/cpu-reservation" description="Pin a project to cores, reserve them, set CPU priority and a memory guarantee." />
  <Card title="Replicas and autoscaling" href="/docs/guides/replicas" description="Run several copies of an app on its server, and scale them with the load." />
  <Card title="Restart policy & container settings" href="/docs/guides/container-settings" description="What happens when a container stops." />
  <Card title="Logs & monitoring" href="/docs/guides/logs-monitoring" description="See how much CPU and memory the app really uses." />
</Cards>
