---
title: "CLI reference"
description: "The pug binary — server, workers, migrations and dev infrastructure commands."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.pug.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# CLI reference

Everything Pug's backend does at runtime is a sub-command of a **single binary**, `pug`. The server, every worker, the database migrations, seeding, and email tooling all live in it — there's nothing else to install. This page is the complete command tree.

```bash
go run ./cmd/pug <command>     # from a source checkout
./bin/pug <command>            # after `make build`
```

Every command loads `.env` from the working directory if present, then falls back to the process environment (see [Configuration](/self-hosting/configuration)).

## Command tree

- `pug` — the unified binary
  - `server` — API server — Connect RPC on :3000
  - `dev  ·  start` — server + ALL workers in one process
  - `worker` — run a single worker process
    - `events` — consume JetStream → write to ClickHouse
    - `email` — transactional email
    - `compliance` — GDPR/DPDP erasure, export, retention
    - `demo` — rolling demo traffic — gated by PUG_DEMO_ENABLED
    - `profile`
      - `identify`
      - `alias`
      - `upsert`
  - `postgres migrate` — -d up|down  -n N
  - `nats migrate` — init JetStream streams + consumers
  - `clickhouse migrate` — -d up|down  -n N
  - `seed` — -c count  -b batch  --no-reset
  - `email preview` — magic_link|invite|provider_test  [--text --out]

The same binary runs three ways — see [Overview → Processes](/self-hosting#processes-at-a-glance): everything-in-one (`pug dev`), one process per sub-command (production), or [single-purpose standalone binaries / images](/self-hosting/deployment#1-build) (`pug-worker-events`, …) that each map to one of these commands.

## `server`

```bash
pug server
```

Starts the Connect RPC API server on `:3000` (override with `PUG_SERVER_PORT`). Handles both SDK ingestion and dashboard/API reads, and serves `/healthz` and `/readyz` probes. On ingestion it enriches events (geo, user-agent, bot detection) from the request headers before publishing them to NATS — so enrichment happens here, not in the events worker. This is the only process that listens for public traffic.

## `dev`

```bash
pug dev        # `pug start` is an alias
```

Runs the **API server and every worker together in one process** — the fastest way to get a complete, working stack up. On boot it prints the server URL, the reachable infrastructure, and the active worker list; **Ctrl+C** stops everything cleanly.

It starts the server plus the `events`, `compliance`, and three `profile` workers unconditionally; the `email` worker starts only if email is configured, and the `demo` worker only if `PUG_DEMO_ENABLED=true`. Worker health endpoints are disabled here (probing is for orchestrated deployments).

`pug dev` is built for [local development](/self-hosting/development), but it's also a legitimate way to run a **small single-node instance**. The trade-off versus separate processes is that you can't scale or restart components independently — for production at any real volume, run one process per role instead ([Deployment](/self-hosting/deployment#3-run)).

## `worker …`

Each worker is a standalone NATS JetStream consumer. Run one per command; scale the `events` worker with multiple replicas for high ingest.

| Command | Consumes / does |
|---------|-----------------|
| `pug worker events` | Consumes ingested events from JetStream and writes them to ClickHouse. **The one to scale horizontally.** |
| `pug worker email` | Sends transactional email (magic links, invites, notifications). |
| `pug worker compliance` | GDPR/DPDP data-subject erasure, export, and retention. |
| `pug worker profile identify` | Applies `identify` calls to profiles. |
| `pug worker profile alias` | Merges identities via `alias`. |
| `pug worker profile upsert` | Writes profile property updates. |
| `pug worker demo` | Generates rolling demo traffic. Idles unless `PUG_DEMO_ENABLED=true` — a normal self-host does not run it. |

Each worker serves `/healthz` + `/readyz` on `PUG_WORKER_HEALTH_ADDR` (default `:8090`; `off` to disable) — see [Health checks](/self-hosting/deployment#health-checks).

## Migrations

Run once before the first boot and again on every upgrade; all are idempotent.

| Command | What it does | Flags |
|---------|--------------|-------|
| `pug postgres migrate` | Applies Postgres schema migrations. | `--direction`/`-d` `up`\|`down` (default `up`), `--num`/`-n N` (steps; `0` = all) |
| `pug nats migrate` | Creates the JetStream streams and consumers. | — |
| `pug clickhouse migrate` | Applies ClickHouse schema migrations. | `--direction`/`-d` `up`\|`down` (default `up`), `--num`/`-n N` |

```bash
pug postgres migrate
pug nats migrate
pug clickhouse migrate

pug postgres migrate --direction down --num 1   # roll back one Postgres migration
```

Connection details come from `DATABASE_URL`, `NATS_URL`, and `CLICKHOUSE_URL`.

## `seed`

```bash
pug seed                 # ~500k demo events by default
pug seed --count 10000   # keep it light on a laptop
```

Seeds the **demo project** with synthetic data so you have something to query immediately. It resets Postgres and ClickHouse, then runs the demo flow: ensures the demo account, backfills events, seeds profiles **only** for the users those events belong to, and copies them into ClickHouse. (This is the one-shot version of what the `demo` worker does continuously.)

| Flag | Default | Description |
|------|---------|-------------|
| `--count` / `-c` | `500000` | Total number of events to generate. |
| `--batch` / `-b` | `10000` | Events per ClickHouse insert batch. |
| `--no-reset` | off | Skip the migrate down/up reset; truncate the demo tables and re-seed instead. |

> Run migrations first (or let `seed` reset the stores). Not for production — it targets the demo project specifically.

## `email preview`

```bash
pug email preview magic_link            # render to HTML on stdout
pug email preview invite --text         # render the plaintext twin
pug email preview provider_test --out test.html
```

Renders a transactional email to HTML (or `--text` for the plaintext version) without sending anything — useful for checking branding (`PUG_EMAIL_LOGO_URL`, `PUG_DASHBOARD_BASE_URL`) before going live. Kinds: `magic_link`, `invite`, `provider_test`. `--out FILE` writes to a file instead of stdout.

> This is the top-level `pug email` tooling group — distinct from `pug worker email`, which is the process that actually delivers mail.

## Further reading

- [Deployment](/self-hosting/deployment) — run these commands as production processes
- [Development](/self-hosting/development) — the local workflow and `make` targets that wrap them
- [Configuration](/self-hosting/configuration) — the environment every command reads

Source: https://docs.pug.sh/self-hosting/cli/index.mdx
