Producer yang cepat dan consumer yang lebih lambat dapat berjalan aman hanya selama selisih laju keduanya tetap terbatas. Jika pekerjaan masuk lebih cepat daripada kemampuan penyelesaiannya dalam waktu yang cukup lama, buffering tidak menghapus overload. Buffer hanya menyimpan selisih tersebut.

Backpressure menjadikan ketimpangan kapasitas itu bagian dari protokol antarkomponen. Alih-alih menerima pekerjaan tanpa batas, stage yang jenuh membuat kode upstream melambat, menunggu kapasitas, mengurangi demand, atau menolak pekerjaan berdasarkan kebijakan yang eksplisit.

Antrean menyimpan selisih laju

Misalkan producer menghasilkan pekerjaan dengan laju (p) dan consumer menyelesaikannya dengan laju (c). Selama (p > c), pekerjaan dalam antrean bertambah kira-kira sebesar:

[ q’(t) = p - c ]

selama ketimpangan tersebut bertahan dan tidak ada batas admission yang menghentikannya.

Ketimpangan sementara adalah burst yang normal. Ketimpangan berkelanjutan adalah overload. Memperbesar antrean dapat menampung burst yang lebih panjang, tetapi juga menambah jumlah pekerjaan yang sudah diterima ketika consumer tertinggal.

Kapasitas antrean dan kapasitas pemrosesan adalah resource yang berbeda. Memori dapat menyimpan ribuan request tertunda tanpa menambah throughput database, jaringan, CPU, atau remote service.

Bounded handoff membuat saturasi terlihat

Bounded queue memberi producer titik konkret saat kapasitas habis. Ketika antrean penuh, operasi handoff harus memiliki semantik yang jelas.

Producer sinkron dapat menunggu sampai slot tersedia. Producer asinkron dapat menunggu sinyal readiness. Request handler dapat menolak pekerjaan baru. Protokol streaming dapat mengurangi atau menghentikan data yang diminta dari upstream.

Semua mekanisme itu membawa informasi yang sama: kapasitas downstream sedang tidak tersedia.

Unbounded queue menyembunyikan sinyal tersebut. Producer terus melihat enqueue berhasil sementara latency dan konsumsi memori meningkat. Kegagalan baru muncul kemudian sebagai timeout, tekanan memori proses, atau pekerjaan usang yang hasilnya sudah tidak dibutuhkan caller.

Backpressure berbeda dari rate limiting

Rate limiting menerapkan kebijakan terhadap demand yang diterima, biasanya memakai rate, quota, atau burst allowance yang dikonfigurasi. Backpressure mencerminkan kapasitas saat ini di sepanjang jalur eksekusi.

Sebuah service dapat membutuhkan keduanya. Token bucket dapat membatasi satu tenant sesuai rate kontraktual, sementara bounded worker queue menerapkan backpressure ketika service sedang jenuh. Yang pertama menyatakan kebijakan alokasi; yang kedua mencegah kemacetan downstream tersembunyi.

Perbedaannya juga terlihat saat pemulihan. Rate limiter dapat menolak traffic ketika worker sedang idle karena quota sudah habis. Backpressure dapat hilang segera setelah kapasitas downstream kembali tersedia.

Blocking memerlukan model eksekusi tanpa circular wait

Blocking handoff sederhana ketika producer dan consumer memiliki kapasitas eksekusi yang independen. Mekanisme ini berbahaya ketika producer memegang resource yang dibutuhkan consumer.

Bayangkan thread pool dengan semua worker mengirim pekerjaan lanjutan ke antrean penuh lalu memblokir sambil menunggu slot. Jika consumer antrean itu juga membutuhkan worker dari pool yang sama dan sudah habis, tidak ada worker yang dapat menciptakan kapasitas yang sedang ditunggu.

Lock menimbulkan risiko serupa. Menunggu kapasitas downstream sambil memegang lock dapat mencegah jalur downstream memperoleh lock tersebut untuk menyelesaikan pekerjaan yang ada.

Karena itu, backpressure memerlukan model eksekusi selain batas antrean. Titik blocking, kepemilikan lock, thread atau task pool, dan jalur cancellation harus tersusun tanpa circular wait.

Sinyal demand asinkron tetap memerlukan accounting terbatas

API asinkron sering merepresentasikan backpressure tanpa memblokir thread. Consumer dapat meminta jumlah item terbatas, writable stream dapat mengekspos readiness, atau operasi send dapat mengembalikan future yang selesai saat kapasitas tersedia.

Accounting tetap harus dibatasi. Jika aplikasi merespons socket yang tidak writable dengan menumpuk payload di list tanpa batas, aplikasi hanya memindahkan antrean.

Masalah serupa muncul pada future. Membuat sejuta operasi asinkron sebelum menunggu penyelesaiannya dapat menghabiskan banyak memori dan concurrency downstream walaupun tidak ada thread yang diblokir. Semaphore, bounded channel, atau jendela in-flight terbatas dapat membuat anggaran concurrency eksplisit.

Cancellation perlu mengikuti pekerjaan dalam antrean

Backpressure meningkatkan kemungkinan pekerjaan menunggu sebelum dieksekusi. Selama penantian itu, caller dapat terputus, deadline dapat habis, atau operasi yang lebih baru dapat menggantikan pekerjaan dalam antrean.

Jika cancellation berhenti di batas request terluar, pekerjaan usang dapat tetap berada di antrean internal dan memakai kapasitas setelah hasilnya tidak lagi bernilai.

Jalur yang kuat membawa informasi cancellation atau deadline melewati handoff. Pekerjaan dalam antrean kemudian dapat dihapus, dilewati sebelum pemrosesan mahal, atau dihentikan ketika operasinya mendukung cancellation yang aman.

Cancellation bukan pengganti kontrol kapasitas. Fungsinya adalah mencegah resource langka dipakai untuk pekerjaan yang hasilnya sudah tidak dibutuhkan.

Kebijakan overload berada di batas admission

Tidak semua producer dapat menunggu. HTTP server mungkin perlu mengembalikan respons overload. Pipeline telemetry dapat memilih membuang sampel berprioritas rendah. Batch importer dapat menghentikan pembacaan sumber sementara. Message consumer dapat mengurangi fetch window.

Tindakan yang tepat bergantung pada kontrak di batas tersebut, tetapi keputusannya harus disengaja. Buffering diam-diam mengubah keputusan kapasitas menjadi keputusan latency tanpa menyatakan trade-off itu.

Jika rejection diizinkan, lakukan sebelum pekerjaan mahal sejauh memungkinkan. Penolakan dini mempertahankan kapasitas bagi request yang sudah diterima dan memberi caller sinyal yang lebih jelas daripada menerima pekerjaan yang kemungkinan besar berakhir timeout.

Metrik perlu memperlihatkan tekanan sebelum kegagalan

Queue depth berguna, tetapi belum cukup. Antrean setengah penuh yang cepat menyusut berbeda dari antrean setengah penuh yang terus bertambah.

Sinyal yang berguna mencakup queue occupancy, enqueue wait time, pekerjaan yang ditolak atau dibuang, operasi in-flight, throughput consumer, arrival rate producer, jumlah cancellation, dan waktu yang dihabiskan pada batas admission.

Enqueue wait yang berkelanjutan merupakan bukti langsung bahwa producer sedang dibatasi. Antrean yang berulang kali mencapai batas dapat menandakan kapasitas kurang, demand berlebihan, atau batas yang terlalu sempit untuk burst normal.

Metrik ini juga membedakan backpressure yang efektif dari overload tersembunyi. Sistem yang tetap berada dalam batas memori dengan membuat semua caller menunggu jauh melewati deadline memang bounded, tetapi tidak memberikan layanan yang berguna.

Sinyal kapasitas perlu melintasi batas yang sama dengan demand

Backpressure paling efektif ketika setiap stage dapat mengomunikasikan keterbatasan kapasitas kepada stage yang memasoknya. Hubungan ini dapat berada dalam satu proses melalui bounded channel, melintasi stream melalui flow-control window, atau berada pada service boundary melalui rejection dan retry semantics yang eksplisit.

Mekanismenya berubah mengikuti transport, tetapi invariant-nya tetap: penerimaan pekerjaan tidak boleh menyiratkan kapasitas downstream tanpa batas.

Bounded handoff membuat overload terlihat pada titik saat sistem masih dapat menentukan tindakan terhadap pekerjaan baru. Hasilnya, penggunaan memori tetap terbatas, biaya latency dapat diamati, dan kemacetan berubah dari kejutan yang terlambat menjadi keputusan kontrol yang eksplisit.