MUHAMMAD
FARI
MADYAN
[ Press ESC or Click to Skip ]

System Design Roadmap

1

Part 1: Fondasi Jaringan – Paket Data, TCP/UDP, TLS & REST

2

Part 2: Komponen Inti Skalabilitas – Load Balancers, CDN, Redis, API Gateway, Database & Kafka

3

Part 3: Pola & Konsep Terdistribusi – Teorema CAP, Consistent Hashing, Sharding & Saga

4

Part 4: Studi Kasus Interview Nyata – TinyURL, WhatsApp, Food Delivery & Notifikasi

Artikel ini tersedia dalam Bahasa Inggris

🇬🇧 Read in English
🇮🇩 Bahasa Indonesia📚 System Design Roadmap

System Design Roadmap Part 4: Studi Kasus Interview Nyata – TinyURL, WhatsApp, Food Delivery & Notifikasi

Taklukkan wawancara system design dengan arsitektur produksi menyeluruh: pemendek TinyURL, chat real-time skala WhatsApp, pesan antar makanan geospatial Zomato/Gojek, engine notifikasi terdistribusi, dan rate limiter Redis.

Muhammad Fari MadyanPenulis

12 menit baca

·

7 Oktober 2026


Pendahuluan: Ujian Nyata di Ruang Wawancara System Design

Pada Bagian 1 hingga 3, kita telah menguasai ilmunya: mekanisme jaringan, komponen fisik skalabilitas, dan pola arsitektur terdistribusi.

Sekarang tibalah pada seninya: Wawancara System Design (System Design Interview).

Dalam sesi 45 menit wawancara teknis di perusahaan teknologi tier-1 atau FAANG, Anda akan diberikan skenario yang sengaja dibuat ambigu:

"Rancanglah sistem chat seperti WhatsApp" atau "Rancang sistem pemesanan makanan seperti GoFood atau DoorDash."

Kandidat yang gagal biasanya langsung terburu-buru menggambar kotak-kotak di papan tulis. Sebaliknya, kandidat level senior yang sukses selalu mengikuti kerangka kerja (framework) yang terstruktur dan disiplin:

┌─────────────────────────────────────────────────────────────────────────────┐ │ KERANGKA KERJA 4 LANGKAH WAWANCARA SYSTEM DESIGN │ ├─────────────────────────────────────────────────────────────────────────────┤ │ Langkah 1 (05 mnt): Klarifikasi Kebutuhan (Fungsional, Non-Fungsional, Skala│ │ Langkah 2 (10 mnt): Desain Arsitektur Tingkat Tinggi (Kontrak API & Alur) │ │ Langkah 3 (20 mnt): Bedah Mendalam Bottleneck (Model Data, Scaling, Edge-Case│ │ Langkah 4 (05 mnt): Kesimpulan (Metrik, SPOF, Monitoring, Masa Depan Sistem)│ └─────────────────────────────────────────────────────────────────────────────┘

Di bagian pamungkas ini, kita akan menerapkan seluruh materi roadmap untuk merancang 5 sistem produksi nyata langkah demi langkah.


Kasus 1: Merancang Pemendek URL (Studi Kasus TinyURL)

Pemendek URL bertugas mengonversi URL panjang (https://example.com/products/deals/item-984218?ref=campaign) menjadi alias pendek (https://tiny.url/aZ9k2m).

┌─────────────────────────────────────────────────────────────────────────────┐ │ ARSITEKTUR SISTEM TINYURL │ └─────────────────────────────────────────────────────────────────────────────┘ [ Client ] ──POST /api/v1/urls──► [ Load Balancer ] │ ▼ [ URL Service ] / \ 1. Ambil Token ID / \ 2. Tulis ke Cache Unik Pra-Generate / \ ▼ ▼ [ Key Generation ] [ Redis Cache ] [ Service (KGS) ] (20% URL Terpopuler) │ ▼ [ PostgreSQL / DynamoDB ] (short_key PK -> original_url)

1. Estimasi Kapasitas & Kebutuhan

  • Trafik: 100 juta URL baru dibuat setiap bulan. Rasio Baca vs Tulis = $10:1$ (1 Miliar pembacaan per bulan).
  • Write RPS: $100\text{ Juta} / (30 \times 86.400\text{ detik}) \approx 40\text{ tulis/detik}$.
  • Read RPS: $\approx 400\text{ baca/detik}$ (puncak jam sibuk: ~2.000 RPS).
  • Penyimpanan: Selama 5 tahun = $100\text{ Juta} \times 12 \times 5 = 6\text{ Miliar baris data}$. Dengan $500\text{ byte/baris} \approx 3\text{ TB}$ (sangat mudah ditampung dalam satu klaster database terdistribusi).

2. Tantangan Inti: Menghasilkan Kunci Pendek Unik Bebas Tabrakan

Kunci pendek harus ringkas. Menggunakan alfabet Base62 ([a-zA-Z0-9]), panjang 7 karakter menghasilkan: $$62^7 \approx 3,52\text{ Triliun kombinasi unik}$$ Kapasitas ini lebih dari cukup untuk puluhan tahun ke depan!

Dua Pendekatan Pembuatan Kunci:

  1. Hash dari URL Asli (MD5 / SHA-256): Mengambil 7 karakter pertama dari MD5 sering memicu tabrakan hash (hash collision) jika dua user memendekkan URL yang sama atau terjadi pemotongan string.
  2. Key Generation Service (KGS) Mandiri (Praktik Standar Industri):
    • Service KGS terpisah menggunakan generator urutan ID terdistribusi (seperti Apache ZooKeeper atau Twitter Snowflake) untuk mencetak deretan angka integer 64-bit unik.
    • Worker mengambil alokasi 10.000 ID sekaligus ke memori lokal.
    • Angka integer dikonversi langsung ke string Base62.
    • Hasil: Dijamin 100% unik dalam kecepatan $O(1)$ tanpa koordinasi kueri database yang berat!

3. Pengalihan Browser: HTTP 301 vs. HTTP 302

Saat pengunjung membuka https://tiny.url/aZ9k2m:

  • HTTP 301 Moved Permanently: Browser menyimpan pengalihan secara permanen di cache lokal pengguna. Kunjungan berikutnya langsung menuju URL asli tanpa melewati server Anda lagi.
    • Kelebihan: Beban server sangat minim dan pengalihan sangat instan.
    • Kekurangan: Anda kehilangan kemampuan merekam metrik analitik klik dan tidak bisa mencabut URL secara instan.
  • HTTP 302 Found (Temporary Redirect): Browser selalu menghubungi server TinyURL terlebih dahulu pada setiap klik.
    • Kelebihan: Analitik klik (lokasi geografi, perangkat, waktu) tercatat 100% akurat.
    • Kekurangan: Menambah beban request ke server.
    • Saran Interview: Sampaikan trade-off ini secara lugas! Pilih 302 jika analitik klik adalah kebutuhan wajib bisnis, atau 301 jika efisiensi biaya infrastruktur adalah prioritas utama.

Kasus 2: Merancang Sistem Chat Real-Time (Studi Kasus WhatsApp)

WhatsApp melayani miliaran pengguna yang saling bertukar teks pesan terenkripsi, media, dan status online dengan latensi sub-detik.

┌─────────────────────────────────────────────────────────────────────────────┐ │ ENGINE CHAT REAL-TIME SKALA WHATSAPP │ └─────────────────────────────────────────────────────────────────────────────┘ [ Pengirim ] [ Penerima ] │ ▲ │ WebSocket │ WebSocket ▼ │ ┌───────────────────────────┐ ┌───────────────────────────┐ │ Chat Gateway Server 1 │ │ Chat Gateway Server 2 │ └─────────────┬─────────────┘ └─────────────▲─────────────┘ │ │ ▼ │ ┌───────────────────────────┐ ┌─────────────┴─────────────┐ │ Message Ingestion Engine │ ──► [ Kafka Topic ] ───► │ Push / Routing Engine │ └─────────────┬─────────────┘ └───────────────────────────┘ │ ▲ ▼ │ ┌───────────────────────────┐ ┌─────────────┴─────────────┐ │ Cassandra Message Store │ │ Registri Sesi User │ │ (Partition: chat_id) │ │ (Redis: user_id -> Host) │ └───────────────────────────┘ └───────────────────────────┘

1. Protokol Komunikasi: Mengapa WebSocket?

  • Polling HTTP atau Long Polling sangat boros daya baterai ponsel dan membebani server akibat overhead header HTTP berulang serta jabat tangan TCP baru.
  • WebSockets membuka satu koneksi TCP dua arah (bidirectional) yang persistent, sangat ringan, dan berlatensi ultra-rendah.

2. Alur Pengiriman Pesan & Semantik Centang

  1. Pengirim mengirim teks melalui koneksi WebSocket aktif ke Chat Gateway 1.
  2. Chat Gateway 1 memvalidasi token dan membalas Message Ack ke pengirim (menampilkan centang abu-abu satu: Terkirim ke Server).
  3. Pesan disimpan secara permanen di database Apache Cassandra (Wide-Column NoSQL).
    • Mengapa Cassandra? Pesan chat adalah data runtun waktu (time-series) yang selalu diurutkan berdasarkan chat_id dan timestamp. Mesin LSM-Tree Cassandra memberikan kecepatan tulis yang luar biasa dan penskalaan horizontal tanpa downtime.
  4. Sistem memeriksa cache sesi di Redis (user_id -> ip_server_gateway) untuk mencari di server mana penerima sedang online.
    • Jika Online: Pesan diteruskan ke Chat Gateway 2, yang langsung mendorongnya ke ponsel penerima via WebSocket (centang abu-abu dua: Diterima di Perangkat). Saat obrolan dibuka, event dibalas menjadi centang biru (Dibaca).
    • Jika Offline: Pesan dimasukkan ke antrean layanan Push Notification (Apple APNs / Google FCM).

3. Optimasi Status Kehadiran (Presence) & Obrolan Grup

  • Presence (Status Online/Offline): Client mengirim sinyal detak jantung (heartbeat ping) setiap 5 detik melalui WebSocket. Redis menyimpan status tersebut dengan TTL 15 detik (SET presence:user_42 "online" EX 15). Jika koneksi ponsel terputus dan heartbeat berhenti, kunci otomatis hangus dan status user beralih menjadi offline.
  • Grup Chat: Untuk grup dengan 500 anggota, menyalin pesan sebanyak 500 kali (naive fanout-on-write) akan membebani jaringan server. Solusinya, pesan hanya disimpan satu kali di partisi kotak surat grup di Cassandra. Gateway masing-masing anggota cukup menarik pesan tersebut berdasarkan pointer urutan grup.

Kasus 3: Merancang Aplikasi Pesan Antar Makanan (Zomato / Gojek / DoorDash)

Aplikasi pesan antar makanan memerlukan sinkronisasi posisi real-time antartiga pihak: Pelanggan, Restoran, dan Driver Pengemudi.

┌─────────────────────────────────────────────────────────────────────────────┐ │ ARSITEKTUR GEOSPATIAL PESAN ANTAR MAKANAN │ └─────────────────────────────────────────────────────────────────────────────┘ [ Aplikasi Driver ] ──Ping Lokasi (tiap 4 dtk)──► [ Location Ingest Service ] │ ▼ [ Redis Geospatial ] (GEOADD drivers:city lng lat id) │ [ Pelanggan ] ──Order Dibayar──► [ Order State Machine ] │ │ │ ▼ ▼ [ Driver Dispatch Matching Engine ] (GEORADIUS: Cari 10 driver radius 3km)

1. Indexing Geospatial: Menemukan Driver Terdekat Secara Real-Time

Kueri database relasional standar (WHERE lat BETWEEN x AND y) memerlukan pembacaan tabel yang sangat lambat untuk koordinat yang bergerak dinamis. Kita harus mempartisi ruang dua dimensi:

┌──────────────────────────────────────┬──────────────────────────────────────┐ │ Geohash (Base32) │ Google S2 / Uber H3 │ ├──────────────────────────────────────┼──────────────────────────────────────┤ │ • Membagi bumi menjadi sel kisi │ • Membagi bumi menjadi hierarki │ │ berbentuk persegi panjang. │ heksagon segi enam sama sisi (H3). │ │ • Sel bersebelahan memiliki awalan │ • Sel heksagonal memiliki jarak tepi │ │ string yang sama ("qqgu1", "qqgu2")│ yang sama ke seluruh tetangganya. │ │ • Sangat mudah disimpan di Redis. │ • Standar industri ride-hailing. │ └──────────────────────────────────────┴──────────────────────────────────────┘

Pilihan di Lingkungan Produksi: Gunakan struktur data Redis Geospatial (GEOADD, GEORADIUS, GEOSEARCH). Di balik layar, Redis mengonversi titik koordinat garis bujur dan lintang menjadi nilai integer Geohash 52-bit yang disimpan di dalam Sorted Set (ZSET), memungkinkan kueri radius driver berkecepatan $O(\log N + M)$ tuntas dalam waktu di bawah 2 milidetik!

2. Pipeline Penyerapan Lokasi Driver

  • 500.000 driver aktif mengirimkan koordinat GPS setiap 4 detik = 125.000 operasi tulis per detik.
  • Data ping masuk melalui koneksi UDP atau gRPC ke streaming cluster (Topik Kafka: driver-locations).
  • Worker Kafka Streams menyaring dan memperbarui koordinat terbaru ke Redis dengan TTL 30 detik.

3. State Machine Pesanan & Algoritma Dispatch

Status pesanan dikelola sebagai mesin status (Finite State Machine) yang ketat: $$\text{Dibuat} \longrightarrow \text{Dibayar} \longrightarrow \text{Diterima Restoran} \longrightarrow \text{Driver Ditugaskan} \longrightarrow \text{Diambil} \longrightarrow \text{Terkirim}$$

Algoritma Pencocokan Driver:

  1. Saat pihak resto mengonfirmasi makanan tinggal 10 menit lagi selesai dimasak, Matching Engine menjalankan kueri geospatial untuk mencari driver dalam radius 3 km.
  2. Calon driver diberi skor berdasarkan jarak, tingkat sisa baterai ponsel, riwayat penerimaan order, dan tipe kendaraan.
  3. Order ditawarkan ke driver berperingkat tertinggi dengan batas waktu terima 15 detik. Jika ditolak atau kedaluwarsa, mekanisme Distributed Lock (Redlock) melepas order tersebut dan menawarkannya ke kandidat kedua.

Kasus 4: Merancang Sistem Notifikasi Skala Masif

Platform skala besar mengirim miliaran notifikasi setiap hari melalui berbagai saluran (Push Notif Ponsel, SMS, Email, dan Inbox In-App).

┌─────────────────────────────────────────────────────────────────────────────┐ │ PIPELINE ENGINE NOTIFIKASI TERDISTRIBUSI │ └─────────────────────────────────────────────────────────────────────────────┘ [ Microservice Internal ] │ ▼ [ Gateway Notifikasi ] ──► Memvalidasi Kuota Limit & Preferensi User │ ▼ [ Topik Kafka Berprioritas ] ├── topic: notif-priority-high (Kode OTP, Keamanan Akun, Pembayaran) └── topic: notif-priority-low (Promo Diskon, Rangkuman Mingguan) │ ▼ [ Armada Worker / Engine Template ] ──► Merender HTML & Payload Push │ ┌─────────┼─────────┬─────────┐ ▼ ▼ ▼ ▼ [APNs] [FCM] [Twilio] [SendGrid] (iOS) (Android) (SMS) (Email)

1. Kebutuhan Kritis & Jaminan Keandalan

  • Pesan kritis tidak boleh hilang: Kode verifikasi OTP wajib sampai di ponsel user dalam waktu kurang dari 5 detik.
  • Preferensi Pengguna: Pengguna berhak mematikan promosi SMS tanpa menonaktifkan email notifikasi transaksi.
  • Deduplikasi Pesan: Jangan pernah membombardir user dengan notifikasi ganda akibat jaringan yang putus-nyambung.

2. Manajemen Antrean Berprioritas dengan Kafka

Jangan mencampuradukkan pesan transaksi dan pesan promosi di dalam antrean yang sama:

  • Topik Prioritas Tinggi: Kode OTP, reset sandi, notifikasi debet rekening. Alokasikan worker dalam jumlah besar dengan toleransi antrean nol.
  • Topik Prioritas Rendah: Kampanye marketing berkala. Worker memproses pesan secara bertahap saat jam sepi trafik.

3. Jendela Deduplikasi & Rate Limiting Per-User

  • Rate limiter membatasi pesan promosi maksimal 3 kali per jam untuk setiap akun user.
  • Deduplication Window: Setiap notifikasi dihitung nilai hash identitasnya dari (user_id, channel, event_type, date_hour). Nilai hash disimpan di Redis dengan EXPIRE 1 jam. Jika ada pesan masuk dengan hash yang sama persis dalam rentang tersebut, sistem langsung membuangnya secara otomatis.

4. Penanganan Kegagalan Vendor Eksternal & Dead Letter Queue (DLQ)

Penyedia pihak ketiga (SendGrid, Twilio) sering mengalami gangguan jaringan (outage).

  • Bungkus pemanggilan API vendor dengan pola Circuit Breaker.
  • Jika Twilio gagal, alihkan rute pengiriman SMS secara otomatis ke vendor cadangan (misal MessageBird atau AWS SNS).
  • Jika semua percobaan ulang gagal setelah exponential backoff, lempar pesan tersebut ke Dead Letter Queue (DLQ) untuk dianalisis oleh tim engineer.

Kasus 5: Merancang Distributed Rate Limiter

API publik wajib menerapkan kuota batas (misalnya 100 request per menit per alamat IP atau API Key) guna menangkal serangan penyalahgunaan dan menjaga keadilan alokasi sumber daya server.

┌─────────────────────────────────────────────────────────────────────────────┐ │ ARSITEKTUR DISTRIBUTED RATE LIMITER DENGAN REDIS │ └─────────────────────────────────────────────────────────────────────────────┘ [ Request HTTP Masuk ] │ ▼ [ Lapisan Filter API Gateway ] │ ▼ [ Cache L1 Memori Lokal (Opsional) ] (Bypass cepat untuk IP internal terpercaya) │ ▼ [ Klaster Redis (Engine Skrip Lua Atomik) ] - Kunci: "rl:{tenant_id}:{menit_jendela}" - Algoritma: Sliding Window Counter │ ┌────────────────┴────────────────┐ ▼ ▼ [ Kuota Masih Ada ] [ Kuota Terlampaui ] Teruskan Request Tolak dengan HTTP 429 ke Microservice "Retry-After: 34"

1. Algoritma Sliding Window Counter di Redis

Sliding Window Counter menggabungkan perhitungan request dari jendela waktu sebelumnya dengan jendela waktu saat ini:

$$\text{Estimasi Hitungan} = \text{Hitungan Jendela Kini} + \left(\text{Hitungan Jendela Lalu} \times \left(1 - \frac{\text{Offset Waktu Kini}}{\text{Ukuran Jendela}}\right)\right)$$

Algoritma ini menghasilkan kalkulasi sub-milidetik, hemat memori ($<50\text{ byte per kunci}$), dan berhasil mengeliminasi lonjakan trafik di batas pergantian jendela waktu.

2. Standar Header Respons HTTP

Selalu informasikan sisa kuota ke aplikasi client melalui header standar HTTP RFC:

HTTP

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 28
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1775568000

{
  "error": "rate_limit_exceeded",
  "message": "Anda telah melampaui kuota 100 request per menit. Silakan coba kembali dalam 28 detik."
}

Matriks Pamungkas Wawancara System Design (FAANG Survival Matrix)

┌─────────────────────────────────────────────────────────────────────────────┐ │ MATRIKS JURUS ARSITEKTUR WAWANCARA TEKNIS │ ├──────────────────────┬──────────────────────────────────────────────────────┤ │ Karakteristik Beban │ Jurus Arsitektur yang Wajib Diajukan │ ├──────────────────────┼──────────────────────────────────────────────────────┤ │ Dominan Baca (Read) │ Redis Cache-Aside + PostgreSQL Read Replicas + CDN │ │ Dominan Tulis (Write)│ Ingesti Kafka + Cassandra / DynamoDB (LSM-Tree) │ │ Transaksi Finansial │ RDBMS Relasional + ACID + Saga Pattern + Outbox │ │ Latensi Real-Time │ WebSockets + Registri Sesi Redis + Sorted Set (ZSET) │ │ Pencarian Jarak Geografis │ Redis Geospatial / Uber H3 / Google S2 Hexagon │ │ Jaringan Tidak Stabil│ Header Idempotency-Key + Exponential Backoff & Jitter│ │ Ledakan Trafik Dadakan│ Rate Limiter API Gateway (Token Bucket) + Antrean Kafka│ └──────────────────────┴──────────────────────────────────────────────────────┘

Penutup: Perjalanan Menuju Penguasaan System Design

Selamat! Anda telah menuntaskan seluruh kurikulum System Design Roadmap:

  1. Part 1: Fondasi Jaringan membekali Anda dengan mekanisme protokol dasar (Paket Data, TCP, UDP, TLS 1.3, DNS, REST).
  2. Part 2: Komponen Inti Skalabilitas memberi Anda penguasaan komponen fisik (Load Balancer, CDN, Redis, API Gateway, SQL vs NoSQL, Kafka).
  3. Part 3: Pola & Konsep Terdistribusi membekali Anda dengan teori dan pola pertahanan bencana (Teorema CAP, Consistent Hashing, Sharding, Idempotensi, Outbox, Saga, CQRS).
  4. Part 4: Studi Kasus Interview Nyata menyatukan semuanya ke dalam desain arsitektur produksi untuk TinyURL, WhatsApp, Aplikasi Pesan Antar Makanan, Sistem Notifikasi, dan Rate Limiter.

System design bukanlah seni menghafal diagram yang kaku. System design adalah seni menimbang trade-off rekayasa sistem di bawah batasan sumber daya. Saat Anda melangkah ke ruang wawancara berikutnya, jangan mencari arsitektur yang "sempurna"—tunjukkan kepada pewawancara bagaimana Anda menavigasi latensi, biaya, konsistensi data, dan ketahanan sistem untuk menghasilkan arsitektur yang tepat.

Lanjut Membaca

Previous article thumbnail

← Artikel Sebelumnya

System Design Roadmap Part 3: Distributed Patterns & Concepts – CAP Theorem, Hashing, Sharding & Sagas

Artikel Selanjutnya →

Rebuilding Laravel E-Learning to Java Spring Boot & React: Enterprise Architecture & Cloud-Ready Migration

Next article thumbnail