South Africa skittled Sri Lanka for 110 on day two of the second Test at Newlands to reach stumps 317 runs clear after a dismal showing from the tourists.
Quinton de Kock (101) completed his century as the Proteas posted a first-innings total of 392, before Vernon Philander (4-27) and Kagiso Rabada (4-37) took four wickets apiece to dismiss Sri Lanka in just 43 overs.
Despite their position of strength, South Africa opted against the follow-on and added a further 35 runs without loss before the end of the day.
Holding a 1-0 advantage in the three-match series, South Africa now appear certain to take an unassailable lead.
Beginning Tuesday on 297-6, Kyle Abbott (16) was first to fall, before De Kock - who surpassed 1,000 Test runs on day one - was seen off by Lahiru Kumara (6-122).
Kumara went on to claim the remaining two wickets of the South African innings but Sri Lanka's performance with the bat fell well short of those standards.
Rabada made early inroads with the scalps of Kaushal Silva (11), Dimuth Karunaratne (24) - the 21-year-old's 50th wicket in 13 Tests - and Angelo Mathews (2) as Sri Lanka crumbled to 60-4.
The right-arm fast bowler, who took 3-10 in 25 balls at the start of the final session, added the wicket of Dinesh Chandimal (4) before Philander proceeded to tear through the lower order and surpass 150 Test wickets, taking 4-5 in 12 balls to see off the Sri Lankan tail.
Rangana Herath (1), Suranga Lakmal (0), Kumara (4) and Nuwan Pradeep (0) all departed with only 32 runs being added to Sri Lanka's total, although most of those came courtesy of top-scorer Upul Tharanga (26 not out).
The 79 runs picked up by Sri Lanka from the second to the 10th wickets was their worst record against South Africa in Tests.
The hosts could justifiably have asked Sri Lanka to bat again on the back of their woeful performance at the crease, but Stephen Cook and Dean Elgar emerged to kick-off a second South African innings.
Elgar, who hit 129 in the first innings, reached stumps on 19, while Cook - out for a duck on Monday - had amassed 15 by the end of the day.