On a partitioned table, logical decoding emits changes for the leaf partition. Its REPLICA IDENTITY is the one that counts — the parent’s is never read. And ALTER on the parent doesn’t propagate:

CREATE TABLE t (id bigint, created_at timestamp, PRIMARY KEY (id, created_at))
  PARTITION BY RANGE (created_at);
CREATE TABLE t_p1 PARTITION OF t FOR VALUES FROM ('2026-01-01') TO ('2027-01-01');

ALTER TABLE t REPLICA IDENTITY FULL;
-- t    -> f
-- t_p1 -> d   existing partition: no cascade

CREATE TABLE t_p2 PARTITION OF t FOR VALUES FROM ('2027-01-01') TO ('2028-01-01');
-- t_p2 -> d   new partition: not inherited

A partition is born DEFAULT and stays there. For replication, ALTER on the parent is a silent no-op.

This bites CDC. AWS DMS warns that it doesn’t support REPLICA IDENTITY FULL when the endpoint uses the pglogical plugin — and sure enough, UPDATEs never reach the target. If the leaves are FULL, looking at the parent gives nothing away: its value is independent of what decoding actually sees.

The fix is one line per partition:

ALTER TABLE t_p1 REPLICA IDENTITY DEFAULT;  -- now uses the PK
ALTER TABLE t_p2 REPLICA IDENTITY DEFAULT;

Catalog-only: no rewrite, milliseconds, regardless of table size.

Check afterwards — always on the leaves, never the parent:

SELECT c.relname,
       CASE c.relreplident WHEN 'd' THEN 'DEFAULT' WHEN 'f' THEN 'FULL'
                           WHEN 'n' THEN 'NOTHING' WHEN 'i' THEN 'INDEX' END AS ri
FROM pg_inherits i
JOIN pg_class c ON c.oid = i.inhrelid
WHERE i.inhparent = 't'::regclass
ORDER BY c.relname;

DEFAULT uses the primary key — and since the partition key must be part of the PK, it’s already there.