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

# Sequin

> Stream Postgres CDC events into S2 with self-hosted Sequin.

[Sequin](https://github.com/sequinstream/sequin) is an open-source Postgres change data capture engine. Its S2 sink can backfill a Postgres table and stream subsequent changes into S2.

## Prerequisites

* An [S2 account](https://s2.dev/sign-up)
* The [S2 CLI](/docs/quickstart#get-started-with-the-cli)
* [Docker](https://docs.docker.com/get-started/get-docker/) with Docker Compose

## Steps

<Steps titleSize="h2">
  <Step title="Set up S2" icon="s">
    [Sign in to S2](https://s2.dev/sign-in), open **Access Tokens**, and issue a token that can create, read, and write the resources used below.

    Configure the CLI, choose a globally unique basin name, and create the target stream:

    ```bash theme={null}
    s2 config set access_token YOUR_ACCESS_TOKEN
    export BASIN="YOUR_UNIQUE_BASIN_NAME"
    s2 create-basin "${BASIN}"
    s2 create-stream "s2://${BASIN}/products"
    ```
  </Step>

  <Step title="Run Sequin" icon="server">
    Download Sequin's [Docker Compose bundle](https://github.com/sequinstream/sequin/releases/latest) and start it:

    ```bash theme={null}
    curl -fsSL https://github.com/sequinstream/sequin/releases/latest/download/sequin-docker-compose.zip \
      -o sequin-docker-compose.zip
    unzip sequin-docker-compose.zip
    cd sequin-docker-compose
    docker compose up -d
    docker compose ps
    ```

    Wait until `sequin_postgres` reports `healthy` and the other four services report `Up`.
  </Step>

  <Step title="Log in to Sequin" icon="key">
    Open [http://localhost:7376](http://localhost:7376) and log in with the quickstart credentials:

    * **Email:** `admin@sequinstream.com`
    * **Password:** `sequinpassword!`
  </Step>

  <Step title="Create the S2 sink" icon="s">
    <Steps>
      <Step title="Choose S2">
        Open **Sinks**, click **Create Sink**, and select **S2**.
      </Step>

      <Step title="Configure the source">
        Leave `sequin-playground` selected. The Compose bundle seeds its `public.products` table with six sample rows. Expand **Initial backfill** and select `public.products` to send those existing rows to S2.
      </Step>

      <Step title="Configure the destination">
        Under **S2 Configuration**, enter the S2 access token you used for the CLI.

        Under **Routing**, enter:

        * **Basin:** The basin name you chose above
        * **Stream:** `products`

        Click **Test Connection**. When it reports **Connection succeeded**, click **Create Sink**.
      </Step>
    </Steps>

    <Check>
      The sink should report that all six health checks are passing and six messages were processed.
    </Check>
  </Step>

  <Step title="Verify live changes" icon="waveform-lines">
    Tail the S2 stream:

    ```bash theme={null}
    s2 tail -f "s2://${BASIN}/products"
    ```

    The six sample product rows should appear with `"action":"read"`. Leave the tail running.

    In another terminal, from the `sequin-docker-compose` directory, insert a row into Postgres:

    ```bash theme={null}
    docker compose exec -T sequin_postgres \
      psql -U postgres -d sequin_playground -c \
      "insert into products (name, price) values ('Organic Honey (16 oz)', 12.99);"
    ```

    The new row should appear in the S2 tail with `"action":"insert"`.

    <Tip>
      If delivery fails, inspect the sink's **Messages** tab and run `docker compose logs sequin` from the Compose directory.
    </Tip>
  </Step>

  <Step title="Clean up (optional)" icon="trash">
    Stop the S2 tail, then remove the local containers, volumes, stream, and basin:

    ```bash theme={null}
    docker compose down --volumes
    s2 delete-stream "s2://${BASIN}/products"
    s2 delete-basin "${BASIN}"
    ```
  </Step>
</Steps>
