Lewis Hamilton won ahead of Max Verstappen and Valtteri Bottas, passing both in the early stages before dominating to the finish.
At the start, Bottas leapt off the front row best, with the polesitter then racing down to the rapid right-hand Turn 1 to extend his advantage as Verstappen had a half look at passing the Hamilton before backing out.
Behind the leaders, Sergio Perez lost fourth with a slow getaway, which allowed Carlos Sainz to jump up to fifth on the run to Turn 1, with Esteban Ocon and Lando Norris battling over sixth further around lap one – the McLaren muscling by on the outside run through Turn 11.
Bottas's lead at the end of lap one of 66 was 0.8-seconds, but that was soon erased as the safety car was called out to allow the Portimao marshals to clear debris that stemmed from Kimi Raikkonen colliding with his Alfa Romeo teammate Antonio Giovinazzi as they started lap two.
The collision, with Raikkonen closing on Giovinazzi, broke the 2007 world champion's front wing, which became wedged under his car and meant he skated straight on into the gravel at Turn 1, where he retired.
The race resumed at the start of lap seven – the pack brought twice through the pitlane under the suspension as the main straight was cleared – Bottas waited until he reached the grid hatchings before roaring back to speed, which caught out Hamilton.
Verstappen was therefore able to close in on the world champion and pass him with a thrilling move around the outside of Turn 1 before chasing after Bottas.
For the next few tours it looked as if Hamilton was struggling to hang onto the leaders, but Verstappen sliding coming out of the penultimate corner on lap 10 gave the Mercedes driver the chance to attack as the Red Bull lost DRS to Bottas.
Hamilton attacked at the first chance, using DRS to shoot to the inside line at Turn 1, sealing the move before Verstappen attacked back on the outside of the ever-tightening right of Turn 3, where Hamilton ran him out of road on the outside and chased on after Bottas.
For the rest of the race's opening third, Bottas and Hamilton edged slightly clear of Verstappen, but he remained resolutely in play as they all worked on keeping their medium tyres in shape.
After a cagey period with Bottas holding firm in front as the leaders regularly lapped in the mid-to-high 1m22s, Hamilton gained considerably running onto the main straight at the end of lap 19, and with DRS at the start of the next he attacked for the lead.
Bottas defended the inside line, but Hamilton swept around the outside line to seize the lead for first time, quickly scampering out of DRS range ahead of his teammate.
As the race approached half-distance, Hamilton had worked his lead above three seconds, with Verstappen remaining within DRS range of Bottas but unable to get close enough to mount a move for lap after lap.
Just as Verstappen dropped out of DRS threat, Red Bull called him to take hard tyres at the end of lap 35 – the Dutchman locking up both front tyres approaching the speed limit line.
Mercedes brought Bottas the following time by, where a stop taking one-second longer than Verstappen's – 3.3s vs 2.3s – meant the Red Bull was able to get close going through the opening turns after Bottas rejoined.
The Mercedes driver lost momentum with cold tyres coming out of Turn 3, which gave Verstappen his chance to pounce with warmer rubber, and he attacked out of Turn 4 and took second down Bottas's inside at the hairpin.
Up front, Hamilton came in at the end lap 37, also taking hards – albeit a slightly used set compared to the brand-new ones on Verstappen's car.
Once the pitstop sequence had shaken out, Hamilton's lead was 3.2s over Verstappen, who initially started to eat into that advantage before falling back again over the next few laps as Hamilton recorded a string of fastest laps.
Hamilton's lead was never under threat from there, although he had to make one more pass for the lead – an easy DRS overtake on the main straight to get by Perez, who had cycled into the net lead by completing a very long opening stint, the second Red Bull only coming in at the end of lap 51 and taking softs.
Hamilton's margin of victory was 29.1s at the flag, with Verstappen initially just keeping Bottas at bay over the initial laps of the second stint, much as the Finn had done in reverse towards the end of the first half of the race.
The gap between the pair was then grew when Bottas spent two laps approaching the final 10 tours losing two seconds each time to Verstappen due to an exhaust temperature sensor briefly robbing him of top speed.
As Bottas was far enough ahead of Perez, who had taken the fastest lap with his softs, Mercedes brought its second car in with three laps remaining to try and sneak back the bonus point.
Bottas did achieve that with a 1m19.865s, but only because Verstappen's 1m19.849s was deleted for running too wide exiting the penultimate corner on the final lap.
Behind the top three came Perez, who had run behind Norris after the restart after the pair had shuffled Sainz back.
The Red Bull then soon brought its pace advantage to bear to retake fourth and Perez began his long drive to extend the life of the mediums he had started on.
With Perez gone ahead, Norris saw off Ferrari's attempt to undercut at the pitstops – where he and Sainz exchanged softs for mediums – and the Briton then kept the softer rubber alive much better than his former teammate.
Sainz tumbled to 11th at the flag, with the drivers initially behind him taking hard tyres at their stops and enjoying much fastest pace across the rest of the race.
Norris did not face this problem, as he came home fifth ahead of Charles Leclerc, who had been the first driver to start Sainz's plunge shortly after half distance.
Ocon finished seventh ahead of teammate Fernando Alonso, who made notable progress the longer the race went on, enjoying his time on the hard rubber to the finish.
Daniel Ricciardo rose brilliantly from P16 on the grid in the early stages, making up several places in the early laps, then executing a long first stint that meant he was on the attack late-on, albeit passed by Alonso when the Alpine was demonstrating superior pace.
Pierre Gasly rounded out the top 10 ahead of Sainz.
|2||Max Verstappen||Red Bull||29.148|
|4||Sergio Perez||Red Bull||39.735|
|11||Carlos Sainz Jr.||Ferrari||1'18.955|
|12||Antonio Giovinazzi||Alfa Romeo||1 lap|
|13||Sebastian Vettel||Aston Martin||1 lap|
|14||Lance Stroll||Aston Martin||1 lap|
|15||Yuki Tsunoda||AlphaTauri||1 lap|
|16||George Russell||Williams||1 lap|
|17||Mick Schumacher||Haas||2 laps|
|18||Nicholas Latifi||Williams||2 laps|
|19||Nikita Mazepin||Haas||2 laps|
|Kimi Raikkonen||Alfa Romeo|