Cavendish went into the final sprint without any teammates, having burned through his lead-out in the final kilometres to bring back a stubborn breakaway group.
Sagan, with Cavendish, piggy-backed on stage seven winner Alexander Kristoff’s Katusha train and sprinted past the Norwegian in the final 100m.
Earlier in the 138km stage, on a particularly straight section of road, green jersey wearer Sagan attempted to bring the race to life and split the peloton with a burst off the front. The world champion seemed angered that most of his Tinkoff teammates hadn’t followed his move, with Sagan retreating back into the peloton for the rest of the stage.
Once the teams got onto the finishing circuit in Sacremento, Tinkoff came to the front in numbers this time, needing to bring back the seven-man breakaway, who were still over a minute ahead of the pack.
Tinkoff’s show of strength saw the peloton strung out on the wide roads, but with two kilometres to ride the breakaway started to attack each other, meaning Dimension Data needed to use Mark Renshaw to help drag them back, leaving Cavendish alone for the final stages.
Watch highlights of stage eight of the Tour of California
Katusha swarmed to the front for Kristoff, with Sagan and Cavendish sitting on the Norwegian’s wheel. Sagan pre-empted Kristoff’s sprint and got the edge on him, but Cavendish wasn’t to be beaten, easing past Sagan and over the line.
Amgen Tour of California stage eight, Sacramento – Sacramento (138km)
1. Mark Cavendish (GBr) Dimension Data 3-01-12
2. Peter Sagan (Svk) Tinkoff, st
3. Alexander Kristoff (Nor) Katusha, st
4. Danny van Poppel (Ned) Team Sky, st
5. John Degenkolb (Ger) Giant-Alpecin, st
6. Niccolo Bonifazio (Ita) Trek-Segafredo, st
7. Jempy Drucker (Lux) BMC, st
8. Ariel Richeze (Arg) Etixx-Quick Step, st
9. Dylan Groenewegen (Ned) LottoNL-Jumbo, st
10. Travis McCabe (USA) Holowesko-Citadel, st
General classification after stage seven
1. Julian Alaphilippe (Fra) Etixx-QuickStep
2. Rohan Dennis (Aus) BMC Racing at 21 secs
3. Brent Bookwalter (USA) BMC Racing at 43 secs
4. Andrew Talansky (USA) Cannondale at 52 secs
5. Lawson Craddock (USA) Cannondale at 1-22
6. Samuel Sanchez (Spa) BMC Racing at 1-22
7. George Bennett (NZl) LottoNl-Jumbo at 1-50
8. Jurgen Van den Broeck (Bel) Katusha at 1-53
9. Neilson Powless (USA) Axeon Hagens Berman at 1-57
10. Laurens Ten Dam (Ned) Giant-Alpecin, at 2-13