> **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.

# Quickstart

In this quickstart, you run Amp on your own machine, extract 100 Ethereum blocks with their transactions and logs, and
query them with SQL. It takes about 10 minutes.

You use three programs, which the first step installs:

* `ampd`, which runs Amp. Here it runs in [solo mode](/running-amp/solo-mode): all of Amp's services in one process,
  for development.
* `ampctl`, which manages Amp: you register a data source and a dataset with it, and start extracting.
* `ampsql`, which sends SQL queries to Amp and prints the results.

Only want to query data? The [Amp app](https://app.ampdb.io) needs no setup, and you can
[connect to a hosted Amp](/get-started/choose-how-to-run-amp#connect-to-a-hosted-amp) instead of running your own.

## Prerequisites

* **macOS or Linux** (x86-64 or ARM64). Amp's installer has no prebuilt programs for other systems;
  on those, [build Amp from source](/running-amp/installation).
* **Access to Amp's releases on GitHub**, in the `edgeandnode/amp` repository. The installer signs in with your
  [GitHub CLI](https://cli.github.com) login (run `gh auth login` once), or with a token in the `GITHUB_TOKEN`
  environment variable.
* **PostgreSQL 16 or newer**, with its `initdb` and `postgres` programs on your `PATH`. Amp keeps its metadata in
  PostgreSQL, and solo mode starts and stops it for you. `postgres --version` prints the version you have. Install it
  from [postgresql.org](https://www.postgresql.org/download/) or with your package manager. Some packages leave the
  programs off your `PATH`: add their directory, like `export PATH="$(brew --prefix postgresql@17)/bin:$PATH"` for
  Homebrew's `postgresql@17`, or `export PATH="/usr/lib/postgresql/17/bin:$PATH"` on Debian and Ubuntu. To run
  PostgreSQL in Docker instead, see [Use your own PostgreSQL](/get-started/quickstart#use-your-own-postgresql).
* **An Ethereum RPC endpoint**: the URL of the JSON-RPC API of an Ethereum mainnet node, which Amp extracts blocks
  from. Use your own node or a node provider's, many of which have a free plan. It must serve block 24,000,000 and its
  receipts through `eth_getBlockReceipts`. You give it to Amp when you start it.

## Steps

::::steps
### Install Amp

Install `ampup`, Amp's installer and version manager. It then installs Amp's latest release: `ampd`, `ampctl`, and
`ampsql`.

```bash
curl --proto '=https' --tlsv1.2 -sSf https://ampup.sh/install | sh
```

The installer puts the programs in `~/.amp/bin` by default, and adds that directory to your `PATH` in your shell's
startup file. Run the `source` command it prints, or open a new terminal, then check that the programs run:

:::terminal
```bash
ampd --version && ampctl --version && ampsql --version
```

```
ampd v0.0.42
ampctl v0.0.42
ampsql v0.0.42
```
:::

Your version may be newer.

### Start Amp

Set `RPC_URL` to your endpoint's URL, then create a directory for this quickstart, and start Amp in solo mode from it:

:::terminal
```bash
export RPC_URL=…
mkdir -p ~/amp-quickstart && cd ~/amp-quickstart && ampd solo
```

```
…
2026-10-30T16:49:04.950160Z  INFO ampd::solo_cmd: Controller Admin API running at 0.0.0.0:1610
2026-10-30T16:49:04.951253Z  INFO ampd::solo_cmd: Arrow Flight SQL Server running at 0.0.0.0:1602
```
:::

Amp logs what it does as it runs. Once these two lines appear, it's ready. Solo mode has started:

* The **query server**, which answers SQL queries on port 1602.
* The **controller**, whose Admin API `ampctl` talks to on port 1610.
* A **worker**, which extracts data.
* **PostgreSQL**, from the `initdb` and `postgres` on your `PATH`.

Amp keeps everything in `.amp/`, in the directory you started it from: its PostgreSQL database, your providers and
datasets, and the data it extracts.

:::note
Solo mode's managed PostgreSQL and the layout of `.amp/` are unstable: they work, but may change significantly between
releases. To use a PostgreSQL you run yourself, see [Use your own PostgreSQL](/get-started/quickstart#use-your-own-postgresql).
:::

Amp runs until you stop it. Leave it running, and open a new terminal for the next steps.

### Register a provider

Amp has no chain connections built in. A [provider](/get-started/concepts/providers) tells it where to get a chain's
data: its `kind` is the kind of API it speaks (`evm-rpc` for Ethereum's JSON-RPC API), its `network` is the chain, and
its `url` is where to reach it. Write one for your endpoint, in a TOML file:

```bash
cd ~/amp-quickstart
cat > mainnet.toml << 'EOF'
kind = "evm-rpc"
network = "mainnet"
url = "${RPC_URL}"
EOF
```

Whenever Amp uses the provider, it replaces `${RPC_URL}` with the `RPC_URL` environment variable you started `ampd`
with. That keeps your endpoint's URL, which often contains an API key, out of Amp's storage. Register the provider with
Amp, naming it `mainnet_rpc`:

:::terminal
```bash
ampctl provider register mainnet_rpc ./mainnet.toml
```

```
✓ Provider registered successfully
```
:::

### Generate a dataset manifest

A [dataset](/get-started/concepts/datasets) is a set of tables that Amp fills with data and serves. A JSON file called
a manifest defines it. For a raw dataset, which extracts a chain's data, `ampctl` generates the manifest for you:

```bash
ampctl manifest generate --kind evm-rpc --network mainnet --start-block 24000000 --out eth_mainnet.json
```

* `--kind evm-rpc` and `--network mainnet` match your provider's, which is how Amp finds the provider to extract from.
* `--start-block 24000000` starts the dataset at block 24,000,000, from December 2025, rather than at the chain's first
  block.

The manifest, `eth_mainnet.json`, declares three tables, `blocks`, `transactions`, and `logs`, with their columns.
[Manifests](/datasets/manifests) explains the format.

### Register the dataset

Registering stores the manifest in Amp, under a name and a version. It doesn't extract anything yet.

:::terminal
```bash
ampctl dataset register acme/eth_mainnet ./eth_mainnet.json --tag 1.0.0
```

```
✓ Dataset registered successfully
→ Namespace: acme
→ Name: eth_mainnet
→ Version: 1.0.0
→ Hash: b9e2ebd92c0752ba8a61a233f9cc5d3f4f8b601b1b789a882a5dd8ece9bca56b
→ Kind: evm-rpc
→ Start block: 24000000
→ Finalized only: false
→ Tables: blocks, logs, transactions
```
:::

* `acme` is the dataset's namespace, which groups datasets, like a GitHub organization groups repositories.
  `eth_mainnet` is its name.
* `--tag 1.0.0` gives this version of the dataset a [semantic version](https://semver.org) number.
* The hash identifies the manifest's exact contents. A newer Amp release may generate a slightly different manifest,
  with a different hash.

### Deploy the dataset

Deploying starts the extraction: Amp schedules a [job](/get-started/concepts/jobs-and-workers), which the worker runs.
It fetches each block from your provider, and writes the tables as Parquet files in `.amp/data/`. `--end-block` stops it
at block 24,000,099, after 100 blocks. Without it, the dataset would keep following the chain as it grows.

:::terminal
```bash
ampctl dataset deploy acme/eth_mainnet@1.0.0 --end-block 24000099
```

```
✓ Dataset deployed successfully
→ Job ID: 1
```
:::

`acme/eth_mainnet@1.0.0` names the dataset and the version to deploy. The extraction takes a minute or two, depending
on your endpoint. Amp's terminal logs its progress, and this command shows it:

:::terminal
```bash
ampctl dataset status acme/eth_mainnet@1.0.0
```

```
ID:              1
Status:          COMPLETED
Kind:            Raw
Dataset:         acme/eth_mainnet@1.0.0
tables:
  blocks:
    files_count: 1
    total_size_bytes: 63.25 KiB
    networks:
      mainnet:
        start_block: 24000000
        current_block: 24000099
        block_timestamp: 1765585559
        delay_seconds: 27793476s (46 weeks)
        end_block: 24000099
  logs:
    files_count: 1
    total_size_bytes: 2.15 MiB
    networks:
      mainnet:
        start_block: 24000000
        current_block: 24000099
        block_timestamp: 1765585559
        delay_seconds: 27793476s (46 weeks)
        end_block: 24000099
  transactions:
    files_count: 1
    total_size_bytes: 4.08 MiB
    networks:
      mainnet:
        start_block: 24000000
        current_block: 24000099
        block_timestamp: 1765585559
        delay_seconds: 27793476s (46 weeks)
        end_block: 24000099
```
:::

`Status` is `RUNNING` while Amp extracts, and `COMPLETED` once it reaches the end block. For each table,
`current_block` is the last block extracted, and `delay_seconds` is how long ago that block was produced, so yours is
longer.

### Query the data

`ampsql` sends a SQL query to Amp's query server and prints the results. Get the last five blocks:

:::terminal
```bash
ampsql 'SELECT block_num, timestamp, gas_used FROM "acme/eth_mainnet".blocks ORDER BY block_num DESC LIMIT 5'
```

```
+-----------+----------------------+----------+
| block_num | timestamp            | gas_used |
+-----------+----------------------+----------+
| 24000099  | 2025-12-13T00:25:59Z | 10751338 |
| 24000098  | 2025-12-13T00:25:47Z | 36233422 |
| 24000097  | 2025-12-13T00:25:35Z | 52877862 |
| 24000096  | 2025-12-13T00:25:23Z | 15967071 |
| 24000095  | 2025-12-13T00:25:11Z | 21252932 |
+-----------+----------------------+----------+
```
:::

In SQL, a table is its dataset's name in double quotes, then the table's: `"acme/eth_mainnet".blocks`. The quotes are
needed because of the `/`.

Amp's built-in [functions](/querying/functions) decode chain data. This query counts the token transfers in those 100
blocks, by token contract. Smart contracts record what happens in them as logs, and `evm_topic` computes the identifier
of a token transfer's log from its signature. `evm_decode_hex` turns the contracts' addresses into the familiar `0x…`
form. Save the query in a file:

```bash
cat > transfers.sql << 'EOF'
SELECT evm_decode_hex(address) AS token, count(*) AS transfers
FROM "acme/eth_mainnet".logs
WHERE topic0 = evm_topic('Transfer(address indexed from, address indexed to, uint256 value)')
GROUP BY token
ORDER BY transfers DESC
LIMIT 5
EOF
```

Then run it:

:::terminal
```bash
ampsql -f transfers.sql
```

```
+--------------------------------------------+-----------+
| token                                      | transfers |
+--------------------------------------------+-----------+
| 0x0d4a11d5eeaac28ec3f61d100daf4d40471f1852 | 43168     |
| 0x609e0f0cb16e53878ba5e959a22fc7fcd81b124a | 42151     |
| 0xdac17f958d2ee523a2206206994597c13d831ec7 | 5459      |
| 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 | 4158      |
| 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 | 4135      |
+--------------------------------------------+-----------+
```
:::

Add `--format json`, `jsonl`, or `csv` to get results other programs can read, and `-o` with a file name to save them.
[ampsql](/clis/ampsql) lists every option.

### Stop Amp

In Amp's terminal, press Ctrl+C. Amp stops its PostgreSQL, then exits.

Your data stays in `~/amp-quickstart/.amp/`: run `ampd solo` from `~/amp-quickstart` again to pick up where you left
off. To start over, or to clean up, delete the directory:

```bash
rm -rf ~/amp-quickstart
```
::::

## Use your own PostgreSQL

Solo mode can use a PostgreSQL you run, instead of starting its own. For example, to run PostgreSQL 17 in Docker:

```bash
docker run --name amp-postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres:17
```

Then, when you start Amp, also set `AMP_CONFIG_METADB__URL` to its connection URL:

```bash
export RPC_URL=…
export AMP_CONFIG_METADB__URL=postgresql://postgres:postgres@localhost:5432/postgres
mkdir -p ~/amp-quickstart && cd ~/amp-quickstart && ampd solo
```

When it's set, solo mode connects to that database, and doesn't start PostgreSQL itself. Remove the container when
you're done:

```bash
docker rm -f amp-postgres
```

[Solo Mode](/running-amp/solo-mode) has the other ways to configure it.

## Troubleshooting

### `Download failed` … `HTTP 404` when installing

The installer couldn't download Amp's release from GitHub, because it couldn't sign in. Run `gh auth login`, or set
`GITHUB_TOKEN` to a token with access to `edgeandnode/amp`, then run the installer again.

### `command not found` for `ampd`

Your terminal hasn't loaded the new `PATH` yet. Open a new terminal, or run the `source` command the installer printed.

### `Address already in use`

Another program uses one of solo mode's ports: 1602, 1610, or 1620. It may be another `ampd`. Stop it, then start Amp
again.

### `Connection refused` from `ampctl` or `ampsql`

Amp isn't running, or hasn't finished starting. Check its terminal.

### The deployment stays `RUNNING`, with no files

The worker can't extract from your endpoint. It retries, waiting longer after each failure. `ampctl dataset status
acme/eth_mainnet@1.0.0` prints the latest failure under `Error detail:`, and Amp's terminal logs why:

* `Variable not found: RPC_URL`, then `No provider found for kind 'evm-rpc' and network 'mainnet'`: Amp was started
  without `RPC_URL`. Stop it, set `RPC_URL` in its terminal, and start it again.
* `no receipts returned for block 24000000`: your endpoint doesn't serve this block's receipts through
  `eth_getBlockReceipts`. Use another endpoint, or add `fetch_receipts_per_tx = true` to `mainnet.toml`, which fetches
  each transaction's receipt separately, with many more requests. Then register the provider again, under the same
  name: the worker uses the new settings on its next try.
* `429 Too Many Requests`: your endpoint limits how many requests you send. Wait, use an endpoint with a higher limit,
  or slow Amp down with `rate_limit_per_minute` (see [EVM RPC](/providers/evm-rpc)).

## Next steps

* [Concepts](/get-started/concepts/architecture): what you just used, and how it fits together.
* [Derived datasets](/datasets/derived-datasets): transform your dataset with SQL.
* [Streaming queries](/querying/streaming-queries): get new rows as blocks arrive.
* The [TypeScript](/sdks/typescript) and [Python](/sdks/python) SDKs: query Amp from your code.
* [Choose How to Run Amp](/get-started/choose-how-to-run-amp): run Amp in production, or connect to a hosted Amp.
