My experience is (despite the Postgres developer's advice to use it), timestamptz is largely a useless data type since it is just a wrapper around conversion to UTC.
- Are you storing past events? Just store them as UTC. Maybe you use timestamptz to do it for you, but it's actually a more obtuse interface for that than timestamp
- Are you storing future UTC times? Great, just use UTC, see above
- Are you storing future human times? Then timestamptz is actively harmful because it eagerly converts to UTC so even if you get an updated tzdb in time for when the event comes due, you don't know what happened at write time so now your datetime is ambiguous. It's less broken to use a plain timestamp + string timezone column (if you need to sort by it, maybe a denormalized _utc column too, with the understanding that you'll need to regenerate it or accept slight off-by-one errors when you update the tzdb, but at least you can do this when you know what the input value was, unlike with timestamptz)
SQL Server has `datetimeoffset` which stores the UTC offset (and so roundtrips it), which is definitely an improvement. (You still may need/want a string timezone column even with UTC offsets, but you don't need a denormalized _utc column because datetimeoffset math just works as if the times were all UTC.) It seems like something that Postgres could use. Especially because the overhead for storing UTC offsets isn't that much. (10 bytes versus 8.)