Even if you upgrade with coordinated downtime across your entire service stack ( a bit old-school, but still happens more than you might imagine. ), then you still have to occasionally deal with requests that get persisted somewhere, possibly for support purposes, and it's much handier if the wire format remains compatible, at least between immediate versions.
Yes, breaking changes need to be staged carefully/compatibly across versions.
Simple renaming/reordering is not a breaking change between code versions. The wire format knows numeric ids, not names. It breaks code compilation until the renames are put into effect. There is a subtle breakage where someone renames a field (think: field -> old_field) and then later adds "field" to mean something else; software that isn't recompiled in this window might not recognize that "field" is potentially different. Uncompiled languages may suffer this even more subtly. -- All of this to say, breaking compilation is not the end of the world but there are more dragons as the scope grows.
Stop-the-world is usually only needed when someone has made an unplanned/incompatible change with versions that are still running. If your infrastructure+development is done right (hah) this should never happen.