Belajar Site Reliability Engineer - Performance Engineering
Episode 15 of 28

Belajar Site Reliability Engineer - Performance Engineering

Membidik performa secara ilmiah: profiling untuk menemukan bottleneck nyata, strategi optimasi latency termasuk tail latency, dan load testing dengan k6 lengkap dengan threshold — dibuktikan dengan praktik optimasi latency sebelum-sesudah yang terukur

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah reliability-as-code di episode 14 mengunci pengukuran dan pemulihan, muncullah pertanyaan yang paling sering menggelisahkan tim produksi: kenapa lambat? SLO latensi sudah ditetapkan, alert sudah terpasang, tetapi permintaan tetap membengkak di p95. Menjawab dengan tebakan — "mungkin database-nya" — adalah taruhan yang mahal dan sulit dipertanggungjawabkan.

Performance engineering adalah pendekatan ilmiah: temukan bottleneck dengan data (profiling), optimasi bagian yang paling berdampak, lalu buktikan dengan load testing yang terukur. Episode 15 membawa kalian dari "rasa-rasa lambat" ke angka yang bisa dibela di depan tim.

Profiling: Menemukan Bottleneck dengan Data

Sebelum mengoptimasi, jawab satu pertanyaan: kode apa yang paling banyak menghabiskan CPU dan waktu? Jawabannya bukan opini, melainkan hasil sampling profiler — alat yang memotret stack trace program ribuan kali per detik dan mengagregasikannya.

Beberapa tool yang lazim:

  • Go: pprof bawaan runtime — go tool pprof.
  • Python: py-spy (sampling tanpa mengubah kode) atau cProfile.
  • Java: async-profiler untuk CPU & allocation.
  • Umum: perf di Linux untuk profiling sistem.
py-spy: profil proses produksi tanpa restart
py-spy record --pid 4821 -o flame.svg --duration 30

Hasilnya berupa flame graph: sumbu horizontal adalah proporsi waktu, sumbu vertikal adalah kedalaman call stack. Batang yang paling lebar di puncak adalah tersangka utama — dan biasanya jawabannya mengejutkan: bukan SQL query yang rumit, melainkan serialisasi JSON berulang atau logging yang sinkron.

Tip

Profil di lingkungan yang sedekat mungkin dengan produksi — throughput, ukuran data, dan konfigurasi yang sama. Profil di laptop dengan data dummy sering menunjukkan bottleneck yang tidak ada di produksi, dan sebaliknya.

Optimasi Latency: Jangan Optimasi Rata-rata

Latensi punya distribusi. Mean menutupi kenyataan: 99% request selesai dalam 50 ms, tetapi 1% memakan 3 detik — dan pengguna yang merasakan p99 adalah pengguna yang paling lama menunggu. Google dan Netflix menemukan bahwa tail latency (p99, p999) hampir selalu menentukan pengalaman nyata, terutama karena satu request melintasi banyak service.

Latency Budget: Alokasikan Sebelum Membangun

Ketika SLO latensi adalah 500 ms, bagilah menjadi budget per lapisan:

Latency budget endpoint /checkout
gateway        →  50 ms  (5%)
auth service   →  50 ms  (5%)
payment service → 300 ms (60%)
database       →  80 ms  (16%)
buffer         →  20 ms  (4%)

Kunci budget ini adalah menolak penambahan di luar batas. Begitu satu service melampaui jatahnya, seluruh endpoint terkena imbas. Budget mengubah pertanyaan dari "berapa cepat masing-masing?" menjadi "berapa yang tersisa untuk lapisan berikutnya?".

Klasifikasi Sumber Latensi

100%

Empat dari lima kategori di atas tidak bisa diselesaikan dengan "menambah cache" saja. Queueing dipecahkan dengan batching dan concurrency control, GC dengan tuning heap, serialisasi dengan memilih format yang lebih cepat, dan dependency dengan paralelisme — bukan menghapus batas timeout.

Load Testing dengan k6

Setelah bottleneck diperbaiki, buktikan dengan beban yang terukur. k6 (sudah ada di setup episode 0) memungkinkan tes beban didefinisikan sebagai kode, lengkap dengan threshold yang bisa digagalkan — persis pola load test-as-code yang selaras dengan episode 14.

load-test.js
import http from "k6/http";
import { check } from "k6";
 
export const options = {
  scenarios: {
    ramp: {
      executor: "ramping-vus",
      stages: [
        { duration: "1m", target: 50 },
        { duration: "2m", target: 200 },
        { duration: "1m", target: 0 },
      ],
    },
  },
  thresholds: {
    http_req_duration: ["p(95)<500", "p(99)<1200"],
    http_req_failed: ["rate<0.01"],
  },
};
 
export default function () {
  const res = http.get("https://api.example.com/checkout");
  check(res, { "status 2xx": (r) => r.status >= 200 && r.status < 300 });
}
Jalankan load test
k6 run --out json=results.json load-test.js

Bagian thresholds adalah kunci: ia mengubah tes beban dari laporan menjadi gate. Jika p95 melampaui 500 ms, k6 keluar dengan exit code non-zero — siap dipakai di CI sebagai blokir rilis, persis seperti unit test yang gagal.

Praktik: Optimasi Latency

Ikuti siklus lengkap pada service lab kalian:

  1. Ukur baseline: k6 run dengan 100 VU selama 3 menit; catat p50, p95, p99.
  2. Profil: py-spy record (atau profiler bahasa kalian) selama tes beban; buka flame graph.
  3. Identifikasi satu bottleneck terbesar: misalnya serialisasi JSON yang mahal di tiap request.
  4. Optimasi: ganti dengan serialisasi yang lebih ringan atau streaming, tanpa mengubah kontrak API.
  5. Tes ulang: jalankan skenario k6 yang identik, lalu bandingkan distribusi latensi.
  6. Simpan hasil: simpan results.json sebelum/sesudah di repo sebagai bukti (episode 14).
Perbandingan hasil (cuplikan)
Metric          Sebelum    Sesudah
http_req_duration p95   612ms      341ms
http_req_duration p99  1480ms      720ms
http_req_failed      1.2%       0.3%

Warning

Dua jebakan klasik: mengoptimasi mean alih-alih tail (pengguna merasakan p99, bukan p50), dan mengoptimasi dengan microbenchmark di luar alur request nyata. Selalu ukur dalam konteks alur lengkap, dengan beban mendekati produksi, sebelum mengklaim kemenangan.

Penutup

Pada episode 15 ini, kalian telah belajar mendekati performa dengan data, bukan perasaan.

Inti yang harus dibawa pulang:

  • Profile dulu, optimasi belakangan — flame graph lebih dipercaya daripada intuisi.
  • Optimasi tail latency, bukan rata-rata; gunakan latency budget per lapisan.
  • k6 mengubah load test menjadi kode dengan threshold yang bisa dijadikan gate CI.
  • Praktik yang benar: baseline terukur → profil → satu perubahan → ukur ulang → simpan bukti.

Di episode 16 selanjutnya, kita akan memperluas jangkauan: multi-region & disaster recovery — arsitektur active-active, failover, konsep RTO/RPO, dan DR drill untuk memastikan kalian pulih bukan hanya cepat, tapi juga terlatih. Sampai jumpa di episode 16!

Belajar Site Reliability Engineer - Performance Engineering | Belajar Site Reliability Engineer