I know it is too late, but I want to share it with you.
This answer is first posted here, to save your time, I copy it there.
I am not quite sure about this answer, so I originally want to post it as a comment, but as you see, I don't have enough reputation to add a comment, so I have to post it as an answer.
Remember that I have made other changes to my .emacs.d, so it is possible that my answer is totally wrong. If it doesn't work for you, you may follow this link.
I have run into similar case as yours. I run emacs as daemon using systemd. And when I poweroff, recentf can't be save, but when I stop daemon manually, it can. Then I found something I ignored here.
To save time, the core is that Emacs built with gtk support is not a good choice when using Emacs as a daemon, because there is some bug.
You can also see Emacs itself say something about this, if you journalctl it:
Emacs might crash when run in daemon mode and the X11 connection is
Using an Emacs configured with --with-x-toolkit=lucid does not have this problem.
So the point is clear now. Don't build your Emacs with gtk when using it as daemon.
For the solution, I think it may be interrelated to your distribution.
As for me, on Gentoo, it is to enable useflag "motif" and disable useflag "athena" "gtk" "Xaw3d".
For others distribution, you may find it yourself.
The link I found say this:
USE flags for toolkits gtk, motif, athena, and aqua are mutually
exclusive. Generally, USE="gtk" is a good choice. However, if
intending to use Emacs as a daemon, USE="motif -athena -gtk -Xaw3d" or
USE="athena Xaw3d -gtk -motif" is recommended instead because of bug
#292471. USE="athena Xaw3d" resembles USE="gtk" very well. USE="aqua" is a special case applying only to Mac OS X.