A multi-threaded algorithm is considered lock-free if there is an upper bound on the total number of steps it must perform between successive completions of operations. Lock-free algorithms guarantee forward progress in some finite number of operations, making them suitable for SingleStore skiplists and sync replication. However, writing correct lock-free code is extremely difficult due to issues such as data races, memory reordering, and the ABA problem. The presented lock-free stack implementation addresses these challenges by using tagged pointers, hazard pointers, and sequentially consistent memory semantics. Despite its complexity, the stack's performance is limited by its single point of contention and may not be worth it for small data structures. Lock-free algorithms can guarantee progress but do not always guarantee efficiency, and existing implementations should be preferred over trying to write one's own lock-free algorithms.