Pengguna impatient seperti Alice menuntut respons di bawah 200 ms, sehingga arsitektur backend harus diatur untuk menghindari antrean panjang dan biaya berlebih. Menimbang arsitektur untuk pengguna impatient berarti secara langsung mengukur latensi akhir, throughput maksimum, dan biaya operasional, serta memahami di mana trade-off antara respons cepat dan pengeluaran terus menerus berada.

Dalam artikel ini, kita akan membandingkan monolit, mikroservis, event-driven, dan serverless berdasarkan metrik utama, memakai pendekatan kuantitatif simpel seperti hukum Little dan throughput per unit biaya, lalu menutup dengan observabilitas dan eksperimen beban agar keputusan tetap dapat diuji.

Menjawab Tantangan Alice: Latensi Target dan Biaya Operasional

Alice hanya sabar selama beberapa ratus milidetik. Jika arsitektur menghasilkan latensi rata-rata 250 ms, dia sudah mengalami frustrasi. Tapi menekan latensi ke bawah 150 ms sering memerlukan penambahan kapasitas, caching lebih agresif, atau perpustakaan yang lebih mahal.

Gunakan hukum Little (L = λW) untuk menentukan berapa banyak permintaan bersamaan yang aman. Misalnya, jika sistem harus melayani 250 permintaan per detik (λ) dengan waktu tunggu total (W) 0,18 detik demi mempertahankan target Alice, maka rata-rata jumlah permintaan yang sedang diproses (L) sekitar 45. Jika instance backend hanya bisa menampung 20 koneksi simultan, Anda harus menyiapkan minimal 3 node untuk menghindari antrean.

Penambahan node meningkatkan biaya dan menurunkan biaya per permintaan, jadi trade-offnya adalah: akomodasi latensi rendah atau hemat biaya. Kunci praktisnya adalah mengekspresikan target latensi sebagai batas atas antrean dan menyesuaikan kapasitas agar tidak melampaui nilai tersebut.

Perbandingan Arsitektur Backend

Monolit

Arsitektur monolit cenderung menawarkan latency rendah karena tidak ada overhead jaringan antar layanan. Throughput stabil jika instance cukup kuat, tapi sulit diskalakan secara granular. Keuntungannya adalah maintainability sederhana—kode, dependensi, dan pengujian dalam satu repo—namun update besar dapat mengganggu seluruh sistem.

Gunakan monolit jika Alice membutuhkan respons cepat dan beban traffic relatif konstan. Kombinasikan dengan caching di edge/CDN dan connection pooling untuk memaksimalkan latensi tanpa menambah banyak node.

Mikroservis

Mikroservis menarik karena memungkinkan tim menskalakan bagian dengan latency sensitif secara terpisah. Misalnya, layanan validasi kartu kredit bisa dijalankan pada cluster tersendiri dengan autoscaling yang agresif. Latensi akhir bisa naik karena pemanggilan lintas layanan dan serialization overhead; perhatikan penambahan timeout dan circuit breaker.

Gunakan mikroservis saat throughput tinggi tapi beragam dan Anda memerlukan kebebasan deploy. Pastikan observabilitas (distributed tracing) aktif agar bottleneck lintas layanan mudah dijelaskan.

Event-Driven

Arsitektur berbasis event membantu menjaga throughput besar dengan mendekoupling producer dan consumer. Namun, jika Alice memerlukan response langsung setelah event, Anda perlu pola request-response tersendiri karena processing async biasanya menambah latensi keseluruhan.

Solusi hybrid: gunakan event untuk proses non-latency-critical, tetapi sediakan API sinkron untuk permintaan real-time. Perhatikan backlog queue; antrean panjang meningkatkan W dalam hukum Little.

Serverless

Serverless memungkinkan Anda hanya membayar saat fungsi dijalankan, bagus untuk biaya rendah namun kadang menambah cold start latency. Jika target latensi Alice sangat ketat, siapkan provisioned concurrency atau front-door caching untuk menghindari cold start.

Analisis throughput per biaya secara nyata: fungsi yang berjalan 100 ms dengan biaya 0,0000002 USD akan memberikan throughput tinggi, tetapi pengaturan concurrency harus hati-hati agar tidak menimbulkan throttling dan antrean di platform serverless.

Pendekatan Kuantitatif untuk Trade-off Latensi vs Biaya

Satu cara sederhana adalah menghitung throughput per unit biaya. Contoh:

def throughput_per_cost(requests_per_second, monthly_cost_usd):
    return requests_per_second / monthly_cost_usd

print(throughput_per_cost(300, 600))  # 0.5 req/s per USD

Angka ini membantu membandingkan node monolitik kelas besar dengan kumpulan fungsi serverless lebih kecil. Kata kunci: pertahankan latency target (input untuk λ dan W) sambil memaksimalkan rasio throughput/biaya tersebut.

Verifikasi asumsi antrean dengan hukum Little. Misalnya, jika kita ingin latency <200 ms (W = 0,2 detik) dan throughput 400 req/s, maka L: = 80. Jika instance monolitik menampung 40 concurrent worker, kita butuh dua node. Jika hosting berbiaya 120 USD/bulan per node, total biaya 240 USD/bulan untuk menjaga latensi. Gunakan rasio throughput per biaya ini untuk membandingkan dengan opsi yang lain.

Observabilitas dan Eksperimen Beban

Tanpa observabilitas, Anda tidak bisa membuktikan bahwa latency target telah tercapai. Kumpulkan metrik:

  • Latency distribusi (p50, p95, p99) untuk melihat ekor antrean.
  • Queue length atau backlog pada load balancer/worker.
  • Success rate dan sat kurva (CPU, memori).
  • Distributed tracing untuk mengidentifikasi hops yang menyumbat.

Gunakan dashboard yang bisa menggabungkan metrik latency dan biaya untuk melihat bagaimana autoscaling memengaruhi pengeluaran.

Untuk eksperimen beban, jalankan skenario realistis dengan alat seperti k6:

import http from 'k6/http';
import { sleep } from 'k6';

export let options = {
  vus: 50,
  duration: '5m',
};

export default function () {
  http.get('https://api.example.com/items');
  sleep(0.25);
}

Jalankan dengan k6 run script.js lalu pantau latensi p99, CPU, dan antrean pada backend. Catat biaya tambahan akibat penambahan node ketika throughput naik. Jika antrean melonjak, catat penyebab (contention database, GC, dll.) lalu uji ulang setelah optimasi.

Panduan Pemilihan dan Implementasi

Langkah praktis:

  1. Definisikan latency budget untuk Alice. Syarat: apakah 150 ms realistis?
  2. Estimasi λ target dan W maksimum lalu hitung berapa banyak concurrency yang diperlukan.
  3. Tentukan opsi arsitektur yang memenuhi concurrency dengan biaya terendah sambil menjaga maintainability. Misalnya, monolit dengan worker pool besar untuk latency kritis, dan event-driven untuk batch background.
  4. Implementasikan observabilitas dan load test. Jika alert latency > budget, otomatis scale up atau degrade gracefully.
  5. Terus ukur throughput per cost dan adjust kapasitas, caching, atau desain arsitektur bila diperlukan.

Kesimpulannya: menimbang arsitektur untuk pengguna impatient berarti terus-menerus mengukur latensi aktual versus throughput dan biaya nyata. Gunakan pendekatan kuantitatif, bandingkan arsitektur, dan jalankan observabilitas serta eksperimentasi beban untuk memastikan Alice mendapatkan respons yang diharapkan tanpa membengkaknya biaya operasi.