Pin ensures that a value won't move in memory, which is required for self-referential types like async futures. Most async code hides this complexity, but understanding it helps when you hit compiler errors about Unpin. A type is Unpin if it's safe to move even when pinned; most types are Unpin by default. When you write async fn, the compiler generates a state machine that might borrow across .await points, making it !Unpin. You pin futures with Box::pin() or pin!(). I rarely use Pin directly in application code, but it's essential for writing async combinators, custom runtimes, or intrusive data structures. The guarantees enable memory-safe async without garbage collection.