> For the complete documentation index, see [llms.txt](https://docs.opendatadiscovery.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0044-postgres-artefact-lazy-create-no-drop.md).

# ADR-0044: Postgres replication artefacts are lazy-created, never dropped

## Status

**Accepted.** Reconstructed from the codebase on 2026-05-30; the decision is live in the source today.

## Context

The notification WAL consumer (ADR-0043) needs two Postgres objects to exist: a logical **replication slot** and a **publication**. The platform has to ensure they exist before streaming — but it must also decide what to do with them over the platform's lifetime: create them automatically, and if so, ever remove them? Replication slots in particular are durable server-side objects that retain WAL on the primary until consumed, so their lifecycle has real operational weight.

## Decision

**The platform creates the replication slot and publication lazily on first leader run if they are absent, and never drops them.** When the elected consumer starts, it checks for each artefact and creates it only when missing: `SELECT EXISTS (... pg_replication_slots WHERE slot_name = ?)` then `createReplicationSlot()` if absent; `SELECT EXISTS (... pg_publication WHERE pubname = ?)` then `CREATE PUBLICATION ...` if absent. There is **no DROP path anywhere** in the notification subsystem — once created, the artefacts persist until an operator removes them.

This makes cleanup the operator's responsibility, by design. The decision keeps boot idempotent (restart, redeploy, or re-elect a leader without disturbing existing artefacts) and avoids the platform ever deleting an object an operator may have created, renamed, or be relying on. It is the same lazy-create-no-drop shape the platform uses for other Postgres-resident artefacts whose lifecycle outlives a single process (for example its range partitions).

## Consequences

* 📌 **Bounded growth requires operator action.** An unconsumed replication slot makes the Postgres primary retain WAL indefinitely, which can exhaust disk; because the platform never drops the slot, an operator who disables notifications (or renames the slot) must drop the old slot manually. The operator-facing notifications documentation states this cleanup responsibility.
* Boot is idempotent: the consumer can start, restart, or fail over without recreating or disturbing existing artefacts — the exists-check makes creation a no-op when they are already present.
* The platform never removes an operator's database objects, avoiding the risk of deleting something created or repurposed out-of-band — at the cost of the manual-cleanup burden above.
* Changing the configured slot or publication name produces a *new* artefact on next run and orphans the old one (it is not renamed or dropped) — another instance of the same operator-owns-cleanup consequence.

## Evidence

* `odd-platform-api/.../notification/NotificationSubscriber.java:104-126` — `registerReplicationSlot(...)`: `SELECT EXISTS (SELECT slot_name FROM pg_replication_slots WHERE slot_name = ?)`, and only on `false` does it call `createReplicationSlot().logical().withSlotName(...).withOutputPlugin("pgoutput").make()`.
* `odd-platform-api/.../notification/NotificationSubscriber.java:128-158` — `registerPublication(...)`: `SELECT EXISTS (SELECT oid FROM pg_publication WHERE pubname = ?)`, and only on `false` does it `execute("CREATE PUBLICATION %s FOR TABLE %s")`.
* No `DROP` statement (no `pg_drop_replication_slot`, no `DROP PUBLICATION`) exists anywhere in the `notification` package — confirmed by sweep — so neither artefact is ever removed by the platform.

## See also

* [ADR-0043 — The notification WAL consumer is a leader-elected singleton](/developer-guides/architecture-decision-log/adr-0043-notification-wal-single-leader.md) — the consumer that creates and relies on these artefacts.
* [Notifications](/features/active-platform-features/notifications.md) — the operator-facing guidance, including manual replication-slot cleanup.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.opendatadiscovery.org/developer-guides/architecture-decision-log/adr-0044-postgres-artefact-lazy-create-no-drop.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
