Kagiso Rabada and Vernon Philander took four wickets each as South Africa bowled out Sri Lanka for 110 and took total control on the second day of the second Test at Newlands on Tuesday.
South Africa built on a first innings lead of 282 and reached 35 for no wicket by the close, an overall lead of 317 runs. With three days remaining, Sri Lanka faced a seemingly impossible task if they were to prevent the hosts from securing a series-clinching win.
Rabada took four for 37 and Philander four for 27. The Sri Lankan batting crumbled after Rabada broke a stubborn opening partnership.
Kaushal Silva and Dimuth Karunaratne defied South Africa's new ball attack for 73 minutes, putting on 31 runs before Rabada made the breakthrough in the 16th over when Silva was forced on to the back foot by a lifting delivery which he played on to his stumps.
Sri Lanka lost a second wicket shortly before tea when Kusal Mendis, who had earlier slog-swept left-arm spinner Keshav Maharaj for six, tried to repeat the shot and top-edged a simple catch to JP Duminy at short cover.
The innings went into an irreversible slide three balls after tea when Dimuth Karunaratne, who had made a patient 24, square-cut Rabada and Temba Bavuma dived to take a sharp, low catch at backward point.
Rabada and Maharaj reduced the Lankans to 78 for six. Upul Tharanga and Rangana Herath put on 22 for the seventh wicket before Philander wrapped up the innings by taking the final four wickets at a personal cost of five runs in 12 balls.
Maharaj, bowling into a strong south-easterly wind, took two for 32 while the two fast bowlers took seven of their combined eight wickets with the wind at their backs.
Both Rabada and Philander reached personal milestones. Rabada took his 50th wicket in his 13th Test, while Philander achieved 150 wickets in 39 Tests.
Earlier Quinton de Kock made his third Test century and fast bowler Lahiru Kumara took six wickets as South Africa were bowled out for 392 in their first innings.
Kumara, 19, who had not taken more than two wickets in an innings in his previous two Test matches and three other first-class games, finished with six for 122.
De Kock took his score from 68 to 101, made off 124 balls with 11 fours, before edging Kumara to wicketkeeper Dinesh Chandimal.
Seven South Africans were caught behind, three by Mendis when Chandimal was suffering from a fever on the first day and four by Chandimal on Tuesday. The combined wicketkeeping haul was one more than the Sri Lankan Test record and equal to the world record.