ALTER TABLE outbox ADD COLUMN delivery_attempts INTEGER NOT NULL DEFAULT 0, ADD COLUMN last_delivery_error TEXT, ADD COLUMN dead_lettered_at TIMESTAMPTZ; -- The unpublished dispatchers read oldest-first and previously stopped on the -- first delivery error, so one permanently malformed payload blocked every -- later event of that type forever. Dead-lettered rows leave the working set -- via this partial index so a poison row degrades to one lost event instead of -- a stalled queue. DROP INDEX IF EXISTS outbox_unpublished_order; CREATE INDEX outbox_unpublished_order ON outbox (created_at, event_id) WHERE published_at IS NULL AND dead_lettered_at IS NULL;