Reference · System Design · Trade-off komponen

Trade-off komponen

Ringkasan satu halaman untuk dibaca ulang menjelang interview, diurutkan sesuai tangga skala (Lesson 0025) dan dirangkum dari bagian "Kapan tidak perlu" di setiap lesson komponen. Angka sinyal adalah titik awal yang masuk akal untuk interview, bukan aturan baku.

Prinsip: ukur dulu, lalu perubahan termurah. Naik satu anak tangga hanya kalau angka menuntut. Patokan: 1.000 DAU ≈ di bawah 1 QPS rata-rata, cukup satu server + satu database (0004).

Tangga skala: delapan anak tangga

KomponenKapan dipakai (sinyal)Kapan tidakAlternatif lebih murah / risiko
Ukur (golden signals, EXPLAIN)Selalu pertama: latency, traffic, errors, saturation; query plan untuk query lambat [1]Tidak pernah dilewatiHampir nol biaya
Index, perbaiki query/kode (0009)EXPLAIN menunjukkan scan seluruh tabel, query N+1, satu query mendominasi waktuKolom yang tidak pernah di-query; tabel yang sangat sering ditulisRisiko kecil: index menambah overhead saat menulis
Cache (0013)Baca:tulis tinggi (mis. 100:1), key sama dibaca berulang, p99/CPU database masih tinggi setelah index1.000 DAU; data yang tidak boleh basi (saldo, stok saat checkout); sebagian besar request missHeader Cache-Control untuk browser/CDN, local cache kecil. Risiko: cache-aside "doesn't guarantee consistency between the data store and the cache" [2]
Scale vertical (0005)CPU/memori di atas ±70% terus-menerus setelah query diperbaikiSudah di mesin terbesar yang wajar; masalahnya availability (tetap satu titik gagal)Satu perubahan konfigurasi, tanpa ubah kode; ada batas atas
Read replica (0009)Read-heavy (≥10:1), primary tetap jenuh oleh baca setelah index dan scale vertical; standby bisa melayani query read-only [3]Bottleneck-nya write: replica tidak membantu sama sekaliIndex, cache dulu. Risiko: replication lag (user tidak langsung melihat tulisannya; baca data sendiri dari leader)
Queue / asinkron (0016)Pekerjaan lambat (detik) atau pihak ketiga tidak stabil, hasilnya tidak ditunggu user; lonjakan melebihi kapasitas downstreamUser butuh jawabannya sekarang dan tujuan cepat; rata-rata beban (bukan hanya puncak) sudah melebihi consumer: queue tidak menambah kapasitasTabel job dengan SELECT … FOR UPDATE SKIP LOCKED untuk beberapa ratus job per menit [4]; queue terkelola sebelum cluster Kafka sendiri. Risiko: eventual, pesan ganda, butuh idempotency
Sharding (0010)Write melewati kapasitas satu leader setelah tuning dan scale vertical; data tidak muat di satu server terbesar yang wajarBeban baca saja (itu replica/cache); 1.000 DAUArsip data lama; partitioning di satu server, yang biasanya baru sepadan kalau "the size of the table should exceed the physical memory of the database server" [5]. Risiko: query lintas shard, resharding, hot partition; shard key hampir mustahil diganti
Microservices / pecah service (0024)Beberapa tim saling menunggu deploy; satu modul butuh sumber daya sangat berbeda (mis. CPU 10×) atau siklus rilis sendiriJumlah user saja: 1.000–100.000 DAU masih muat di beberapa server di belakang load balancerPertahankan modular monolith (batas modul dijaga); monolith stateless di belakang LB; worker lewat queue. Risiko: panggilan jaringan, saga, tracing per service

Komponen pendukung

KomponenKapan dipakai (sinyal)Kapan tidakAlternatif lebih murah
Horizontal scaling + load balancer (0006)App server jenuh sementara database longgar; target availability (99,9%) menuntut deploy tanpa downtimeSatu app server: LB hanya menambah satu hop; database yang jenuhScale up; DNS dengan beberapa record A, sederhana tapi kontrolnya sedikit [6]. Tetap tulis aplikasi stateless sejak awal
CDN, reverse proxy, API gateway (0007)User jauh dari origin (RTT puluhan–ratusan ms); bandwidth konten statis besar; banyak service dengan auth/rate limit berulangUser di satu kota; satu monolith (gateway hanya menambah hop); API personal yang tidak bisa di-cacheCache-Control yang benar, kompresi, nama file berversi
NoSQL tambahan (0008)Akses hanya per key pada volume yang melampaui satu relasional yang sudah di-tuning; data graph/time seriesButuh JOIN dan transaksi; 1.000 DAUPostgreSQL + kolom jsonb, yang mendukung index [7]
Datastore multi-node, quorum (0011)Write harus tetap diterima saat node/region putus, pada skala di atas satu leader + standbySatu region, 1.000 DAU: jawab "satu leader, konsisten"Satu leader + standby + read replica; read-your-writes dari leader
Invalidation eksplisit, eviction khusus (0014)Toleransi basi lebih pendek dari TTL yang masuk akal; hit ratio terukur rendahData yang boleh basi beberapa detik/menitTTL pendek; allkeys-lru sebagai default eviction [8]
Proteksi stampede, pecah hot key (0015)QPS satu key × waktu hitung ulang = banyak query serentak (5.000 QPS × 2 detik ≈ 10.000)10 QPS dengan hitung ulang 50 msJitter pada TTL; stale-while-revalidate atau proxy_cache_lock di proxy yang sudah ada
Exactly-once, DLQ, ordering ketat (0017)Duplikat berarti uang hilang dan efeknya sulit dibuat idempotent; urutan mengubah hasilMetrik atau presence yang boleh hilangAt-least-once + consumer idempotent; upsert per primary key; satu transaksi database
Event-driven, outbox (0018)Satu kejadian ditunggu beberapa layanan milik tim berbeda; ada database dan broker, kehilangan event = data tidak konsistenHanya satu penerima yang cepat dan stabil; semua efek di satu databasePanggilan langsung; satu transaksi; tabel job sebagai queue sekaligus outbox
WebSocket, streaming (0020)Data harus sampai dalam hitungan detik dan polling mendominasi beban1.000 user polling tiap 30 detik = ±33 request/detik, ringanREST + short polling; SSE untuk aliran satu arah
Rate limiter (0021)API terbuka; satu client memakai porsi besar (mis. 40% traffic); endpoint mahal per requestTool internal 50 karyawanlimit_req di nginx [9] atau throttling gateway; counter di memori kalau hanya satu server
Circuit breaker, bulkhead (0022)Satu dependency lambat menyeret p99 semua endpoint; pool koneksi habis saat insidenMonolith dengan satu database (kalau database mati, tidak ada yang diselamatkan)Timeout ketat (selalu perlu) + retry terbatas dengan jitter + batas connection pool
Distributed tracing, SLA (0023)Request melewati tiga service atau lebih dan kenaikan p99 tidak terjelaskan dari metrics dan logsMonolith dengan satu databaseLog terstruktur dengan request id + empat golden signals; satu atau dua SLO untuk endpoint terpenting

Kalimat untuk interview: "Untuk skala ini cukup X; kalau metrik Y melewati Z, langkah berikutnya W." Komponen tanpa angka = over-engineering.

[1] PostgreSQL docs: Using EXPLAIN · [2] Azure Architecture Center: Cache-Aside pattern · [3] PostgreSQL docs: Hot Standby · [4] PostgreSQL docs: SELECT (locking clause, SKIP LOCKED) · [5] PostgreSQL docs: Table Partitioning · [6] Google SRE Book, bab 19: Load Balancing at the Frontend · [7] PostgreSQL docs: JSON Types · [8] Redis docs: Key eviction · [9] nginx: Module ngx_http_limit_req_module

Cheat sheet lain: angka dan estimasi · kerangka 5 langkah · Indeks