> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://docs.ampdb.io/api/mcp` to find what you need.

# Solo Mode

Solo mode runs Amp's three [services](/running-amp/ampd#services), the controller, the query server, and a worker, in a
single `ampd` process. It works without any configuration: it keeps its state in a directory, and runs its own
PostgreSQL server for the [metadata database](/running-amp/metadata-database). Use it to develop with Amp, to test, and
in CI.

Since everything shares one process, a crash in one service stops the others, and extraction competes with queries
for CPU and memory. To run Amp in production, use [distributed mode](/running-amp/distributed-mode) instead.

## Prerequisites

* `ampd`, from [Installation](/running-amp/installation).
* PostgreSQL 16 or newer, in one of two ways:
  * Its `initdb` and `postgres` programs on your `PATH`, for solo mode to
    [run a server itself](/running-amp/solo-mode#managed-postgresql). See [Install PostgreSQL](/running-amp/installation#install-postgresql).
  * A PostgreSQL server you run, for solo mode to [connect to](/running-amp/solo-mode#use-your-own-postgresql).

## Start solo mode

Run `ampd solo` in the directory where you want Amp to keep its state:

```bash
ampd solo
```

It starts:

| What                           | Where                                                                                                 |
| ------------------------------ | ----------------------------------------------------------------------------------------------------- |
| The query server               | Arrow Flight on port `1602`                                                                           |
| The controller                 | The [Admin API](/managing-amp/admin-api) on port `1610`                                               |
| A worker, with the ID `worker` | Its health check on port `1620`                                                                       |
| A PostgreSQL server            | A socket in [`.amp/metadb`](/running-amp/solo-mode#managed-postgresql), unless you [use your own](/running-amp/solo-mode#use-your-own-postgresql) |

Leave it running, and use Amp from another terminal: [`ampctl`](/clis/ampctl) connects to `http://localhost:1610` and
[`ampsql`](/clis/ampsql) to `http://localhost:1602` by default. The [quickstart](/get-started/quickstart) walks you
through extracting a chain and querying it.

Press Ctrl+C to stop solo mode. Its state stays in `.amp`, so the next `ampd solo` in the same directory picks up where
it left off, and resumes the jobs that were running.

## Options

| Option                | Environment variable | Default                          | Description                                                                     |
| --------------------- | -------------------- | -------------------------------- | ------------------------------------------------------------------------------- |
| `--amp-dir <AMP_DIR>` | `AMP_DIR`            | `.amp`, in the current directory | The [state directory](/running-amp/solo-mode#the-amp-directory), like `--amp-dir ~/amp-state`.        |
| `--flight-server`     | `AMP_FLIGHT_SERVER`  | off                              | Starts the query server's Arrow Flight endpoint, like `AMP_FLIGHT_SERVER=true`. |
| `--admin-server`      | `AMP_ADMIN_SERVER`   | off                              | Starts the Admin API, like `AMP_ADMIN_SERVER=true`.                             |

`--flight-server` and `--admin-server` choose which endpoints start. Without either, both do; with one, only that one
does. The worker always runs. For example, to serve queries over datasets that are already deployed, without exposing
the Admin API:

```bash
ampd solo --flight-server
```

Solo mode also takes `ampd`'s [`--config`](/running-amp/ampd#options), before the command:
`ampd --config amp.toml solo`.

## The `.amp` directory (Unstable)

Solo mode keeps everything it needs in one directory, `.amp` in the current directory unless you set `--amp-dir`. It
creates the directory and its contents when they don't exist:

```
.amp/
├── config.toml   # Optional: your configuration
├── data/         # Datasets' Parquet files
├── providers/    # Provider configuration files
├── manifests/    # Dataset manifests
└── metadb/       # The managed PostgreSQL server's data
```

* `data/`, `providers/`, and `manifests/` are the default [storage locations](/running-amp/storage). A
  [provider](/providers) is the connection to a chain that a raw dataset extracts from, and a
  [manifest](/datasets/manifests) is a dataset's definition.
* `metadb/` only exists when solo mode [manages PostgreSQL](/running-amp/solo-mode#managed-postgresql).

Solo mode reads its configuration from the first of these that exists, and otherwise uses the defaults of every
setting:

1. The file in `--config` or `AMP_CONFIG`, wherever it is.
2. `config.toml` in the state directory.

[Configuration](/running-amp/configuration) explains the file. A relative path in it, like `data_dir = "data"`, is
relative to the file's directory.

Run one `ampd solo` at a time per directory. To run several, give each its own `--amp-dir`, and its own ports through
[the configuration](/running-amp/configuration-reference#serverflight_addr).

Add the directory to your project's `.gitignore`, so its data and database stay out of Git. Keep `config.toml` if
your team shares it:

```txt [.gitignore]
.amp/*
!.amp/config.toml
```

:::warning
`ampup` reads `AMP_DIR` too, as the directory to install Amp into. Rather than exporting `AMP_DIR` in your shell, use
`--amp-dir`, or set it for one command: `AMP_DIR=~/amp-state ampd solo`.
:::

## Managed PostgreSQL (Unstable)

Unless you [configure a database](/running-amp/solo-mode#use-your-own-postgresql), solo mode runs a PostgreSQL server for the metadata
database, from the `initdb` and `postgres` programs on your `PATH`. You don't need to set it up or start it:

* **The first time**, solo mode creates the database in `.amp/metadb`. After that, it reuses it, so Amp's state
  survives restarts.
* **It only listens on a socket file in `.amp/metadb`**, not on a TCP port, so it doesn't conflict with another
  PostgreSQL server on your machine.
* **It stops with solo mode.** If `ampd` crashed and left the server running, solo mode stops it on its next start.

To look at the database while solo mode runs, connect to its socket as the `postgres` user, without a password:

:::terminal
```bash
psql "host=$PWD/.amp/metadb user=postgres dbname=postgres" -c "SELECT node_id, heartbeat_at FROM workers"
```

```
 node_id |         heartbeat_at
---------+-------------------------------
 worker  | 2026-10-30 13:03:59.480639-04
(1 row)
```
:::

To start quickly, the server doesn't wait for its writes to reach the disk. If your machine loses power or crashes, the
database can lose its latest changes, or be corrupted. That's fine for development, where you can start over, but it's
one reason not to keep data you can't rebuild in solo mode.

Limits:

* **The path to the socket file has a maximum length**: 103 bytes on macOS, and 107 on Linux. With the default state
  directory, the socket file is `.amp/metadb/.s.PGSQL.5432`, so the directory you start solo mode in can have a path
  of up to 77 bytes on macOS, and 81 on Linux. With a longer one, PostgreSQL
  [doesn't start](/running-amp/solo-mode#failed-to-start-postgresql).
* **Amp's Docker image has no PostgreSQL server**, so in a container, [use your own](/running-amp/solo-mode#use-your-own-postgresql).

## Use your own PostgreSQL

To use a PostgreSQL server you run, like a shared development database or a container, give solo mode its URL, in
`.amp/config.toml`:

```toml [.amp/config.toml]
[metadb]
url = "postgresql://amp:amp@localhost:5432/amp"
```

Or in an environment variable:

```bash
AMP_CONFIG_METADB__URL=postgresql://amp:amp@localhost:5432/amp ampd solo
```

Solo mode then doesn't start a server, or create `.amp/metadb`. [Metadata Database](/running-amp/metadata-database)
covers the URL and its other settings. Solo mode uses the `[metadb]` section only, not the per-service sections.

## Run in Docker

The [Docker image](/running-amp/installation#run-with-docker) runs solo mode too, with a PostgreSQL server in another
container. This puts both on a network, and keeps solo mode's state in a volume:

```bash
docker network create amp

docker run -d --name amp-metadb --network amp \
  -e POSTGRES_USER=amp -e POSTGRES_PASSWORD=amp -e POSTGRES_DB=amp \
  postgres:16

docker run -d --name amp --network amp -p 1602:1602 -p 1610:1610 \
  -e AMP_CONFIG_METADB__URL=postgresql://amp:amp@amp-metadb:5432/amp \
  -v amp-data:/amp \
  ghcr.io/edgeandnode/amp:v0.0.42 solo --amp-dir /amp
```

Check that it's up with the Admin API, which lists the embedded worker:

:::terminal
```bash
curl http://localhost:1610/workers
```

```json
{ "workers": [{ "node_id": "worker", "heartbeat_at": "2026-10-30T17:03:06.673065+00:00" }] }
```
:::

## Limitations

* **One worker.** Solo mode runs every job on its embedded worker, `worker`, and ignores
  [`controller.default_worker_id`](/running-amp/configuration-reference#controllerdefault_worker_id).
* **No isolation.** A crash in one service stops all of them, and they share the process's CPU and memory.
* **Not for production.** It can't scale, or keep running when a part of it fails. Use
  [distributed mode](/running-amp/distributed-mode).

## Troubleshooting

### `PostgreSQL binary 'initdb' not found in PATH`

Solo mode is managing PostgreSQL, and can't find its programs. Install PostgreSQL 16 or newer and add its programs to
your `PATH` (see [Install PostgreSQL](/running-amp/installation#install-postgresql)), or
[use your own server](/running-amp/solo-mode#use-your-own-postgresql).

### `Failed to start PostgreSQL`

```
Exiting with error: Solo command failed | Caused by: Failed to start PostgreSQL -> PostgreSQL server exited unexpectedly with status Some(1)
```

Solo mode is managing PostgreSQL, and the server stopped as it started. When this happens the first time you run
solo mode in a directory, the path of the server's [socket file](/running-amp/solo-mode#managed-postgresql), in `.amp/metadb`, is likely too
long: it can't be longer than 103 bytes on macOS, or 107 on Linux. Check its length:

:::terminal
```bash
echo -n "$PWD/.amp/metadb/.s.PGSQL.5432" | wc -c
```

```
     139
```
:::

If it's too long, start solo mode from a directory with a shorter path, give it a state directory with one, like
`ampd solo --amp-dir ~/amp-state`, or [use your own PostgreSQL](/running-amp/solo-mode#use-your-own-postgresql).

### `role "postgres" does not exist`

The state directory's database was created by a version of Amp older than v0.0.37. See
[Upgrading](/running-amp/upgrading#v0037-managed-postgresql-connects-as-postgres).

### `failed to bind to 0.0.0.0:1610`

```
Exiting with error: Solo command failed | Caused by: Failed to initialize controller service -> failed to bind to 0.0.0.0:1610 -> Address already in use (os error 48)
```

Another program, often another `ampd`, uses the port. Stop it, or move solo mode's endpoints to free ports:

```bash
export AMP_CONFIG_SERVER__FLIGHT_ADDR=0.0.0.0:11602
export AMP_CONFIG_CONTROLLER__ADMIN_API_ADDR=0.0.0.0:11610
export AMP_CONFIG_WORKER__HEALTH_ADDR=0.0.0.0:11620
ampd solo
```
