Wearing the points jersey, the two-time world champion looked cool, calm, and collected as his Bora-Hansgrohe team-mates were able to shut down a number of attacks in the final 10km, and made sure that he was well-positioned for the final sprint.
Quick-Step Floors had the numerical advantage with four men on the front going under the flamme rouge, but Sagan was perfectly positioned in fifth place.
With a tailwind blowing up the finishing straight, Sagan launched his sprint early, catching his rivals off guard and cruising across the finish line ahead of Sacha Modolo (UAE Team Emirates) and Matteo Trentin (Quick-Step Floors).
Meanwhile the yellow jersey of Simon Spilak (Katusha-Alpecin) finished safely in the pack, to take his 52 second lead at the top of GC into stage nine’s final time trial.
How it happened
The eighth stage of the Tour de Suisse saw the riders take on eight laps of a hilly circuit in the town of Schaffhausen, totalling just 100km in length.
Four riders attacked early in the opening lap: Lasse Norman Hansen (Aqua Blue Sport), Jaco Venter (Dimension Data), Jelle Wallays (Lotto Soudal), and Nick van der Lijke (Roompot-Nederlandse Loterij), who quickly gained a gap of around two minutes.
Hansen was leading the mountains classification going into the final road stage with 33 points, but Van der Lijke was only one point behind.
However Hansen dominated the eight classified climbs on the stage, consistently out-sprinting his Dutch rival at the top of each climb to confirm his victory in the classification.
The four-man break did a good job of maintaining their lead, but in the with 40km remaining the peloton started to raise the pace to bring the gap down.
With 20km to go the gap was down below a minute as Bora-Hansgrohe set a searing pace as they tried to set up Peter Sagan for a second stage win of the race.
However the pace slackened on a slight hill, which gave the opportunity for an attack that was duly taken by Gianluca Brambilla (Quick-Step Floors). The Italian briefly opened a gap, but was quickly brought back, and his attack did nothing but trimming the gap’s break down to less than 30 seconds.
The catch was made as they crosses the line with one lap and 12.5km to go, but the real drama started with 6.7km to go when Michael Matthews (Team Sunweb) launched an unexpected attack.
He was joined by a number of riders including Greg Van Avermaet (BMC Racing) and Tim Wellens (Lotto Soudal), establishing a small gap before a moment of hesitation saw them caught.
The pace was still blisteringly fast, but Bora-Hansgrohe were able to neutralise a few more moves despite only having a couple of riders remaining to support Sagan.
Into the final two kilometres and the peloton was down to no more than 40 riders, but a number of those were from Quick-Step, who had four riders near the front of affairs.
The Belgian team led it out into the finale 500m, but Peter Sagan was poised in fifth wheel, jumping clear in the final 200m to take victory by tow bike lengths ahead of Sacha Modolo .
Tour de Suisse 2017, stage eight: Schaffhausen to Schaffhausen (100km)
1. Peter Sagan (Svk) Bora-Hansgrohe, in 2-12-50
2. Sacha Modolo (Ita) UAE Team Emirates
3. Matteo Trentin (Ita) Quick-Step Floors
4. Magnus Cort Nielsen (Den) Orica-Scott
5. Niccolo Bonifazio (Ita) Bahrain-Merida
6. Michael Matthews (Aus) Team Sunweb
7. John Degenkolb (Ger) Trek-Segafredo
8. Oscar Gatto (Ita) Astana
9. Kevin Reza (Fra) FDJ
10. Salvatore Puccio (Ita) Team Sky, all at same time
General classification after stage eight
1. Simon Spilak (Slo) Katusha-Alpecin, in 27-59-50
2. Damiano Caruso (Ita) BMC Racing, at 52 secs
3. Steven Kruijswijk (Ned) LottoNl-Jumbo, at 1-05
4. Domenico Pozzovivo (Ita) Ag2r La Mondiale, at 2-28
5. Rui Costa (Por) UAE Team Emirates, at 2-35
6. Mathias Frank (Sui) Ag2r La Mondiale, at 2-51
7. Mikel Nieve (Esp) Team Sky, at 2-54
8. Ion Izagirre (Esp) Bahrain-Meirda, at 3-51
9. Marc Soler (Esp) Movistar, at 4-07
10. Pello Bilbao (Esp) Astana, at 4-10