System design adalah merancang bagian-bagian sebuah sistem (server, database, cache, antrean) dan cara mereka terhubung, supaya sistem itu memenuhi kebutuhannya pada skala tertentu. Bayangin kamu dipercaya mengurus katering nikahan. Sebelum masak, kamu tanya dulu: tamunya 500 atau 5.000? Datangnya bergantian atau serentak jam 11.00? Jawaban itu yang menentukan berapa kompor, berapa panci, dan berapa orang di dapur. Resepnya sama, skalanya yang beda. System design juga begitu: tanya kebutuhan, hitung angkanya, baru gambar kotak-kotaknya.
🧪 Tebakan cepat: TiketNada punya 1 juta pengguna aktif per hari, masing-masing rata-rata 20 request. Berapa request per detik rata-ratanya: sekitar 23, 231, atau 2.315? Tebak dulu, jawabannya ada di bagian "Estimasi: berapa request per detik".
Lima langkah merancang
- Requirements: apa yang harus dikerjakan sistem, dan seberapa baik.
- Estimasi: berapa request per detik, berapa data per tahun, berapa bandwidth.
- Desain high-level: kotak dan panah. Load balancer, server aplikasi, database, cache.
- Deep dive: bedah satu atau dua bagian yang paling kritis.
- Bottleneck dan trade-off: di mana sistem akan jebol duluan, dan apa yang kamu korbankan untuk mencegahnya.
Gak ada satu desain yang "benar". Yang ada desain yang cocok dengan kebutuhan dan angkanya, dengan trade-off yang kamu sebut terang-terangan.
Requirements TiketNada
Requirements dibagi dua. Functional requirements adalah apa yang dikerjakan sistem. Non-functional requirements adalah seberapa baik dia mengerjakannya.
| Functional | Non-functional |
|---|---|
| Pengguna melihat daftar dan detail konser | Halaman konser terbuka di bawah 500 ms untuk 95% request |
| Pengguna memesan maksimal 4 tiket per pesanan | Uptime 99,9% per bulan |
| Pengguna membayar pesanan | Pesanan yang sudah dibayar gak boleh hilang |
| E-tiket PDF dikirim ke email setelah bayar | Tetap jalan saat war tiket jam 10.00 |
Pemula biasanya cuma menulis kolom kiri. Padahal kolom kanan yang menentukan arsitekturnya: aplikasi yang sama untuk 100 orang dan untuk 1 juta orang bentuknya jauh berbeda.
Scalability, availability, reliability
Tiga kata ini sering tertukar:
- Scalability: sanggup menangani beban yang bertumbuh. Ada dua cara. Vertical scaling (scale up): mesinnya diganti yang lebih besar, CPU dan RAM lebih banyak. Horizontal scaling (scale out): tambah mesin. Vertical gampang tapi ada batasnya; horizontal hampir gak terbatas tapi butuh load balancer dan membawa masalah distributed system.
- Availability: berapa persen waktu sistem bisa dipakai. High availability artinya sistem tetap beroperasi walau ada komponen yang gagal, dengan downtime minimal. Caranya redundansi: dua server, failover otomatis, dan gak ada single point of failure (satu bagian yang kalau mati, semuanya ikut mati).
- Reliability: berfungsi dengan benar secara konsisten. Sistem bisa cepat dan scalable tapi tidak reliable, misalnya sering menjual kursi yang sama ke dua orang.
Availability ditulis dalam "jumlah sembilan":
| Target | Downtime per tahun | Downtime per bulan (30 hari) |
|---|---|---|
| 99% | 3,65 hari | 7,2 jam |
| 99,9% | 8,76 jam | 43,2 menit |
| 99,99% | 52,6 menit | 4,3 menit |
Janji availability ke pelanggan ditulis di SLA (Service Level Agreement): kontrak formal antara penyedia layanan dan pelanggan, lengkap dengan kompensasinya kalau dilanggar. Target internal tim disebut SLO (Service Level Objective), dan angka yang benar-benar diukur disebut SLI (Service Level Indicator). Biasanya SLO dibuat lebih ketat dari SLA supaya ada ruang aman.
Estimasi: berapa request per detik
Estimasi back-of-the-envelope adalah hitungan kasar di "balik amplop": angka bulat, cukup untuk tahu orde besarnya. Ukuran beban yang paling sering dipakai adalah QPS (queries per second), jumlah request per detik. Angka TiketNada (model contoh):
| Langkah | Hitungan | Hasil |
|---|---|---|
| Request per hari | 1.000.000 pengguna × 20 request | 20.000.000 |
| QPS rata-rata | 20.000.000 ÷ 86.400 detik | ≈ 231 |
| QPS jam sibuk | 231 × 3 | ≈ 694 |
| QPS war tiket | 231 × 50 | ≈ 11.574 |
Jadi jawaban tebakannya sekitar 231. Trik cepatnya: 1 hari = 86.400 detik, bulatkan jadi 100.000, maka 20.000.000 ÷ 100.000 = 200. Melenceng 14%, tapi orde besarnya sama, dan itu yang penting.
Lihat baris terakhir. Kalau satu server aplikasi kuat 500 QPS, hari biasa cukup 2 server, tapi war tiket butuh 11.574 ÷ 500 = 23,1, dibulatkan ke atas jadi 24 server. Rancang untuk puncaknya, bukan rata-ratanya.
Estimasi storage dan bandwidth
Misalkan 5% pengguna harian membeli: 50.000 pesanan per hari. Tiap pesanan menyimpan 1 KB data di database dan satu e-tiket PDF 100 KB. Tiap response ke browser rata-rata 20 KB. Di estimasi, 1 KB = 1.000 byte, 1 MB = 1.000 KB, dan 1 GB = 1.000 MB.
// Estimasi TiketNada (model contoh)
const dau = 1000000; // pengguna aktif per hari
const requestPerUser = 20;
const detikPerHari = 86400;
const qps = (dau * requestPerUser) / detikPerHari;
console.log("QPS rata-rata:", Math.round(qps)); // 231
const pesananPerHari = dau * 0.05; // 5% membeli
const kbPerPesanan = 1 + 100; // data 1 KB + e-tiket 100 KB
const gbPerTahun = (pesananPerHari * kbPerPesanan * 365) / 1000000;
console.log("Storage per tahun:", Math.round(gbPerTahun), "GB"); // 1843
const mbPerDetik = (qps * 20) / 1000; // response 20 KB
console.log("Bandwidth:", mbPerDetik.toFixed(1), "MB/s =", Math.round(mbPerDetik * 8), "Mbps"); // 4.6 MB/s = 37 Mbps
qpsadalah request per hari dibagi detik per hari: 231.gbPerTahun: 50.000 pesanan × 101 KB × 365 hari = 1.843.250.000 KB. Dibagi 1.000.000 (KB ke GB) jadi 1.843 GB, sekitar 1,8 TB per tahun.mbPerDetik: 231 request × 20 KB = 4.630 KB per detik, yaitu 4,6 MB/s. Kecepatan jaringan biasa ditulis dalam bit, dan 1 byte = 8 bit, jadi sekitar 37 Mbps.
Angka ini langsung memberi keputusan desain: database cuma menampung 18 GB per tahun (1 KB × 50.000 × 365), sisanya e-tiket. Jadi PDF disimpan di object storage, bukan di database.
🤔 Trade-off, bukan jawaban benar
Tiap pilihan membayar sesuatu. Tambah satu angka sembilan di availability berarti server cadangan, region kedua, dan biaya berlipat. Saat jaringan antarserver terputus, sistem harus memilih: tetap menjawab dengan data yang mungkin lama, atau menolak demi data yang pasti benar. TiketNada boleh menampilkan sisa kursi yang telat beberapa detik di halaman konser, tapi gak boleh menjual kursi yang sama dua kali. Pilihan ini dibahas di lesson CAP Theorem.
⚠️ Jebakan yang sering ketemu
- Langsung menggambar arsitektur. Tanpa requirements dan angka, semua keputusan cuma selera.
- Merancang untuk rata-rata. War tiket TiketNada 50 kali rata-ratanya. Server yang pas untuk 231 QPS tumbang di 11.574.
- Tertukar byte dan bit. MB/s (megabyte) dan Mbps (megabit) beda 8 kali.
- Over-engineering. Microservices dan sepuluh database untuk aplikasi 100 pengguna. Mulai sederhana, pecah saat angkanya menuntut.
TL;DR: System design adalah merancang komponen dan hubungannya supaya kebutuhan terpenuhi pada skala tertentu. Mulai dari requirements: functional (apa yang dikerjakan) dan non-functional (seberapa baik: latency, availability, durability). Scalability = sanggup menangani beban yang tumbuh (vertical: mesin lebih besar, horizontal: lebih banyak mesin). High availability = tetap jalan walau ada komponen gagal, lewat redundansi. Reliability = berfungsi benar secara konsisten. SLA = Service Level Agreement, janji availability ke pelanggan; 99,9% artinya maksimal 43,2 menit down per bulan. Lalu estimasi: QPS = request per hari ÷ 86.400 (TiketNada: 231, puncak war tiket 11.574), storage = data per hari × 365 (1,8 TB per tahun), bandwidth = QPS × ukuran response (4,6 MB/s). Rancang untuk puncaknya dan sebut trade-off-nya.