Tail recursion is when a recursive call is the last thing executed by a function. This allows the call stack to reuse stack frames rather than building up the call stack, avoiding stack overflow issues. A tail recursive function calculates results as it goes rather than waiting to return from recursive calls. This optimization makes tail recursive functions more efficient than regular recursive functions in terms of speed and memory usage.