How we handle WordPress updates without breaking client sites

We manage WordPress sites for a range of clients. Not all of them are on formal maintenance retainers, which means some of them have been running on outdated plugins for months before we get the call that something broke. The call usually comes at the worst possible time. Friday evening. Saturday morning. A client's biggest traffic day of the year.
Most WordPress breakages we have seen trace back to one of three things: a plugin update that conflicted with another plugin, a PHP version change that the theme or a key plugin was not ready for, or a WordPress core update applied without testing on staging first. All three are preventable. None of them are prevented by good intentions alone. They require a process.
The staging-first rule
Every client site we manage has a staging environment. This was not always the case. Earlier in our work, staging felt like overhead for smaller sites. We changed that position after one too many incidents. The cost of staging is small. The cost of debugging a broken WooCommerce checkout in production while the client refreshes their orders page is not.
Our update process is: run updates on staging, test the critical paths specific to that site (usually checkout, contact forms, and any custom functionality), check the error log, and only then apply to production. For sites with high transaction volume, we do production updates during low-traffic windows, never during business hours.
Plugin management is underestimated work
The average WordPress site we inherit has between fifteen and thirty active plugins. Many of them are doing things that could be achieved with fewer dependencies, or with native WordPress functionality that has been added since the plugin was installed. Part of our maintenance work is periodic plugin audits: what is this for, is it still needed, is there a more actively maintained alternative.
Plugin sprawl is a security surface and a compatibility liability. Every plugin you remove is one fewer thing that can conflict with the next update. We have sites we have brought from twenty-eight plugins to fourteen without losing any functionality, and they are faster, simpler, and considerably easier to maintain.
The other thing we do that clients often underestimate is keeping PHP versions current across our hosting environments. WordPress officially recommends specific PHP versions, and running on an unsupported or older version is a quiet risk that does not announce itself until something breaks or, worse, until a vulnerability is exploited. We document the PHP version per site and flag any that fall behind in our quarterly reviews.
None of this is exciting work. That is the point. A site that stays up and runs correctly is invisible. The drama only happens when the process breaks down.