Every node stores a balance factor: height(left) − height(right). Valid values are −1, 0 and +1. Insertion walks back up the path to the root, updating heights and checking factors.

A factor of +2 with the new key in the outer subtree needs a single right rotation; if the key landed in the inner subtree you need a left-right double rotation. The mirrored cases apply for −2.
Each rotation is O(1) pointer surgery, and at most one rebalance is needed per insertion, so insertion stays O(log n).