This course covers the foundations of distributed systems including models of computing, logical clocks and synchronization, consensus, distributed indexing, concurrency, consistency, failures, reliability and security. We will examine popular applications of distributed computing; analyze how the foundations manifest themselves in different ways depending on real-world constraints. Such applications include distributed file systems, peer-to-peer systems, distributed transactions, and web services.