
# Scheduled wake

Recurring wake windows for a server in BLACKHOLE mode: the platform brings the server up by a given cron-expressed moment, and the task itself is fired by the app's own cron once the machine is already up — the platform never reads or runs the app's code.

**On a preemptible plan, waking is best-effort, not a guarantee.** A server of this type comes up as capacity frees up — through a queue — so there may be no free capacity by the window's moment, and the window can be skipped. The create and update response carries `preemptibleAdvisoryCode: "PREEMPTIBLE_BEST_EFFORT"` for exactly this case — see [Create a window](./wake-schedules/create.md). For time-critical tasks, use a non-preemptible plan or the always-on (24/7) mode.

Scope: `vibe:infra`

## Operations

- [Create a window](./wake-schedules/create.md) — `POST /v1/infra/servers/:id/wake-schedules`
- [List windows](./wake-schedules/list.md) — `GET /v1/infra/servers/:id/wake-schedules`
- [Update a window](./wake-schedules/update.md) — `PATCH /v1/infra/servers/:id/wake-schedules/:scheduleId`
- [Delete a window](./wake-schedules/delete.md) — `DELETE /v1/infra/servers/:id/wake-schedules/:scheduleId`

## Scenarios

**A weekday morning report:**

1. [`POST /wake-schedules`](./wake-schedules/create.md) with `cronExpr: "0 9 * * 1-5"`, `timezone: "America/New_York"`.
2. The response carries `tzWarningCode: "SINGLE_ZONE"` — the timezone is unambiguous, and the platform injects it into the `TZ` environment variable on the next deploy.
3. The cron inside the server fires the task at 9:00 New York time. On a non-preemptible plan, the platform guarantees the server is already up by that moment. On a preemptible plan (the response carries `preemptibleAdvisoryCode: "PREEMPTIBLE_BEST_EFFORT"`), this is best-effort: the server comes up as capacity frees up, and the window can be skipped when capacity is unavailable.

**Several windows across different timezones:**

1. Create windows with different `timezone` values for the same server.
2. Each mutation response carries `tzWarningCode: "MULTI_ZONE"` — the platform does not auto-inject `TZ` when windows span more than one zone. Handle time in the app in UTC.

**A Galaxy app — a wider wake margin:**

1. For a server with `kind: "GALAXY_APP"`, set `lead` with a margin covering the host, the tunnel, and the container startup — up to 900 seconds, not the default margin sized for a standalone server.
2. The Galaxy host itself (`kind: "GALAXY"`) does not accept windows — the schedule is declared on a specific app, and the platform brings up the host too when needed.

## See also

- [Infrastructure](/docs/infra)
- [What the app receives](/docs/infra/app-runtime) — deploy timezone and the in-VM cron
- [Lifecycle](/docs/infra/lifecycle)
- [Changelog](/docs/changelog)
