Offspinner Dilruwan Perera finished with his best match figures of 10 for 78 after taking 6 for 32 in the second innings while Rangana Herath leaped to ninth on the all-time wicket-takers' list with his 3 for 38.
Herath surpassed Shaun Pollock and Dale Steyn in this match. Steyn has been chasing Pollock's record of 421 wickets to become South Africa's leading Test wicket-taker and drew level in this match.
That will serve as scant consolation for South Africa, whose line-up has serious questions to answer about their shot selection and temperament.
South Africa have never faced fewer overs in Asia than they did in this innings. Only three of their batsmen got into double figures and only one, No. 7 Vernon Philander, scored more than 20.
They lost wickets at intervals of between five and nine minutes between lunch and tea and lost the game inside eight sessions. Dimuth Karunaratne on his own scored more runs - 218 - than South Africa over both innings - 199.
Despite forcing a collapse that saw Sri Lanka lose 6 for 73 on the third morning, South Africa was facing a mammoth task after conceding a first-innings deficit of 161 runs.
They were set 352 to win, which required them to pull off the joint third-highest successful chase on the island against an attack they have been unable to decipher.
Scorecard:
Sri Lanka first innings - 287 (Karunaratne 158*, Rabada 4-50, Shamsi 3-91)
South Africa first innings - 126 (du Plessis 49, Dilruwan 4-46, Lakmal 3-21)
Sri Lanka second innings- 190 (Karunaratne 60, Maharaj 4-58, Rabada 3-44)
South Africa second innings- 73 (Philander 22, Dilruwan 6-32, Herath 3-38)