seems to fix it to work as we were expecting. Is that particularly costly? Should I only set the constraint to be deferred when we really need it? Would it be more efficient to perform the deletes explicitly within a transaction rather than relying on the cascades and deferring that one constraint?
I don't know. I tend to go with only deferring the check if the specific transaction requires it. If there are no issues I would presume that checking at the end would be more efficient. But if there are problems you could end up performing unnecessary work. Memory consumption probably increases as well since constraint related information cannot be discarded as each command completes but must be kept around for the eventual validation.