Beranda / Kursus / Scalability for Beginners / I — Konsep Dasar
I — Konsep Dasar
Artikel 2 dari 9

Anatomi Sistem yang Scalable: Load Balancer, Caching, dan Connection Pooling

Komponen-komponen inti sebuah sistem yang scalable — load balancer, stateless application, caching layer, dan connection pooling — dibedah satu per satu sebelum masuk ke praktik.

10 Juli 2026

Di artikel sebelumnya, kita sudah paham kenapa aplikasi berhenti scale. Sekarang saatnya membedah apa saja komponen yang membentuk sistem yang scalable. Ibaratnya, sebelum masuk ke praktik menskalakan task-tracker-api, kita kenalan dulu dengan potongan-potongan puzzle-nya — supaya begitu masuk ke Bagian 3 dan seterusnya, istilah yang muncul tidak lagi asing.

Gambaran Besar: Dari Satu Instance ke Banyak Instance

Sistem sederhana yang belum scale biasanya terlihat seperti ini — satu client bicara langsung ke satu instance aplikasi, yang bicara langsung ke satu database:

Client ──► Aplikasi (1 instance) ──► Database (1 instance)

Sistem yang sudah scalable biasanya terlihat seperti ini — beberapa komponen baru masuk ke gambar:

                     ┌──► Aplikasi (instance 1) ──┐
Client ──► Load Balancer ──► Aplikasi (instance 2) ──┼──► Cache (Redis)
                     └──► Aplikasi (instance 3) ──┘        │
                                                            ▼
                                                        Database

Setiap kotak baru di diagram ini punya peran spesifik. Mari bahas satu per satu.

Load Balancer — Membagi Trafik ke Banyak Instance

Load balancer adalah komponen yang menerima semua request masuk, lalu mendistribusikannya ke salah satu dari beberapa instance aplikasi yang tersedia. Beberapa strategi distribusi yang umum:

  • Round-robin — bergiliran, instance 1 → 2 → 3 → 1 → 2 → 3 → dst. Sederhana dan jadi default di banyak load balancer (termasuk Nginx, yang akan kita pakai di Bagian 7).
  • Least connections — mengarahkan request ke instance yang sedang menangani paling sedikit koneksi aktif. Lebih adil kalau durasi tiap request bervariasi jauh.
  • Berbasis health check — load balancer rutin mengecek apakah tiap instance masih sehat (biasanya lewat endpoint /health), dan otomatis berhenti mengirim trafik ke instance yang tidak merespons.
  • Manfaat load balancer bukan cuma soal distribusi beban — dia juga yang membuat sistem tidak lagi punya single point of failure di lapisan aplikasi. Kalau satu instance mati, load balancer otomatis mengalihkan trafik ke instance lain yang masih hidup.

    Stateless vs Stateful — Kenapa Ini Krusial untuk Horizontal Scaling

    Ini konsep yang sering jadi jebakan pemula. Stateless artinya instance aplikasi tidak menyimpan data spesifik-user apa pun di memori antar request — setiap request diproses berdiri sendiri, semua data yang dibutuhkan (identitas user, data aplikasi) diambil dari luar instance itu sendiri (database, cache terpusat, atau dikirim ulang oleh client, misalnya lewat token).

    Kenapa ini penting untuk horizontal scaling? Karena load balancer bisa mengirim request pertama dari seorang user ke instance 1, lalu request berikutnya dari user yang sama ke instance 2 — round-robin tidak menjamin satu user selalu ke instance yang sama. Kalau instance aplikasi menyimpan state penting di memori lokal (misalnya session login disimpan di variabel Python biasa), request kedua yang mendarat di instance berbeda tidak akan menemukan state itu — user tiba-tiba "ter-logout" secara acak.

    task-tracker-api yang kita bangun sejak awal seri FastAPI sudah stateless dengan benar: setiap endpoint mengambil data dari database (dan nanti, cache) di setiap request, bukan menyimpannya di variabel Python yang hidup selama proses berjalan. Ini kenapa nanti di Bagian 7 kita bisa langsung menjalankan 3 instance sekaligus tanpa perlu mengubah logic aplikasi sama sekali.

    Caching Layer — Menyerap Beban Sebelum Sampai ke Database

    Cache adalah penyimpanan sementara yang jauh lebih cepat diakses dibanding sumber data aslinya (biasanya database), dipakai untuk menyimpan hasil yang sering diminta ulang. Alih-alih tiap request query ke database, request yang datanya sudah pernah diambil sebelumnya cukup dijawab dari cache.

    Redis adalah pilihan populer untuk ini — in-memory data store yang sangat cepat, dan (penting untuk horizontal scaling) bisa dibagi bersama oleh semua instance aplikasi. Ini bedanya dengan cache lokal di memori tiap instance: kalau instance 1 meng-cache sesuatu di memorinya sendiri, instance 2 dan 3 tidak akan tahu — mereka harus query ulang ke database. Dengan cache terpusat seperti Redis, begitu satu instance mengisi cache, SEMUA instance bisa langsung memanfaatkannya. Kita praktik ini di Bagian 4.

    Connection Pooling — Mengelola Koneksi Database yang Terbatas

    Setiap koneksi ke database itu tidak gratis — ada biaya membuka koneksi baru (TCP handshake, autentikasi), dan database punya batas jumlah koneksi simultan yang bisa ditangani. Kalau setiap request membuka koneksi baru dan menutupnya setelah selesai, di trafik tinggi ini jadi overhead besar dan gampang membentur batas koneksi database.

    Connection pool menyelesaikan ini dengan menyiapkan sejumlah koneksi di awal, lalu "meminjamkannya" ke request yang butuh, dan mengembalikannya ke pool setelah selesai — bukan menutup koneksinya. Ini persis yang sudah kita pakai secara implisit lewat SQLModel/SQLAlchemy di seri FastAPI (Depends(get_session)), dan akan kita atur eksplisit ukurannya di Bagian 5, karena ukuran pool yang salah — terlalu kecil atau terlalu besar — sama-sama bisa jadi bottleneck baru begitu ada banyak instance aplikasi yang berbagi satu database.

    Merangkai Semuanya

    Kelima konsep ini — load balancer, stateless application, shared cache, dan connection pooling — adalah potongan puzzle yang sama yang akan kita rakit satu per satu mulai Bagian 4. Urutannya sengaja disusun dari yang paling murah/simpel (caching, database tuning) ke yang paling kompleks (horizontal scaling dengan Docker), karena di dunia nyata begitu juga urutan yang paling masuk akal untuk dicoba — jangan langsung lompat ke arsitektur paling rumit kalau masalahnya sebenarnya bisa selesai dengan index database yang hilang.

    Rangkuman

  • Load balancer mendistribusikan trafik ke banyak instance aplikasi, sekaligus menghilangkan single point of failure di lapisan aplikasi.
  • Stateless — instance aplikasi tidak boleh menyimpan state penting di memori lokal, karena load balancer tidak menjamin satu user selalu ke instance yang sama.
  • Caching layer (Redis) menyerap beban baca sebelum sampai ke database, dan bisa dibagi bersama semua instance.
  • Connection pooling mengelola koneksi database yang terbatas secara efisien, mencegah overhead membuka-tutup koneksi berulang.
  • Topik

    ScalabilityFundamentals