If you're using an atom, you're already sticking state in a place; the problem with atoms is choosing granularity. If one atom has everything in it, it will become a point of contention.
If your compare-and-set returns false, what do you do?
STM resolves these issues by letting you coordinate updates to more granular, finer-scoped refs
The drawback here is that the STM (at least the Clojure implementation few years ago when I tested it) is orders of magnitude slower than simple atomic reference.
It actually does not have to be, but this is how it is (was) implemented. I built a simple STM (in Java) as part of my bachelor thesis and its performance was comparable to the atomic reference.
If your compare-and-set returns false, what do you do?
STM resolves these issues by letting you coordinate updates to more granular, finer-scoped refs