# Functions

Writing, deploying and operating persistent workers.

> Section: Functions

## Write a worker

Export an async default function. Handle errors inside your loop and include a delay, otherwise the worker will consume a full CPU doing nothing useful.

```typescript
export default async function main() {
  while (true) {
    try {
      console.log('Worker heartbeat', new Date().toISOString());
    } catch (error) {
      console.error(error);
    }
    await new Promise(resolve => setTimeout(resolve, 5000));
  }
}
```

## Deploy

The CLI bundles local imports with esbuild from a single entry file. Secrets are passed as environment variables.

```bash
veltic functions deploy PROJECT_ID heartbeat ./worker.ts --memory 256
```

## Process jobs reliably

Store job state in PostgreSQL. Processes restart, so handlers must be idempotent. Use an atomic claim so competing workers never take the same row.

```sql
update jobs
set status = 'running', claimed_at = now()
where id = (
  select id from jobs
  where status = 'pending'
  order by created_at
  for update skip locked
  limit 1
)
returning *;
```

## When a worker dies

Exceeding the hard memory limit terminates the container through the kernel; the restart policy retries up to five times. Check the logs and the memory chart in the dashboard rather than assuming a transient fault.
