Think Like Cave Architect
Ugh. Week 9 to Week 12 now. No more small tool โ now design whole cave-system. URL Shortener, Rate Limiter, Chat App, News Feed, Database choice, Sharding, Replication. Then take real AgentOS and make it stronger โ proof-of-strength for interview fire.
Design: URL Shortener
Turn long ugly link into short cave-mark, like bit.ly/xk9F2. Classic first design-hunt โ small enough to finish, big enough teach real lesson.
Core Requirement
- Given long URL, return short code (e.g. 7 char).
- Given short code, redirect to original long URL fast.
- High read : write ratio (~100:1) โ many click, few create.
Key Design Decision
- Encoding: Base62 (a-z, A-Z, 0-9) of auto-increment ID, or random-generate + collision check.
- Storage: Key-Value store (Redis/DynamoDB) โ short-code โ long-URL mapping.
- Cache: Cache hot short-codes in Redis, most click hit small % of link (80/20 rule).
// Base62 encode โ turn auto-increment ID into short code const CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; function encode(id) { let code = ''; while (id > 0) { code = CHARS[id % 62] + code; id = Math.floor(id / 62); } return code.padStart(7, 'a'); } encode(125); // e.g. "aaaaaab" style short code
Design: Rate Limiter
Too many hunter attack cave gate at once โ rate limiter stop after X request per time-window, protect cave from overload or abuse.
โถ Live Hunt: Token Bucket Algorithm
Common Algorithm
- Token Bucket: bucket refill at fixed rate, request consume token, allow burst up to bucket size.
- Fixed Window: count request per fixed time-block (e.g. per minute), simple but allow edge-burst.
- Sliding Window Log: track exact timestamp of each request, accurate but more memory.
Where Store Counter
Redis (with TTL / atomic INCR) common choice โ fast, shared across multiple app server instance. Local in-memory counter only work for single-server, not distributed system.
Design: Chat App
Two hunter talk across far cave, message must arrive fast, in order, even if hunter offline for while.
Core Requirement
- Real-time message delivery (low latency).
- Message persist โ offline user get message when back online.
- Read receipt, typing indicator (nice-to-have).
- Support 1-on-1 and group chat.
Key Design Decision
- Connection: WebSocket for real-time push (not polling โ too slow, too wasteful).
- Fan-out: Message Queue between sender and multiple recipient (group chat).
- Storage: NoSQL (Cassandra-style) โ chat history is write-heavy, append-only, partition by conversation-id.
Design: News Feed
Hunter follow many other hunter, want see all their new stone-post in one scroll, newest first, without wait long.
Fan-out on Write vs Read
Fan-out on Write: when post created, immediately push to all follower's feed-cache. Fast read, but expensive if celebrity has million follower.
Fan-out on Read: feed built at request-time, pull latest post from everyone you follow. Slower read, but no wasted write for inactive user.
Hybrid Approach (Real World)
Most big platform mix both โ normal user get fan-out-on-write (fast), celebrity account use fan-out-on-read (avoid write-storm). This exact kind of trade-off talk is what SDE 2 interview want hear.
Message Queue (Kafka / RabbitMQ Concept)
Instead hunter hand stone direct to other hunter (must both free same moment), drop stone in shared basket. Other hunter pick up basket whenever ready. Decouple sender from receiver.
Why Use Queue
- Decoupling: producer and consumer don't need know each other, don't need be online same time.
- Buffering: absorb traffic spike, consumer process at own pace.
- Retry/reliability: failed message can requeue, not lost.
Kafka vs RabbitMQ (concept)
Kafka: log-based, message kept for replay, great for high-throughput event stream (analytics, activity log).
RabbitMQ: traditional message broker, message removed after ack, great for task-queue / job processing.
// Conceptual producer/consumer โ not tied to specific library // Producer side queue.publish('new_message_topic', { chatId, senderId, text }); // Consumer side (fan-out service) queue.subscribe('new_message_topic', async (event) => { const recipients = await getRecipients(event.chatId); for (const r of recipients) pushToClient(r, event); });
SQL vs NoSQL Choice
Two style of storage-cave. SQL โ strict shelf, every stone same shape, strong relationship rule. NoSQL โ flexible basket, stone can differ shape, trade strict-rule for speed/scale.
| Aspect | SQL (Relational) | NoSQL |
|---|---|---|
| Schema | Fixed, strict | Flexible, dynamic |
| Relationship | Strong (JOIN, FK) | Weak / denormalized |
| Scale style | Vertical mainly | Horizontal, built-in |
| Consistency | ACID (strong) | Often eventual |
| Good for | Transaction, complex query | High-volume, flexible data |
Sharding
One storage-cave too full, can't fit more stone. Split data across many smaller cave (shard), each hold only piece of whole.
โถ Live Hunt: Hash-Based Sharding
Sharding Strategy
- Hash-based: hash(key) % N shards. Even spread, but resharding painful (need consistent hashing to ease this).
- Range-based: shard by value range (e.g. user A-M, N-Z). Simple, but risk hot-shard if data skew.
Sharding Challenge
Cross-shard JOIN become hard/expensive. Resharding (adding new shard) need data migration. Choose shard-key carefully โ wrong choice cause "hot shard" bottleneck.
Replication
Keep copy of same cave-data in multiple place. If one cave collapse (server down), other copy still stand โ data survive.
Master-Replica (Primary-Secondary)
All WRITE go to Master. Master copy change to Replica(s). READ can spread across Replicas โ reduce load on Master, improve read-throughput.
Sync vs Async Replication
Synchronous: Master wait Replica confirm write before ack client. Strong consistency, slower write.
Asynchronous: Master ack immediately, Replica catch up later. Fast write, small risk of data-lag/loss on crash.
Take AgentOS from Project to Proof-of-Strength
This week not learn new tool โ this week PROVE tool already learned. Real interview love real project more than any tutorial-clone. AgentOS (Caretaker + Nexus-a2a) already strong seed โ now make it bloom.
Pick One Real Feature to Add
- Caretaker: improve ChromaDB search relevance (known weak spot) โ try re-ranking, hybrid search, or better embedding strategy.
- Nexus-a2a: add new agent-communication pattern, or a monitoring/observability hook for agent message flow.
- Add a small system-design element you just learned โ e.g. rate-limit Caretaker's API, or shard memory storage by agent-id.
README Must Include
- One-line pitch: what problem AgentOS solve.
- Architecture diagram โ Caretaker, Nexus-a2a, OS Core (planned), how they connect.
- Setup instruction (clean, tested, copy-paste-able).
- Design decision section โ "why I choose X over Y" (shows architect thinking).
// Example README skeleton structure ## AgentOS > Universal memory + agent-to-agent communication layer for AI agent system. ## Architecture [diagram: Caretaker (memory) <-> Nexus-a2a (comm) <-> OS Core (planned, Rust)] ## Why These Choice - ChromaDB for vector search: chosen for local-first, no external dependency - FastAPI for Nexus-a2a: async support fit agent-to-agent latency need ## Setup git clone ... && uv sync && uv run start