Sebuah service dapat berjalan sehat pada 2.000 request per detik lalu runtuh pada 2.400. Tambahan 400 request tidak sekadar menunggu giliran. Request tersebut dapat memenuhi connection slot, antrean, memory, worker thread, database session, dan retry budget sementara throughput yang berguna justru turun.
Load shedding menempatkan keputusan admission sebelum resource langka terpakai penuh. Ketika sistem tidak mampu melayani seluruh pekerjaan masuk di dalam batas operasinya, sebagian request ditolak lebih awal daripada membiarkan semuanya berebut resource sampai seluruh jalur menjadi lambat.
Targetnya bukan nol error saat overload. Targetnya adalah error yang terkendali agar throughput berguna tetap tersedia dan sistem masih memiliki ruang untuk pulih.
Saturasi mengubah biaya menunggu
Service dengan beban ringan biasanya memiliki worker cadangan dan antrean pendek. Satu request tambahan hanya memberi sedikit dampak pada pekerjaan yang sudah berjalan.
Di dekat titik jenuh, arrival yang sama dapat memiliki biaya berbeda. Worker pool yang penuh mendorong pekerjaan ke antrean. Waktu antre menambah latency sehingga caller menunggu lebih lama. Sebagian caller melakukan retry dan menambah arrival baru. Memory yang ditahan request dalam antrean bertambah, sementara downstream pool dapat terpakai lebih lama.
Sistem yang menerima pekerjaan lebih cepat daripada kemampuan menyelesaikannya menumpuk utang di antrean. Jika arrival terus berada di atas kapasitas service, utang itu baru berkurang ketika permintaan turun atau kapasitas naik.
Menolak sebagian pekerjaan di dekat admission boundary mencegah utang tersebut tumbuh tanpa batas.
Admission ditempatkan sebelum resource langka
Penolakan menghemat kapasitas paling besar ketika terjadi sebelum pekerjaan mahal dimulai.
Bayangkan HTTP service dengan database pool sebagai bottleneck. Menolak request setelah payload besar selesai diparsing, beberapa remote call dilakukan, dan database connection diperoleh hanya melindungi sedikit kapasitas. Admission gate sebelum tahap tersebut dapat menghindari sebagian besar biaya.
Boundary yang tepat bergantung pada workload. Posisinya dapat berada sebelum worker pool, database transaction, queue, decompression, model inference call, atau operasi fan-out.
Gate yang efektif mengukur tekanan dekat dengan resource yang dilindungi. Threshold CPU global dapat terlalu tidak langsung jika bottleneck sebenarnya adalah database pool berisi 50 connection.
Concurrency limit membatasi pekerjaan yang sedang berjalan
Salah satu mekanisme admission yang praktis adalah concurrency limit. Jika service mengizinkan paling banyak N operasi mahal pada saat yang sama, request N + 1 harus menunggu dalam antrean terbatas atau menerima penolakan.
Model minimalnya:
if in_flight >= limit:
reject()
else:
in_flight += 1
execute()
in_flight -= 1Implementasi nyata harus melepas permit pada setiap jalur penyelesaian, termasuk error dan cancellation. Jika penantian diizinkan, kebijakan untuk pekerjaan dalam antrean juga harus tegas.
Concurrency limit berbeda dari rate limit. Rate limit mengendalikan arrival sepanjang waktu. Concurrency limit mengendalikan occupancy secara bersamaan. Dependency yang lambat dapat membuat arrival rate yang tidak tinggi menjadi berbahaya karena setiap request menahan kapasitas lebih lama.
Keduanya dapat dipakai bersama: satu membatasi intensitas arrival, sedangkan yang lain membatasi pekerjaan yang sudah diterima.
Antrean terbatas membuat overload terlihat
Antrean tanpa batas hanya menunda penolakan. Ketika waktu antre melewati time budget yang masih berguna bagi caller, request yang sudah diterima dapat kedaluwarsa sebelum eksekusi dimulai.
Antrean terbatas memberi batas tunggu dalam satuan pekerjaan. Saat antrean penuh, service memiliki sinyal overload yang konkret dan dapat segera menolak arrival baru.
Ukuran antrean sebaiknya mengikuti kontrak latency dan service rate, bukan keinginan untuk menyembunyikan error. Antrean yang lebih besar dapat menambah jumlah request yang akhirnya timeout sambil tetap memakai memory dan scheduling effort.
Admission yang sadar deadline dapat lebih ketat. Jika sebuah request secara realistis tidak sempat dieksekusi sebelum deadline, penolakan saat enqueue mempertahankan ruang bagi pekerjaan dengan budget yang masih layak.
Kebijakan seleksi menentukan pekerjaan yang bertahan
Tidak semua request memiliki nilai operasional yang sama. Service dapat mencadangkan kapasitas untuk health check, operasi control plane, traffic interaktif, atau request yang dibutuhkan untuk memulihkan sistem.
Priority harus tetap dibatasi. Jika traffic berpriority tinggi dapat memakai semua permit, kelas lain dapat mengalami starvation tanpa batas. Pool terpisah, permit cadangan, atau weighted admission membuat alokasi tersebut eksplisit.
Input kebijakan juga harus stabil. Priority field dari client tidak aman sebagai satu-satunya otoritas jika client diuntungkan dengan menandai semua request sebagai urgent. Priority biasanya berasal dari authenticated identity, klasifikasi route di sisi server, atau sumber kebijakan tepercaya lain.
Random shedding dapat memadai ketika seluruh request setara. Kebijakan yang lebih selektif hanya berguna jika klasifikasinya mewakili sasaran service yang nyata.
Penolakan memerlukan kontrak retry
Penolakan dini memindahkan tanggung jawab ke caller, sehingga respons harus memiliki semantik yang jelas.
Untuk HTTP, service dapat memakai 429 Too Many Requests untuk admission berbasis policy atau rate dan 503 Service Unavailable untuk kegagalan kapasitas sementara, sesuai kontrak API. Retry-After dapat memberi petunjuk retry ketika server memiliki estimasi atau interval kebijakan yang bermakna.
Retry tidak boleh menghapus manfaat shedding. Retry langsung yang tersinkronisasi dapat mengubah satu gelombang penolakan menjadi gelombang berikutnya. Caller memerlukan jumlah attempt terbatas, backoff, jitter, dan deadline request awal.
Operasi non-idempotent memerlukan perhatian tambahan. Penolakan sebelum eksekusi lebih mudah di-retry dengan aman dibanding kegagalan ambigu setelah side effect mungkin sudah commit. Karena itu, admission sebaiknya terjadi sebelum operasi melewati durable side-effect boundary jika protocol memungkinkan.
Limit adaptif memerlukan feedback signal yang stabil
Concurrency limit tetap sederhana dan mudah diprediksi, tetapi kapasitas aman dapat berubah mengikuti dependency latency, ukuran instance, cache state, atau campuran workload.
Adaptive admission dapat menyesuaikan limit dari latency atau queueing signal yang diamati. Controller tetap memerlukan guardrail. Signal yang bising dapat membuat limit berosilasi, sedangkan kenaikan cepat dapat mendorong dependency yang sedang pulih kembali ke kondisi jenuh.
Measurement sebaiknya mewakili pekerjaan yang diterima, bukan hanya pekerjaan yang ditolak. Volume penolakan menunjukkan demand melewati gate saat ini; angka itu tidak membuktikan bahwa resource yang dilindungi aman menerima lebih banyak pekerjaan.
Kebijakan adaptif memerlukan batas minimum dan maksimum, laju penyesuaian yang terkendali, serta telemetry yang menampilkan limit terpilih dan signal yang menggerakkannya.
Shedding harus tersusun di seluruh service boundary
Penolakan pada satu service tidak melindungi setiap komponen downstream. Request yang diterima frontend dapat melakukan fan-out ke beberapa dependency dengan capacity envelope berbeda.
Admission gate lokal sebaiknya melindungi resource langka lokal. Downstream service tetap memerlukan kontrol sendiri karena estimasi upstream dapat usang dan caller lain mungkin memakai dependency yang sama.
Call chain juga memerlukan propagasi deadline dan cancellation. Parent request yang ditolak atau kedaluwarsa sebaiknya menghentikan child work jika cancellation didukung. Tanpa itu, frontend dapat terlihat terlindungi sementara kapasitas remote masih dipakai operasi yang sudah ditinggalkan.
Load shedding, bounded concurrency, deadline, dan cancellation menangani bagian berbeda dari jalur overload yang sama.
Kapasitas pemulihan merupakan bagian dari desain
Service yang jenuh memerlukan kapasitas bebas untuk memproses pekerjaan yang mengembalikan kondisi normal: health probe, cache refresh, leadership traffic, configuration update, atau request yang menguras backlog.
Jika traffic biasa memakai seluruh resource, service dapat tetap terjebak meski peak demand mulai turun. Admission policy dapat mencadangkan sedikit kapasitas untuk operasi penting bagi pemulihan atau mengisolasinya dalam pool terpisah.
Cadangan ini bukan throughput gratis. Kapasitas tersebut sengaja tidak diberikan kepada pekerjaan biasa agar sistem tetap memiliki jalur kembali ke kondisi stabil.
Throughput berguna menjadi sasaran utama
Kebijakan overload yang baik terlihat dari lebih dari sekadar jumlah penolakan. Operator memerlukan admitted request rate, rejected request rate, in-flight work, queue depth, queue wait, dependency latency, timeout rate, retry volume, dan resource saturation.
Perbedaan pentingnya terletak pada offered load dan pekerjaan berguna yang selesai. Saat overload, menerima lebih banyak request dapat menaikkan metrik pertama sekaligus menurunkan metrik kedua.
Load shedding membuat trade-off tersebut eksplisit. Setelah kapasitas habis, menolak pekerjaan tertentu lebih awal dapat menjaga pekerjaan yang tersisa cukup cepat untuk selesai, mempertahankan dependency di dalam batas operasinya, dan menyisakan headroom agar service dapat pulih.