

I entrust you with this horror, go figure out what to blame.
shutdown-analyze.sh
#! /usr/bin/env bash
shutdown_start=$(journalctl -b -1 -u systemd-logind --grep="System is (powering down|rebooting)" --output=cat --no-pager --output-fields=_SOURCE_REALTIME_TIMESTAMP)
shutdown_start=$((shutdown_start / 1000000))
units=$(journalctl -b -1 --since=@$shutdown_start --output=cat --no-pager --output-fields=UNIT JOB_TYPE=stop CODE_FUNC=job_emit_start_message)
for u in $units; do
stopping_start=$(journalctl -b -1 --since=@$shutdown_start -u "$u" --output=cat --no-pager --output-fields=_SOURCE_REALTIME_TIMESTAMP JOB_TYPE=stop CODE_FUNC=job_emit_start_message _SYSTEMD_UNIT=init.scope)
stopping_end=$(journalctl -b -1 --since=@$shutdown_start -u "$u" --output=cat --no-pager --output-fields=_SOURCE_REALTIME_TIMESTAMP JOB_TYPE=stop CODE_FUNC=job_emit_done_message _SYSTEMD_UNIT=init.scope)
duration_human=$(systemd-analyze timespan $((stopping_end - stopping_start))us | tail -1 | sed 's/.*: //')
printf "%s\t%10s %s\n" $((stopping_end - stopping_start)) "$duration_human" "$u"
done | sort -rn | cut -f 2

Individual services can override the default 90 seconds timeout. But then you can override their override if you think you are smarter, of course.