.
```
## /README.md
This repository contains free resources to learn System Design concepts and prepare for interviews.
👉 Subscribe to my [AlgoMaster Newsletter](https://bit.ly/amghsd) and get a **FREE System Design Interview Handbook** in your inbox.
✅ If you are new to System Design, start here: [System Design was HARD until I Learned these 30 Concepts](https://blog.algomaster.io/p/30-system-design-concepts)
## 📌 System Design Key Concepts
- [Scalability](https://blog.algomaster.io/p/scalability)
- [Availability](https://blog.algomaster.io/p/system-design-what-is-availability)
- [CAP Theorem](https://blog.algomaster.io/p/cap-theorem-explained)
- [ACID Transactions](https://blog.algomaster.io/p/what-are-acid-transactions-in-databases)
- [Consistent Hashing](https://blog.algomaster.io/p/consistent-hashing-explained)
- [Rate Limiting](https://blog.algomaster.io/p/rate-limiting-algorithms-explained-with-code)
- [SPOF](https://blog.algomaster.io/p/system-design-how-to-avoid-single-point-of-failures)
- [Fault Tolerance](https://www.cockroachlabs.com/blog/what-is-fault-tolerance/)
- [Consensus Algorithms](https://medium.com/@sourabhatta1819/consensus-in-distributed-system-ac79f8ba2b8c)
- [Gossip Protocol](http://highscalability.com/blog/2023/7/16/gossip-protocol-explained.html)
- [Service Discovery](https://blog.algomaster.io/p/service-discovery-in-distributed-systems)
- [API Design](https://abdulrwahab.medium.com/api-architecture-best-practices-for-designing-rest-apis-bf907025f5f)
- [Disaster Recovery](https://cloud.google.com/learn/what-is-disaster-recovery)
- [Distributed Tracing](https://www.dynatrace.com/news/blog/what-is-distributed-tracing/)
## 🛠️ System Design Building Blocks
- [APIs](https://blog.algomaster.io/p/whats-an-api)
- [Content Delivery Network (CDN)](https://blog.algomaster.io/p/content-delivery-networks)
- [Proxy vs Reverse Proxy](https://blog.algomaster.io/p/proxy-vs-reverse-proxy-explained)
- [Domain Name System (DNS)](https://www.cloudflare.com/learning/dns/what-is-dns/)
- [Caching](https://blog.algomaster.io/p/4d7d6f8a-6803-4c7b-85ca-864c87c2cbf2)
- [Caching Strategies](https://blog.algomaster.io/p/top-5-caching-strategies-explained)
- [Distributed Caching](https://blog.algomaster.io/p/distributed-caching)
- [API Gateway](https://blog.algomaster.io/p/what-is-an-api-gateway)
- [Load Balancing](https://blog.algomaster.io/p/load-balancing-algorithms-explained-with-code)
- [Databases Types](https://blog.algomaster.io/p/15-types-of-databases)
- [SQL vs NoSQL](https://blog.algomaster.io/p/sql-vs-nosql-7-key-differences)
- [Database Indexes](https://blog.algomaster.io/p/a-detailed-guide-on-database-indexes)
- [Consistency Patterns](https://systemdesign.one/consistency-patterns/)
- [HeartBeats](https://blog.algomaster.io/p/heartbeats-in-distributed-systems)
- [Circuit Breaker](https://medium.com/geekculture/design-patterns-for-microservices-circuit-breaker-pattern-276249ffab33)
- [Idempotency](https://blog.algomaster.io/p/idempotency-in-distributed-systems)
- [Database Scaling](https://blog.algomaster.io/p/system-design-how-to-scale-a-database)
- [Data Replication](https://redis.com/blog/what-is-data-replication/)
- [Data Redundancy](https://blog.algomaster.io/p/489440f1-9c80-4241-9ec8-de156964c3b9)
- [Database Sharding](https://blog.algomaster.io/p/what-is-database-sharding)
- [Database Architectures](https://www.mongodb.com/developer/products/mongodb/active-active-application-architectures/)
- [Failover](https://www.druva.com/glossary/what-is-a-failover-definition-and-related-faqs)
- [Bloom Filters](https://blog.algomaster.io/p/bloom-filters)
- [Message Queues](https://blog.algomaster.io/p/message-queues)
- [WebSockets](https://blog.algomaster.io/p/websockets)
- [Checksums](https://blog.algomaster.io/p/what-are-checksums)
- [Microservices Guidelines](https://newsletter.systemdesign.one/p/netflix-microservices)
- [Distributed Locking](https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html)
## ⚖️ System Design Tradeoffs
- [Top 15 Tradeoffs](https://blog.algomaster.io/p/system-design-top-15-trade-offs)
- [Vertical vs Horizontal Scaling](https://blog.algomaster.io/p/system-design-vertical-vs-horizontal-scaling)
- [Concurrency vs Parallelism](https://blog.algomaster.io/p/concurrency-vs-parallelism)
- [Long Polling vs WebSockets](https://blog.algomaster.io/p/long-polling-vs-websockets)
- [Batch vs Stream Processing](https://blog.algomaster.io/p/batch-processing-vs-stream-processing)
- [Stateful vs Stateless Design](https://blog.algomaster.io/p/741dff8e-10ea-413e-8dd2-be57434917d2)
- [Strong vs Eventual Consistency](https://blog.algomaster.io/p/7d9da525-fe25-4e16-94e8-8056e7c57934)
- [Read-Through vs Write-Through Cache](https://blog.algomaster.io/p/59cae60d-9717-4e20-a59e-759e370db4e5)
- [Push vs Pull Architecture](https://blog.algomaster.io/p/af5fe2fe-9a4f-4708-af43-184945a243af)
- [REST vs RPC](https://blog.algomaster.io/p/106604fb-b746-41de-88fb-60e932b2ff68)
- [Synchronous vs. asynchronous communications](https://blog.algomaster.io/p/aec1cebf-6060-45a7-8e00-47364ca70761)
- [Latency vs Throughput](https://aws.amazon.com/compare/the-difference-between-throughput-and-latency/)
## 🖇️ System Design Architectural Patterns
- [Client-Server Architecture](https://blog.algomaster.io/p/4585cf8e-30a4-4295-936f-308a25cb716c)
- [Microservices Architecture](https://medium.com/hashmapinc/the-what-why-and-how-of-a-microservices-architecture-4179579423a9)
- [Serverless Architecture](https://blog.algomaster.io/p/2edeb23b-cfa5-4b24-845e-3f6f7a39d162)
- [Event-Driven Architecture](https://www.confluent.io/learn/event-driven-architecture/)
- [Peer-to-Peer (P2P) Architecture](https://www.spiceworks.com/tech/networking/articles/what-is-peer-to-peer/)
## ✅ How to Answer a System Design Interview Problem
### [Read the Full Article](https://blog.algomaster.io/p/how-to-answer-a-system-design-interview-problem)
## 💻 System Design Interview Problems
### Easy
- [Design URL Shortener like TinyURL](https://blog.algomaster.io/p/design-a-url-shortener)
- [Design Leaderboard](https://systemdesign.one/leaderboard-system-design/)
- [Design Content Delivery Network (CDN)](https://www.youtube.com/watch?v=8zX0rue2Hic)
- [Design Parking Garage](https://www.youtube.com/watch?v=NtMvNh0WFVM)
- [Design Vending Machine](https://www.youtube.com/watch?v=D0kDMUgo27c)
- [Design Distributed Key-Value Store](https://www.youtube.com/watch?v=rnZmdmlR-2M)
- [Design Distributed Cache](https://www.youtube.com/watch?v=iuqZvajTOyA)
- [Design Authentication System](https://www.youtube.com/watch?v=uj_4vxm9u90)
- [Design Unified Payments Interface (UPI)](https://www.youtube.com/watch?v=QpLy0_c_RXk)
### Medium
- [Design WhatsApp](https://blog.algomaster.io/p/design-a-chat-application-like-whatsapp)
- [Design Spotify](https://blog.algomaster.io/p/design-spotify-system-design-interview)
- [Design Distributed Job Scheduler](https://blog.algomaster.io/p/design-a-distributed-job-scheduler)
- [Design a Scalable Notification Service](https://blog.algomaster.io/p/design-a-scalable-notification-service)
- [Design Instagram](https://www.youtube.com/watch?v=VJpfO6KdyWE)
- [Design Tinder](https://www.youtube.com/watch?v=tndzLznxq40)
- [Design Facebook](https://www.youtube.com/watch?v=9-hjBGxuiEs)
- [Design Twitter](https://www.youtube.com/watch?v=wYk0xPP_P_8)
- [Design Reddit](https://www.youtube.com/watch?v=KYExYE_9nIY)
- [Design Netflix](https://www.youtube.com/watch?v=psQzyFfsUGU)
- [Design Youtube](https://www.youtube.com/watch?v=jPKTo1iGQiE)
- [Design Google Search](https://www.youtube.com/watch?v=CeGtqouT8eA)
- [Design E-commerce Store like Amazon](https://www.youtube.com/watch?v=EpASu_1dUdE)
- [Design TikTok](https://www.youtube.com/watch?v=Z-0g_aJL5Fw)
- [Design Shopify](https://www.youtube.com/watch?v=lEL4F_0J3l8)
- [Design Airbnb](https://www.youtube.com/watch?v=YyOXt2MEkv4)
- [Design Autocomplete for Search Engines](https://www.youtube.com/watch?v=us0qySiUsGU)
- [Design Rate Limiter](https://www.youtube.com/watch?v=mhUQe4BKZXs)
- [Design Distributed Message Queue like Kafka](https://www.youtube.com/watch?v=iJLL-KPqBpM)
- [Design Flight Booking System](https://www.youtube.com/watch?v=qsGcfVGvFSs)
- [Design Online Code Editor](https://www.youtube.com/watch?v=07jkn4jUtso)
- [Design Stock Exchange System](https://www.youtube.com/watch?v=dUMWMZmMsVE)
- [Design an Analytics Platform (Metrics & Logging)](https://www.youtube.com/watch?v=kIcq1_pBQSY)
- [Design Payment System](https://www.youtube.com/watch?v=olfaBgJrUBI)
- [Design a Digital Wallet](https://www.youtube.com/watch?v=4ijjIUeq6hE)
### Hard
- [Design Location Based Service like Yelp](https://www.youtube.com/watch?v=M4lR_Va97cQ)
- [Design Uber](https://www.youtube.com/watch?v=umWABit-wbk)
- [Design Food Delivery App like Doordash](https://www.youtube.com/watch?v=iRhSAR3ldTw)
- [Design Google Docs](https://www.youtube.com/watch?v=2auwirNBvGg)
- [Design Google Maps](https://www.youtube.com/watch?v=jk3yvVfNvds)
- [Design Zoom](https://www.youtube.com/watch?v=G32ThJakeHk)
- [Design Distributed Counter](https://systemdesign.one/distributed-counter-system-design/)
- [Design File Sharing System like Dropbox](https://www.youtube.com/watch?v=U0xTu6E2CT8)
- [Design Ticket Booking System like BookMyShow](https://www.youtube.com/watch?v=lBAwJgoO3Ek)
- [Design Distributed Web Crawler](https://www.youtube.com/watch?v=BKZxZwUgL3Y)
- [Design Code Deployment System](https://www.youtube.com/watch?v=q0KGYwNbf-0)
- [Design Distributed Cloud Storage like S3](https://www.youtube.com/watch?v=UmWtcgC96X8)
- [Design Distributed Locking Service](https://www.youtube.com/watch?v=v7x75aN9liM)
- [Design Slack](https://systemdesign.one/slack-architecture/)
- [Design Live Comments](https://systemdesign.one/live-comment-system-design/)
## 📚 Books
- [Designing Data-Intensive Applications](https://www.amazon.in/dp/9352135245)
## 📩 Newsletters
- [AlgoMaster Newsletter](https://blog.algomaster.io/)
## 📺 YouTube Channels
- [Tech Dummies Narendra L](https://www.youtube.com/@TechDummiesNarendraL)
- [Gaurav Sen](https://www.youtube.com/@gkcs)
- [codeKarle](https://www.youtube.com/@codeKarle)
- [ByteByteGo](https://www.youtube.com/@ByteByteGo)
- [System Design Interview](https://www.youtube.com/@SystemDesignInterview)
- [sudoCODE](https://www.youtube.com/@sudocode)
- [Success in Tech](https://www.youtube.com/@SuccessinTech/videos)
## 📜 Must-Read Engineering Articles
- [How Discord stores trillions of messages](https://discord.com/blog/how-discord-stores-trillions-of-messages)
- [Building In-Video Search at Netflix](https://netflixtechblog.com/building-in-video-search-936766f0017c)
- [How Canva scaled Media uploads from Zero to 50 Million per Day](https://www.canva.dev/blog/engineering/from-zero-to-50-million-uploads-per-day-scaling-media-at-canva/)
- [How Airbnb avoids double payments in a Distributed Payments System](https://medium.com/airbnb-engineering/avoiding-double-payments-in-a-distributed-payments-system-2981f6b070bb)
- [Stripe’s payments APIs - The first 10 years](https://stripe.com/blog/payment-api-design)
- [Real time messaging at Slack](https://slack.engineering/real-time-messaging/)
## 🗞️ Must-Read Distributed Systems Papers
- [Paxos: The Part-Time Parliament](https://lamport.azurewebsites.net/pubs/lamport-paxos.pdf)
- [MapReduce: Simplified Data Processing on Large Clusters](https://research.google.com/archive/mapreduce-osdi04.pdf)
- [The Google File System](https://static.googleusercontent.com/media/research.google.com/en//archive/gfs-sosp2003.pdf)
- [Dynamo: Amazon’s Highly Available Key-value Store](https://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf)
- [Kafka: a Distributed Messaging System for Log Processing](https://notes.stephenholiday.com/Kafka.pdf)
- [Spanner: Google’s Globally-Distributed Database](https://static.googleusercontent.com/media/research.google.com/en//archive/spanner-osdi2012.pdf)
- [Bigtable: A Distributed Storage System for Structured Data](https://static.googleusercontent.com/media/research.google.com/en//archive/bigtable-osdi06.pdf)
- [ZooKeeper: Wait-free coordination for Internet-scale systems](https://www.usenix.org/legacy/event/usenix10/tech/full_papers/Hunt.pdf)
- [The Log-Structured Merge-Tree (LSM-Tree)](https://www.cs.umb.edu/~poneil/lsmtree.pdf)
- [The Chubby lock service for loosely-coupled distributed systems](https://static.googleusercontent.com/media/research.google.com/en//archive/chubby-osdi06.pdf)
---
If you find this resource helpful, please give it a star ⭐️ and share it with others!
## /diagrams/interview-template.png
Binary file available at https://raw.githubusercontent.com/ashishps1/awesome-system-design-resources/refs/heads/main/diagrams/interview-template.png
## /diagrams/system-design-github-logo.png
Binary file available at https://raw.githubusercontent.com/ashishps1/awesome-system-design-resources/refs/heads/main/diagrams/system-design-github-logo.png
## /implementations/java/consistent_hashing/ConsistentHashing.java
```java path="/implementations/java/consistent_hashing/ConsistentHashing.java"
package implementations.java.consistent_hashing;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
public class ConsistentHashing {
private final int numReplicas; // Number of virtual nodes per server
private final TreeMap ring; // Hash ring storing virtual nodes
private final Set servers; // Set of physical servers
public ConsistentHashing(List servers, int numReplicas) {
this.numReplicas = numReplicas;
this.ring = new TreeMap<>();
this.servers = new HashSet<>();
// Add each server to the hash ring
for (String server : servers) {
addServer(server);
}
}
private long hash(String key) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(key.getBytes());
byte[] digest = md.digest();
return ((long) (digest[0] & 0xFF) << 24) |
((long) (digest[1] & 0xFF) << 16) |
((long) (digest[2] & 0xFF) << 8) |
((long) (digest[3] & 0xFF));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("MD5 algorithm not found", e);
}
}
public void addServer(String server) {
servers.add(server);
for (int i = 0; i < numReplicas; i++) {
long hash = hash(server + "-" + i); // Unique hash for each virtual node
ring.put(hash, server);
}
}
public void removeServer(String server) {
if (servers.remove(server)) {
for (int i = 0; i < numReplicas; i++) {
long hash = hash(server + "-" + i);
ring.remove(hash);
}
}
}
public String getServer(String key) {
if (ring.isEmpty()) {
return null; // No servers available
}
long hash = hash(key);
// Find the closest server in a clockwise direction
Map.Entry entry = ring.ceilingEntry(hash);
if (entry == null) {
// If we exceed the highest node, wrap around to the first node
entry = ring.firstEntry();
}
return entry.getValue();
}
public static void main(String[] args) {
List servers = Arrays.asList("S0", "S1", "S2", "S3", "S4", "S5");
ConsistentHashing ch = new ConsistentHashing(servers, 3);
// Step 2: Assign requests (keys) to servers
System.out.println("UserA is assigned to: " + ch.getServer("UserA"));
System.out.println("UserB is assigned to: " + ch.getServer("UserB"));
// Step 3: Add a new server dynamically
ch.addServer("S6");
System.out.println("UserA is now assigned to: " + ch.getServer("UserA"));
// Step 4: Remove a server dynamically
ch.removeServer("S2");
System.out.println("UserB is now assigned to: " + ch.getServer("UserB"));
}
}
```
## /implementations/java/load_balancing_algorithms/IPHash.java
```java path="/implementations/java/load_balancing_algorithms/IPHash.java"
import java.util.List;
public class IPHash {
private List servers;
public IPHash(List servers) {
this.servers = servers;
}
public String getNextServer(String clientIp) {
int hash = clientIp.hashCode();
int serverIndex = Math.abs(hash) % servers.size();
return servers.get(serverIndex);
}
public static void main(String[] args) {
List servers = List.of("Server1", "Server2", "Server3");
IPHash ipHash = new IPHash(servers);
List clientIps = List.of("192.168.0.1", "192.168.0.2", "192.168.0.3");
for (String ip : clientIps) {
System.out.println(ip + " is mapped to " + ipHash.getNextServer(ip));
}
}
}
```
## /implementations/java/load_balancing_algorithms/LeastConnections.java
```java path="/implementations/java/load_balancing_algorithms/LeastConnections.java"
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LeastConnections {
private Map serverConnections;
public LeastConnections(List servers) {
serverConnections = new HashMap<>();
for (String server : servers) {
serverConnections.put(server, 0);
}
}
public String getNextServer() {
return serverConnections.entrySet().stream()
.min(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.orElse(null);
}
public void releaseConnection(String server) {
serverConnections.computeIfPresent(server, (k, v) -> v > 0 ? v - 1 : 0);
}
public static void main(String[] args) {
List servers = List.of("Server1", "Server2", "Server3");
LeastConnections leastConnectionsLB = new LeastConnections(servers);
for (int i = 0; i < 6; i++) {
String server = leastConnectionsLB.getNextServer();
System.out.println(server);
leastConnectionsLB.releaseConnection(server);
}
}
}
```
## /implementations/java/load_balancing_algorithms/LeastResponseTime.java
```java path="/implementations/java/load_balancing_algorithms/LeastResponseTime.java"
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class LeastResponseTime {
private List servers;
private List responseTimes;
public LeastResponseTime(List servers) {
this.servers = servers;
this.responseTimes = new ArrayList<>(servers.size());
for (int i = 0; i < servers.size(); i++)
responseTimes.add(0.0);
}
public String getNextServer() {
double minResponseTime = responseTimes.get(0);
int minIndex = 0;
for (int i = 1; i < responseTimes.size(); i++) {
if (responseTimes.get(i) < minResponseTime) {
minResponseTime = responseTimes.get(i);
minIndex = i;
}
}
return servers.get(minIndex);
}
public void updateResponseTime(String server, double responseTime) {
int index = servers.indexOf(server);
responseTimes.set(index, responseTime);
}
public static double simulateResponseTime(String server) {
// Simulating response time with random delay
Random random = new Random();
double delay = 0.1 + (1.0 - 0.1) * random.nextDouble();
try {
Thread.sleep((long) (delay * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
return delay;
}
public static void main(String[] args) {
List servers = List.of("Server1", "Server2", "Server3");
LeastResponseTime leastResponseTimeLB = new LeastResponseTime(servers);
for (int i = 0; i < 6; i++) {
String server = leastResponseTimeLB.getNextServer();
System.out.println("Request " + (i + 1) + " -> " + server);
double responseTime = simulateResponseTime(server);
leastResponseTimeLB.updateResponseTime(server, responseTime);
System.out.println("Response Time: " + String.format("%.2f", responseTime) + "s");
}
}
}
```
## /implementations/java/load_balancing_algorithms/RoundRobin.java
```java path="/implementations/java/load_balancing_algorithms/RoundRobin.java"
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class RoundRobin {
private List servers;
private AtomicInteger index;
public RoundRobin(List servers) {
this.servers = servers;
this.index = new AtomicInteger(-1);
}
public String getNextServer() {
int currentIndex = index.incrementAndGet() % servers.size();
return servers.get(currentIndex);
}
public static void main(String[] args) {
List servers = List.of("Server1", "Server2", "Server3");
RoundRobin roundRobinLB = new RoundRobin(servers);
for (int i = 0; i < 6; i++) {
System.out.println(roundRobinLB.getNextServer());
}
}
}
```
## /implementations/java/load_balancing_algorithms/WeightedRoundRobin.java
```java path="/implementations/java/load_balancing_algorithms/WeightedRoundRobin.java"
import java.util.List;
public class WeightedRoundRobin {
private List servers;
private List weights;
private int currentIndex;
private int currentWeight;
public WeightedRoundRobin(List servers, List weights) {
this.servers = servers;
this.weights = weights;
this.currentIndex = -1;
this.currentWeight = 0;
}
public String getNextServer() {
while (true) {
currentIndex = (currentIndex + 1) % servers.size();
if (currentIndex == 0) {
currentWeight--;
if (currentWeight <= 0) {
currentWeight = getMaxWeight();
}
}
if (weights.get(currentIndex) >= currentWeight) {
return servers.get(currentIndex);
}
}
}
private int getMaxWeight() {
return weights.stream().max(Integer::compare).orElse(0);
}
public static void main(String[] args) {
List servers = List.of("Server1", "Server2", "Server3");
List weights = List.of(5, 1, 1);
WeightedRoundRobin weightedRoundRobinLB = new WeightedRoundRobin(servers, weights);
for (int i = 0; i < 7; i++) {
System.out.println(weightedRoundRobinLB.getNextServer());
}
}
}
```
## /implementations/java/rate_limiting/FixedWindowCounter.java
```java path="/implementations/java/rate_limiting/FixedWindowCounter.java"
package implementations.java.rate_limiting;
import java.time.Instant;
public class FixedWindowCounter {
private final long windowSizeInSeconds; // Size of each window in seconds
private final long maxRequestsPerWindow; // Maximum number of requests allowed per window
private long currentWindowStart; // Start time of the current window
private long requestCount; // Number of requests in the current window
public FixedWindowCounter(long windowSizeInSeconds, long maxRequestsPerWindow) {
this.windowSizeInSeconds = windowSizeInSeconds;
this.maxRequestsPerWindow = maxRequestsPerWindow;
this.currentWindowStart = Instant.now().getEpochSecond();
this.requestCount = 0;
}
public synchronized boolean allowRequest() {
long now = Instant.now().getEpochSecond();
// Check if we've moved to a new window
if (now - currentWindowStart >= windowSizeInSeconds) {
currentWindowStart = now; // Start a new window
requestCount = 0; // Reset the count for the new window
}
if (requestCount < maxRequestsPerWindow) {
requestCount++; // Increment the count for this window
return true; // Allow the request
}
return false; // We've exceeded the limit for this window, deny the request
}
}
```
## /implementations/java/rate_limiting/LeakyBucket.java
```java path="/implementations/java/rate_limiting/LeakyBucket.java"
package implementations.java.rate_limiting;
import java.time.Instant;
import java.util.LinkedList;
import java.util.Queue;
public class LeakyBucket {
private final long capacity; // Maximum number of requests the bucket can hold
private final double leakRate; // Rate at which requests leak out of the bucket (requests per second)
private final Queue bucket; // Queue to hold timestamps of requests
private Instant lastLeakTimestamp; // Last time we leaked from the bucket
public LeakyBucket(long capacity, double leakRate) {
this.capacity = capacity;
this.leakRate = leakRate;
this.bucket = new LinkedList<>();
this.lastLeakTimestamp = Instant.now();
}
public synchronized boolean allowRequest() {
leak(); // First, leak out any requests based on elapsed time
if (bucket.size() < capacity) {
bucket.offer(Instant.now()); // Add the new request to the bucket
return true; // Allow the request
}
return false; // Bucket is full, deny the request
}
private void leak() {
Instant now = Instant.now();
long elapsedMillis = now.toEpochMilli() - lastLeakTimestamp.toEpochMilli();
int leakedItems = (int) (elapsedMillis * leakRate / 1000.0); // Calculate how many items should have leaked
// Remove the leaked items from the bucket
for (int i = 0; i < leakedItems && !bucket.isEmpty(); i++) {
bucket.poll();
}
lastLeakTimestamp = now;
}
}
```
## /implementations/java/rate_limiting/SlidingWindowCounter.java
```java path="/implementations/java/rate_limiting/SlidingWindowCounter.java"
package implementations.java.rate_limiting;
import java.time.Instant;
public class SlidingWindowCounter {
private final long windowSizeInSeconds; // Size of the sliding window in seconds
private final long maxRequestsPerWindow; // Maximum number of requests allowed in the window
private long currentWindowStart; // Start time of the current window
private long previousWindowCount; // Number of requests in the previous window
private long currentWindowCount; // Number of requests in the current window
public SlidingWindowCounter(long windowSizeInSeconds, long maxRequestsPerWindow) {
this.windowSizeInSeconds = windowSizeInSeconds;
this.maxRequestsPerWindow = maxRequestsPerWindow;
this.currentWindowStart = Instant.now().getEpochSecond();
this.previousWindowCount = 0;
this.currentWindowCount = 0;
}
public synchronized boolean allowRequest() {
long now = Instant.now().getEpochSecond();
long timePassedInWindow = now - currentWindowStart;
// Check if we've moved to a new window
if (timePassedInWindow >= windowSizeInSeconds) {
previousWindowCount = currentWindowCount;
currentWindowCount = 0;
currentWindowStart = now;
timePassedInWindow = 0;
}
// Calculate the weighted count of requests
double weightedCount = previousWindowCount * ((windowSizeInSeconds - timePassedInWindow) / (double) windowSizeInSeconds)
+ currentWindowCount;
if (weightedCount < maxRequestsPerWindow) {
currentWindowCount++; // Increment the count for this window
return true; // Allow the request
}
return false; // We've exceeded the limit, deny the request
}
}
```
## /implementations/java/rate_limiting/SlidingWindowLog.java
```java path="/implementations/java/rate_limiting/SlidingWindowLog.java"
package implementations.java.rate_limiting;
import java.time.Instant;
import java.util.LinkedList;
import java.util.Queue;
public class SlidingWindowLog {
private final long windowSizeInSeconds; // Size of the sliding window in seconds
private final long maxRequestsPerWindow; // Maximum number of requests allowed in the window
private final Queue requestLog; // Log of request timestamps
public SlidingWindowLog(long windowSizeInSeconds, long maxRequestsPerWindow) {
this.windowSizeInSeconds = windowSizeInSeconds;
this.maxRequestsPerWindow = maxRequestsPerWindow;
this.requestLog = new LinkedList<>();
}
public synchronized boolean allowRequest() {
long now = Instant.now().getEpochSecond();
long windowStart = now - windowSizeInSeconds;
// Remove timestamps that are outside of the current window
while (!requestLog.isEmpty() && requestLog.peek() <= windowStart) {
requestLog.poll();
}
if (requestLog.size() < maxRequestsPerWindow) {
requestLog.offer(now); // Log this request
return true; // Allow the request
}
return false; // We've exceeded the limit for this window, deny the request
}
}
```
## /implementations/java/rate_limiting/TokenBucket.java
```java path="/implementations/java/rate_limiting/TokenBucket.java"
package implementations.java.rate_limiting;
import java.time.Instant;
public class TokenBucket {
private final long capacity; // Maximum number of tokens the bucket can hold
private final double fillRate; // Rate at which tokens are added to the bucket (tokens per second)
private double tokens; // Current number of tokens in the bucket
private Instant lastRefillTimestamp; // Last time we refilled the bucket
public TokenBucket(long capacity, double fillRate) {
this.capacity = capacity;
this.fillRate = fillRate;
this.tokens = capacity; // Start with a full bucket
this.lastRefillTimestamp = Instant.now();
}
public synchronized boolean allowRequest(int tokens) {
refill(); // First, add any new tokens based on elapsed time
if (this.tokens < tokens) {
return false; // Not enough tokens, deny the request
}
this.tokens -= tokens; // Consume the tokens
return true; // Allow the request
}
private void refill() {
Instant now = Instant.now();
// Calculate how many tokens to add based on the time elapsed
double tokensToAdd = (now.toEpochMilli() - lastRefillTimestamp.toEpochMilli()) * fillRate / 1000.0;
this.tokens = Math.min(capacity, this.tokens + tokensToAdd); // Add tokens, but don't exceed capacity
this.lastRefillTimestamp = now;
}
}
```
## /implementations/python/consistent_hashing/consistent-hashing.py
```py path="/implementations/python/consistent_hashing/consistent-hashing.py"
import hashlib
import bisect
class ConsistentHashing:
def __init__(self, servers, num_replicas=3):
"""
Initializes the consistent hashing ring.
- servers: List of initial server names (e.g., ["S0", "S1", "S2"])
- num_replicas: Number of virtual nodes per server for better load balancing
"""
self.num_replicas = num_replicas # Number of virtual nodes per server
self.ring = {} # Hash ring storing virtual node mappings
self.sorted_keys = [] # Sorted list of hash values (positions) on the ring
self.servers = set() # Set of physical servers (used for tracking)
# Add each server to the hash ring
for server in servers:
self.add_server(server)
def _hash(self, key):
"""Computes a hash value for a given key using MD5."""
return int(hashlib.md5(key.encode()).hexdigest(), 16)
def add_server(self, server):
"""
Adds a server to the hash ring along with its virtual nodes.
- Each virtual node is a different hash of the server ID to distribute load.
- The server is hashed multiple times and placed at different positions.
"""
self.servers.add(server)
for i in range(self.num_replicas): # Creating multiple virtual nodes
hash_val = self._hash(f"{server}-{i}") # Unique hash for each virtual node
self.ring[hash_val] = server # Map hash to the server
bisect.insort(self.sorted_keys, hash_val) # Maintain a sorted list for efficient lookup
def remove_server(self, server):
"""
Removes a server and all its virtual nodes from the hash ring.
"""
if server in self.servers:
self.servers.remove(server)
for i in range(self.num_replicas):
hash_val = self._hash(f"{server}-{i}") # Remove each virtual node's hash
self.ring.pop(hash_val, None) # Delete from hash ring
self.sorted_keys.remove(hash_val) # Remove from sorted key list
def get_server(self, key):
"""
Finds the closest server for a given key.
- Hash the key to get its position on the ring.
- Move clockwise to find the nearest server.
- If it exceeds the last node, wrap around to the first node.
"""
if not self.ring:
return None # No servers available
hash_val = self._hash(key) # Hash the key
index = bisect.bisect(self.sorted_keys, hash_val) % len(self.sorted_keys) # Locate nearest server
return self.ring[self.sorted_keys[index]] # Return the assigned server
# ----------------- Usage Example -------------------
# Step 1: Initialize Consistent Hashing with servers
servers = ["S0", "S1", "S2", "S3", "S4", "S5"]
ch = ConsistentHashing(servers)
# Step 2: Assign requests (keys) to servers
print(ch.get_server("UserA")) # Maps UserA to a server
print(ch.get_server("UserB")) # Maps UserB to a server
# Step 3: Add a new server dynamically
ch.add_server("S6")
print(ch.get_server("UserA")) # Might be reassigned if affected
# Step 4: Remove a server dynamically
ch.remove_server("S2")
print(ch.get_server("UserB")) # Might be reassigned if affected
```
## /implementations/python/load_balancing_algorithms/ip_hash.py
```py path="/implementations/python/load_balancing_algorithms/ip_hash.py"
import hashlib
class IPHash():
def __init__(self, servers):
self.servers = servers
def get_next_server(self, client_ip):
hash_value = hashlib.md5(client_ip.encode()).hexdigest()
index = int(hash_value, 16) % len(self.servers)
return self.servers[index]
# Example usage
servers = ["Server1", "Server2", "Server3"]
load_balancer = IPHash(servers)
client_ips = ["192.168.0.1", "192.168.0.2", "192.168.0.3", "192.168.0.4"]
for ip in client_ips:
server = load_balancer.get_next_server(ip)
print(f"Client {ip} -> {server}")
```
## /implementations/python/load_balancing_algorithms/least_connections.py
```py path="/implementations/python/load_balancing_algorithms/least_connections.py"
import random
class LeastConnections:
def __init__(self, servers):
self.servers = {server: 0 for server in servers}
def get_next_server(self):
# Find the minimum number of connections
min_connections = min(self.servers.values())
# Get all servers with the minimum number of connections
least_loaded_servers = [server for server, connections in self.servers.items() if connections == min_connections]
# Select a random server from the least loaded servers
selected_server = random.choice(least_loaded_servers)
self.servers[selected_server] += 1
return selected_server
def release_connection(self, server):
if self.servers[server] > 0:
self.servers[server] -= 1
# Example usage
servers = ["Server1", "Server2", "Server3"]
load_balancer = LeastConnections(servers)
for i in range(6):
server = load_balancer.get_next_server()
print(f"Request {i + 1} -> {server}")
load_balancer.release_connection(server)
```
## /implementations/python/load_balancing_algorithms/least_response_time.py
```py path="/implementations/python/load_balancing_algorithms/least_response_time.py"
import time
import random
class LeastResponseTime:
def __init__(self, servers):
self.servers = servers
self.response_times = [0] * len(servers)
def get_next_server(self):
min_response_time = min(self.response_times)
min_index = self.response_times.index(min_response_time)
return self.servers[min_index]
def update_response_time(self, server, response_time):
index = self.servers.index(server)
self.response_times[index] = response_time
# Simulated server response time function
def simulate_response_time():
# Simulating response time with random delay
delay = random.uniform(0.1, 1.0)
time.sleep(delay)
return delay
# Example usage
servers = ["Server1", "Server2", "Server3"]
load_balancer = LeastResponseTime(servers)
for i in range(6):
server = load_balancer.get_next_server()
print(f"Request {i + 1} -> {server}")
response_time = simulate_response_time()
load_balancer.update_response_time(server, response_time)
print(f"Response Time: {response_time:.2f}s")
```
## /implementations/python/load_balancing_algorithms/round_robin.py.py
```py path="/implementations/python/load_balancing_algorithms/round_robin.py.py"
class RoundRobin:
def __init__(self, servers):
self.servers = servers
self.current_index = -1
def get_next_server(self):
self.current_index = (self.current_index + 1) % len(self.servers)
return self.servers[self.current_index]
# Example usage
servers = ["Server1", "Server2", "Server3"]
load_balancer = RoundRobin(servers)
for i in range(6):
server = load_balancer.get_next_server()
print(f"Request {i + 1} -> {server}")
```
## /implementations/python/load_balancing_algorithms/weighted_round_robin.py
```py path="/implementations/python/load_balancing_algorithms/weighted_round_robin.py"
class WeightedRoundRobin:
def __init__(self, servers, weights):
self.servers = servers
self.weights = weights
self.current_index = -1
self.current_weight = 0
def get_next_server(self):
while True:
self.current_index = (self.current_index + 1) % len(self.servers)
if self.current_index == 0:
self.current_weight -= 1
if self.current_weight <= 0:
self.current_weight = max(self.weights)
if self.weights[self.current_index] >= self.current_weight:
return self.servers[self.current_index]
# Example usage
servers = ["Server1", "Server2", "Server3"]
weights = [5, 1, 1]
load_balancer = WeightedRoundRobin(servers, weights)
for i in range(7):
server = load_balancer.get_next_server()
print(f"Request {i + 1} -> {server}")
```
## /implementations/python/rate_limiting/fixed_window_counter.py
```py path="/implementations/python/rate_limiting/fixed_window_counter.py"
import time
class FixedWindowCounter:
def __init__(self, window_size, max_requests):
self.window_size = window_size # Size of the window in seconds
self.max_requests = max_requests # Maximum number of requests per window
self.current_window = time.time() // window_size
self.request_count = 0
def allow_request(self):
current_time = time.time()
window = current_time // self.window_size
# If we've moved to a new window, reset the counter
if window != self.current_window:
self.current_window = window
self.request_count = 0
# Check if we're still within the limit for this window
if self.request_count < self.max_requests:
self.request_count += 1
return True
return False
# Usage example
limiter = FixedWindowCounter(window_size=60, max_requests=5) # 5 requests per minute
for _ in range(10):
print(limiter.allow_request()) # Will print True for the first 5 requests, then False
time.sleep(0.1) # Wait a bit between requests
time.sleep(60) # Wait for the window to reset
print(limiter.allow_request()) # True
```
## /implementations/python/rate_limiting/leaky_bucket.py
```py path="/implementations/python/rate_limiting/leaky_bucket.py"
from collections import deque
import time
class LeakyBucket:
def __init__(self, capacity, leak_rate):
self.capacity = capacity # Maximum number of requests in the bucket
self.leak_rate = leak_rate # Rate at which requests leak (requests/second)
self.bucket = deque() # Queue to hold request timestamps
self.last_leak = time.time() # Last time we leaked from the bucket
def allow_request(self):
now = time.time()
# Simulate leaking from the bucket
leak_time = now - self.last_leak
leaked = int(leak_time * self.leak_rate)
if leaked > 0:
# Remove the leaked requests from the bucket
for _ in range(min(leaked, len(self.bucket))):
self.bucket.popleft()
self.last_leak = now
# Check if there's capacity and add the new request
if len(self.bucket) < self.capacity:
self.bucket.append(now)
return True
return False
# Usage example
limiter = LeakyBucket(capacity=5, leak_rate=1) # 5 requests, leak 1 per second
for _ in range(10):
print(limiter.allow_request()) # Will print True for the first 5 requests, then False
time.sleep(0.1) # Wait a bit between requests
time.sleep(1) # Wait for bucket to leak
print(limiter.allow_request()) # True
```
## /implementations/python/rate_limiting/sliding_window_counter.py
```py path="/implementations/python/rate_limiting/sliding_window_counter.py"
import time
class SlidingWindowCounter:
def __init__(self, window_size, max_requests):
self.window_size = window_size # Size of the sliding window in seconds
self.max_requests = max_requests # Maximum number of requests per window
self.current_window = time.time() // window_size
self.request_count = 0
self.previous_count = 0
def allow_request(self):
now = time.time()
window = now // self.window_size
# If we've moved to a new window, update the counts
if window != self.current_window:
self.previous_count = self.request_count
self.request_count = 0
self.current_window = window
# Calculate the weighted request count
window_elapsed = (now % self.window_size) / self.window_size
threshold = self.previous_count * (1 - window_elapsed) + self.request_count
# Check if we're within the limit
if threshold < self.max_requests:
self.request_count += 1
return True
return False
# Usage example
limiter = SlidingWindowCounter(window_size=60, max_requests=5) # 5 requests per minute
for _ in range(10):
print(limiter.allow_request()) # Will print True for the first 5 requests, then gradually become False
time.sleep(0.1) # Wait a bit between requests
time.sleep(30) # Wait for half the window to pass
print(limiter.allow_request()) # Might be True or False depending on the exact timing
```
## /implementations/python/rate_limiting/sliding_window_log.py
```py path="/implementations/python/rate_limiting/sliding_window_log.py"
import time
from collections import deque
class SlidingWindowLog:
def __init__(self, window_size, max_requests):
self.window_size = window_size # Size of the sliding window in seconds
self.max_requests = max_requests # Maximum number of requests per window
self.request_log = deque() # Log to keep track of request timestamps
def allow_request(self):
now = time.time()
# Remove timestamps that are outside the current window
while self.request_log and now - self.request_log[0] >= self.window_size:
self.request_log.popleft()
# Check if we're still within the limit
if len(self.request_log) < self.max_requests:
self.request_log.append(now)
return True
return False
# Usage example
limiter = SlidingWindowLog(window_size=60, max_requests=5) # 5 requests per minute
for _ in range(10):
print(limiter.allow_request()) # Will print True for the first 5 requests, then False
time.sleep(0.1) # Wait a bit between requests
time.sleep(60) # Wait for the window to slide
print(limiter.allow_request()) # True
```
## /implementations/python/rate_limiting/token_bucket.py
```py path="/implementations/python/rate_limiting/token_bucket.py"
import time
class TokenBucket:
def __init__(self, capacity, fill_rate):
self.capacity = capacity # Maximum number of tokens the bucket can hold
self.fill_rate = fill_rate # Rate at which tokens are added (tokens/second)
self.tokens = capacity # Current token count, start with a full bucket
self.last_time = time.time() # Last time we checked the token count
def allow_request(self, tokens=1):
now = time.time()
# Calculate how many tokens have been added since the last check
time_passed = now - self.last_time
self.tokens = min(self.capacity, self.tokens + time_passed * self.fill_rate)
self.last_time = now
# Check if we have enough tokens for this request
if self.tokens >= tokens:
self.tokens -= tokens
return True
return False
# Usage example
limiter = TokenBucket(capacity=10, fill_rate=1) # 10 tokens, refill 1 token per second
for _ in range(15):
print(limiter.allow_request()) # Will print True for the first 10 requests, then False
time.sleep(0.1) # Wait a bit between requests
time.sleep(5) # Wait for bucket to refill
print(limiter.allow_request()) # True
```
The better and more specific the context, the better the LLM can follow instructions. If the context seems verbose, the user can refine the filter using uithub. Thank you for using https://uithub.com - Perfect LLM context for any GitHub repo.