1. Home
  2. Docs
  3. Destinations
  4. OpenSearch
DESTINATION · SEARCH

Keep OpenSearch in sync with Postgres.

Same bulk upsert-and-delete path as Elasticsearch, pointed at OpenSearch or Amazon OpenSearch Service.

The OpenSearch sink shares its bulk code path with Elasticsearch: inserts and updates index the row's data under a document id derived from the primary key, deletes remove it, and each batch is one _bulk request.

How delivery works

AspectBehaviour for OpenSearch
OperationInsert/update → index by _id with the row's data; delete → delete by _id.
BatchingOne _bulk NDJSON request per batch.
OrderingPer-row order preserved.
IdempotencyIndexing by _id; retries overwrite.
On failureAny item error other than a 404 on delete fails the batch. Any 2xx is accepted. A 429 pauses the sink for the Retry-After period (30 s if absent) without spending a retry or metering egress. A failed request is retried up to 5 times with exponential backoff (30 s, 1, 2, 4 min, with jitter). After the fifth failure the message is parked as undelivered, the console shows it with the last error, and one click replays it — later changes to the same row wait behind it so order is preserved.
Connection checkGET / on the cluster.

Set up in three steps

  1. Connect your database

    Paste a connection string and press Test. Waltail checks the version (12+), that wal_level is logical, that the user may replicate, and that a slot is free — and shows the fix for anything that fails. Then it creates its own publication and replication slot. Connection guide →

  2. Add OpenSearch as a destination

    Pick the tables to stream, choose OpenSearch, and fill in Cluster URL, Index. Press Test — Waltail checks it can reach and write to OpenSearch before anything is saved.

  3. Change a row

    Insert or update a row. The console shows the first event as it is captured and delivered; from then on, every committed change follows within about a second. Have rows that already exist? Run a backfill — confirm the estimate and they arrive through OpenSearch as read events.

Configuration

Fields as the console asks for them. Secrets are encrypted at rest and never shown again.

FieldConsole labelRequiredNotes
endpointCluster URLYes
indexIndexYesCreated by the first write if it does not exist.
usernameUsernameOptionalBasic auth.
passwordPasswordOptional

Every sink also has two tuning settings: batch size (messages per request, default 100) and rate limit (messages per second, default unlimited). Changes to one row are never in flight twice at once.

Example

Every change is this JSON envelope — data is the row after the change, old the row before it when replica identity provides it, null otherwise:

{
  "op": "update",
  "table": "public.orders",
  "data": { "id": 42, "status": "shipped", "total": 19.99 },
  "old":  { "id": 42, "status": "paid",    "total": 19.99 },
  "seq": 137,
  "idempotency_key": "9f1c3d2e-6b4a-4c7e-9d0f-2a1b3c4d5e6f",
  "commit_lsn": "0/1A2B3C8"
}

Message format reference →

Questions

Does it work with Amazon OpenSearch Service?

Yes, with fine-grained access control and a master user, or a domain open to the Waltail egress IPs. Use the domain endpoint as the cluster URL.

Elasticsearch or OpenSearch sink?

Pick the one that matches your cluster; the write path is the same.

Related

Start streaming to OpenSearch.