8 menit

ZSTD vs Brotli vs GZIP: Memilih Kompresi untuk API

Bandingkan ZSTD, Brotli, dan GZIP untuk API: kecepatan, rasio, biaya CPU, dan default praktis untuk payload JSON dan biner di produksi.

ZSTD vs Brotli vs GZIP: Memilih Kompresi untuk API

Apa Itu Kompresi API (dan Kapan Layak Digunakan)

Kompresi respons API berarti server Anda mengenkripsi (encode) body respons (sering JSON) menjadi aliran byte yang lebih kecil sebelum mengirimkannya lewat jaringan. Klien (browser, aplikasi mobile, SDK, atau layanan lain) kemudian melakukan dekompresi. Di atas HTTP, ini dinegosiasikan lewat header seperti Accept-Encoding (apa yang didukung klien) dan Content-Encoding (apa yang dipilih server).

Apa manfaatnya untuk API

Kompresi terutama memberi Anda tiga hal:

  • Lebih sedikit bandwidth: Respons yang lebih kecil mengonsumsi lebih sedikit byte secara end-to-end.
  • Latency lebih rendah pada tautan terbatas: Lebih sedikit byte sering berarti unduhan lebih cepat pada seluler, Wi‑Fi padat, dan panggilan lintas-wilayah.
  • Biaya egress lebih rendah: Jika Anda membayar data keluar, mengurangi ukuran transfer bisa langsung menurunkan tagihan.

Pertukarannya jelas: kompresi menghemat bandwidth tetapi biaya CPU (kompres/dekompres) dan kadang memori (buffer). Apakah ini layak tergantung pada bottleneck Anda.

Kapan kompresi paling membantu

Kompresi cenderung efektif ketika respons bersifat:

  • Banyak teks dan repetitif, seperti JSON, respons GraphQL, HTML, atau log.
  • Sedang hingga besar, di mana mengurangi puluhan atau ratusan kilobyte berarti.
  • Dihidangkan lewat jaringan lambat atau mahal, seperti seluler, klien internasional, atau trafik lintas-region.

Jika Anda mengembalikan daftar JSON besar (katalog, hasil pencarian, analitik), kompresi sering menjadi salah satu optimasi termudah.

Kapan kompresi kurang membantu

Kompresi sering kali menjadi penggunaan CPU yang buruk ketika respons:

  • Kecil (mis. beberapa ratus byte). Overhead header + CPU bisa melebihi penghematan.
  • Sudah terkompresi (JPEG/PNG, MP4, ZIP, banyak PDF). Mengompres ulang biasanya memberi sedikit pengurangan dan bahkan dapat menambah ukuran.
  • Layanan yang terikat CPU (endpoint sibuk yang sudah kekurangan komputasi). Menambahkan kompresi bisa meningkatkan tail latency.

Sumbu keputusan yang akan digunakan di panduan ini

Saat memilih antara ZSTD vs Brotli vs GZIP untuk kompresi API, keputusan praktis biasanya turun ke:

  1. Pengurangan ukuran (rasio kompresi)
  2. Latency (waktu server-to-first-byte plus decode klien)
  3. Dukungan klien (apa yang klien dan perantara Anda tangani dengan andal)

Sisa artikel ini tentang menyeimbangkan ketiganya untuk API dan pola trafik Anda.

ZSTD vs Brotli vs GZIP: Perbandingan Singkat

Ketiganya mengurangi ukuran payload, tetapi mereka mengoptimalkan batasan yang berbeda—kecepatan, rasio kompresi, dan kompatibilitas.

Ringkasan satu pandang

  • ZSTD (Zstandard): Seringkali keseimbangan terbaik untuk API ketika Anda peduli pada latency rendah dan penggunaan CPU yang dapat diprediksi. Rasio bagus tanpa menjadi lambat.
  • Brotli: Sering menang pada ukuran byte terkecil, terutama untuk respons berbasis teks (JSON, konten mirip HTML). Pengaturan tinggi bisa lebih mahal CPU-nya.
  • GZIP: Opsi “berfungsi di mana saja”. Dukungan luas dan mudah dioperasionalkan, tetapi biasanya lebih lambat dan/atau lebih besar daripada alternatif modern pada anggaran CPU yang sebanding.

Kekuatan tipikal (dan apa artinya untuk API)

Kecepatan ZSTD: Bagus ketika API Anda sensitif terhadap tail latency atau server Anda terikat CPU. Ia dapat mengompresi cukup cepat sehingga overhead sering kali dapat diabaikan dibandingkan waktu jaringan—terutama untuk respons JSON berukuran sedang hingga besar.

Rasio kompresi Brotli: Terbaik ketika bandwidth adalah kendala utama (klien seluler, egress mahal, pengiriman lewat CDN) dan respons sebagian besar berbasis teks. Payload yang lebih kecil bisa bernilai meskipun kompresi memakan waktu lebih lama.

Kompatibilitas GZIP: Terbaik ketika Anda memerlukan dukungan klien maksimum tanpa risiko negosiasi (SDK lama, klien embedded, proxy legacy). Ini baseline yang aman meskipun bukan performer tertinggi.

Apa yang benar-benar diubah oleh “level kompresi”

“Level” kompresi adalah preset yang menukar waktu CPU untuk output yang lebih kecil:

  • Level rendah: Kompresi lebih cepat, payload lebih besar. Bagus untuk API real-time.
  • Level tinggi: Payload lebih kecil, kompresi lebih lambat (dan kadang memerlukan memori lebih banyak). Lebih baik untuk respons besar yang dapat di-cache.

Dekompressi biasanya jauh lebih murah daripada kompresi untuk ketiganya, tetapi level yang sangat tinggi masih dapat menambah beban CPU klien—penting untuk perangkat mobile.

Aturan praktis sederhana

  • Pilihan default: Gunakan ZSTD untuk kebanyakan API JSON/REST/GraphQL saat latency penting.
  • Beralih ke Brotli: Ketika Anda mengoptimalkan untuk byte minimal (respons berbasis teks, pengiriman lewat CDN, jaringan lambat) dan Anda bisa menanggung CPU tambahan.
  • Tetap gunakan GZIP: Ketika Anda membutuhkan kompatibilitas luas atau infrastruktur/tooling Anda tidak mendukung encoding baru.

Rasio Kompresi vs Latency: Perdagangan Inti

Kompresi sering dipasarkan sebagai “respons lebih kecil = API lebih cepat.” Itu sering benar pada jaringan lambat atau mahal—tetapi tidak otomatis. Jika kompresi menambah cukup banyak waktu CPU server, Anda bisa mendapat permintaan yang lebih lambat meskipun byte di jaringan berkurang.

Ke mana saja waktu pergi

Bermanfaat memisahkan dua biaya:

  • Waktu kompresi (server-side): kerja yang dilakukan sebelum server dapat mulai mengirim byte. Ini langsung menambah waktu respons (TTFB).
  • Waktu dekompresi (client-side): kerja yang dilakukan setelah menerima byte. Biasanya lebih murah daripada kompresi, tetapi dapat berpengaruh pada perangkat lambat.

Rasio kompresi yang tinggi dapat mengurangi waktu transfer, tetapi jika kompresi menambah (mis.) 15–30 ms CPU per respons, Anda mungkin kehilangan lebih banyak waktu daripada yang dihemat—terutama pada koneksi cepat.

Perangkap tail-latency di bawah beban

Di bawah beban, kompresi dapat merugikan p95/p99 latency lebih daripada p50. Saat penggunaan CPU melonjak, permintaan mengantri. Antrian memperbesar biaya per-request kecil menjadi delay besar—rata-rata latency tampak baik, tetapi pengguna paling lambat menderita.

Ukur seperti fitur performa

Jangan menebak. Jalankan A/B test atau rollout bertahap dan bandingkan:

  • p50 dan p95 latency (dan idealnya p99)
  • Utilisasi dan saturasi CPU pada instance API
  • Ukuran respons dan time-to-first-byte

Uji dengan pola trafik dan payload yang realistis. “Level” kompresi terbaik adalah yang mengurangi waktu total, bukan hanya byte.

Biaya CPU dan Memori di Server dan Klien

Kompresi tidaklah “gratis”—ia memindahkan kerja dari jaringan ke CPU dan memori pada kedua ujung. Dalam API, itu muncul sebagai waktu penanganan request yang lebih tinggi, jejak memori lebih besar, dan kadang perlambatan di sisi klien.

Di mana CPU dihabiskan

Sebagian besar CPU dihabiskan untuk mengompresi respons. Kompresi menemukan pola, membangun state/dictionary, dan menulis output terenkode.

Dekompressi biasanya lebih murah, tetapi tetap relevan:

  • Server mungkin mendekompresi request (jarang untuk JSON API, lebih umum untuk upload atau batched events).
  • Klien mendekompresi respons di jalur kritis sebelum mem-parse JSON.

Jika API Anda sudah terikat CPU (app server sibuk, auth berat, query mahal), mengaktifkan level kompresi tinggi dapat menambah tail latency meskipun payload mengecil.

Pertimbangan memori

Kompresi dapat meningkatkan penggunaan memori dalam beberapa cara:

  • Buffer: implementasi mungkin membutuhkan buffer input/output; payload lebih besar berarti buffer lebih besar.
  • Full buffering vs streaming: kompresi streaming dapat mulai mengirim lebih awal dan menjaga memori tetap datar, sementara full buffering dapat membesarkan puncak memori per-request.

Di lingkungan containerized, puncak memori yang lebih tinggi bisa berujung pada OOM kills atau batas lebih ketat yang mengurangi densitas.

Dampak pada autoscaling dan batas container

Kompresi menambah siklus CPU per respons, mengurangi throughput per instance. Itu dapat memicu autoscaling lebih cepat, menaikkan biaya. Pola umum: bandwidth turun, tetapi pengeluaran CPU naik—pilihan yang tepat bergantung pada sumber daya mana yang langka untuk Anda.

Mengapa kecepatan dekompresi penting bagi klien

Di perangkat mobile atau perangkat berdaya rendah, dekompresi bersaing dengan rendering, eksekusi JavaScript, dan baterai. Format yang menghemat beberapa KB tetapi memakan waktu dekompresi lebih lama bisa terasa lebih lambat, khususnya ketika “waktu sampai data dapat digunakan” penting.

ZSTD untuk API: Kekuatan, Batasan, dan Default yang Masuk Akal

Zstandard (ZSTD) adalah format kompresi modern yang dirancang untuk memberikan rasio kompresi kuat tanpa memperlambat API Anda. Untuk banyak API berbasis JSON, ini sering menjadi “default” yang kuat: respons lebih kecil dari GZIP pada latency yang serupa atau lebih rendah, ditambah dekompresi yang sangat cepat di klien.

Untuk apa ZSTD paling baik

ZSTD paling bernilai saat Anda peduli pada waktu end-to-end, bukan sekadar byte terkecil. Ia cenderung mengompresi cepat dan mendekompresi sangat cepat—berguna untuk API di mana setiap milidetik CPU bersaing dengan penanganan request.

Ia juga berkinerja baik di berbagai ukuran payload: JSON kecil-ke-sedang sering melihat keuntungan bermakna, sementara respons besar bisa mendapat manfaat lebih.

Level kompresi masuk akal untuk API

Untuk sebagian besar API, mulai dengan level rendah (umumnya level 1–3). Ini sering memberi trade-off terbaik antara latency/ukuran.

Gunakan level lebih tinggi hanya ketika:

  • Payload besar (ratusan KB hingga MB)
  • Bandwidth mahal atau terbatas
  • Anda sudah mengukur bahwa CPU bukan bottleneck

Pendekatan pragmatis: default global rendah, lalu tingkatkan level secara selektif untuk beberapa endpoint “respons besar”.

Streaming dan mode dictionary

ZSTD mendukung streaming, yang dapat mengurangi puncak memori dan mulai mengirim data lebih cepat untuk respons besar.

Dictionary mode bisa menjadi keuntungan besar untuk API yang mengembalikan banyak objek serupa (kunci berulang, skema stabil). Ini paling efektif ketika:

  • Payload relatif kecil tetapi sering
  • Anda dapat mengelola dictionary yang versioned dengan aman

Batas kompatibilitas yang perlu diperhatikan

Dukungan sisi server mudah di banyak stack, tetapi kompatibilitas klien bisa menjadi faktor penentu. Beberapa HTTP client, proxy, dan gateway masih tidak mengiklankan atau menerima Content-Encoding: zstd secara default.

Jika Anda melayani konsumen pihak ketiga, sediakan fallback (biasanya GZIP) dan aktifkan ZSTD hanya ketika Accept-Encoding jelas menyertakannya.

Brotli untuk API: Kapan Menang dan Kapan Tidak

Uji ambang ukuran
Hasilkan endpoint berisi daftar besar dan validasi ambang agar tidak membuang CPU untuk respons kecil.

Brotli dirancang untuk memampatkan teks dengan sangat baik. Pada JSON, HTML, dan payload “banyak kata” lainnya, ia sering mengalahkan GZIP pada rasio kompresi—terutama pada level kompresi yang lebih tinggi.

Di mana Brotli menang

Respons berbasis teks adalah titik kuat Brotli. Jika API Anda mengirim dokumen JSON besar (katalog, hasil pencarian, blob konfigurasi), Brotli dapat mengurangi byte secara signifikan, yang membantu pada jaringan lambat dan dapat menurunkan biaya egress.

Brotli juga kuat ketika Anda dapat mengompresi sekali lalu melayani banyak kali (respons cacheable, resource berversion). Dalam kasus itu, Brotli level tinggi bisa sepadan karena biaya CPU teramortisasi.

Di mana Brotli mengecewakan

Untuk respons API dinamis (dihasilkan setiap permintaan), rasio terbaik Brotli sering membutuhkan level tinggi yang bisa mahal CPU-nya dan menambah latency. Setelah Anda memperhitungkan waktu kompresi, keuntungan nyata dibanding ZSTD (atau bahkan GZIP yang disetel baik) mungkin lebih kecil dari yang diharapkan.

Brotli juga kurang menarik untuk payload yang tidak bisa terkompresi baik (data yang sudah dikompresi, banyak format biner). Pada kasus tersebut Anda hanya membakar CPU.

Panduan level praktis

  • Kompresi runtime: gunakan level rendah (umumnya 1–4) untuk menghindari lonjakan CPU.
  • Precompressed/static: level lebih tinggi (sering 8–11) bisa sepadan jika teramortisasi di banyak permintaan.

Catatan dukungan klien

Browser umumnya mendukung Brotli dengan baik lewat HTTPS, itulah sebabnya ia populer untuk trafik web. Untuk klien API non-browser (SDK mobile, perangkat IoT, stack HTTP lama), dukungan bisa tidak konsisten—jadi negosiasikan dengan benar lewat Accept-Encoding dan sediakan fallback (biasanya GZIP).

GZIP untuk API: Kompatibilitas dan Performa Praktis

GZIP tetap jawaban default untuk kompresi API karena merupakan opsi yang paling dipahami secara universal. Hampir setiap HTTP client, browser, proxy, dan gateway memahami Content-Encoding: gzip, dan prediktabilitas itu penting saat Anda tidak sepenuhnya mengendalikan apa yang ada di antara server dan pengguna.

Mengapa tetap umum

Keuntungannya bukan karena GZIP “terbaik”—melainkan karena jarang menjadi pilihan yang salah. Banyak organisasi memiliki pengalaman operasional bertahun-tahun dengannya, default masuk akal di web server mereka, dan lebih sedikit kejutan dengan perantara yang mungkin salah menangani encoding baru.

Level kompresi praktis untuk API

Untuk payload API (sering JSON), level kompresi menengah-ke-rendah biasanya merupakan titik manis. Level seperti 1–6 sering memberikan sebagian besar pengurangan ukuran sambil menjaga CPU tetap wajar.

Level sangat tinggi (8–9) bisa memeras sedikit lagi, tetapi waktu CPU tambahan biasanya tidak sepadan untuk traffic request/response dinamis di mana latency penting.

Perbandingan di CPU modern

Di hardware modern, GZIP umumnya lebih lambat daripada ZSTD pada rasio kompresi serupa, dan sering tidak bisa menyamai rasio terbaik Brotli pada teks. Dalam beban kerja API nyata, itu biasanya berarti:

  • ZSTD sering menang pada kecepatan per byte yang dihemat.
  • Brotli bisa menang pada ukuran untuk teks yang sangat kompresible, tetapi bisa lebih mahal CPU tergantung pengaturan.
  • GZIP tetap kompetitif karena “cukup cepat” dan dioptimalkan luas di banyak stack.

Edge case kompatibilitas (klien lama dan perantara)

Jika Anda harus mendukung klien lama, perangkat embedded, proxy perusahaan ketat, atau gateway legacy, GZIP adalah pilihan paling aman. Beberapa perantara akan menghapus encoding yang tidak dikenal, gagal meneruskannya, atau merusak negosiasi—isu yang jauh lebih jarang terjadi dengan GZIP.

Jika lingkungan Anda campur atau tidak pasti, mulai dengan GZIP (dan tambahkan ZSTD/Brotli hanya di mana Anda mengendalikan seluruh jalur) sering kali strategi rollout paling andal.

Tipe Payload: Apa yang Mudah Dikompresi (dan Apa yang Tidak)

Bangun bersama tim Anda
Ajak tim Anda ke satu workspace untuk membangun, deploy, dan meninjau perubahan performa bersama.

Kemenangan kompresi bukan hanya soal algoritma. Penggerak terbesar adalah jenis data yang Anda kirim. Beberapa payload mengecil drastis dengan ZSTD, Brotli, atau GZIP; lainnya hampir tidak berubah dan hanya membakar CPU.

Kandidat hebat (imbal hasil tinggi)

Respons berbasis teks cenderung sangat bisa dikompresi karena mengandung kunci berulang, whitespace, dan pola yang dapat diprediksi.

  • JSON (termasuk respons REST tipikal)
  • Respons GraphQL (sering verbose dengan nama field berulang)
  • XML dan HTML
  • Log teks besar dan jejak error yang dikembalikan oleh API

Semakin banyak repetisi dan struktur, semakin baik rasio kompresi.

Payload biner: “mungkin” (ukur dulu)

Format biner seperti Protocol Buffers dan MessagePack lebih ringkas daripada JSON, tetapi mereka bukan “acak”. Mereka masih bisa mengandung tag berulang, layout record serupa, dan urutan yang dapat diprediksi.

Itu berarti mereka sering kali masih bisa dikompresi, terutama untuk respons besar atau endpoint yang mengembalikan daftar. Jawaban yang andal hanyalah menguji dengan trafik nyata Anda: endpoint yang sama, data yang sama, kompresi on/off, dan bandingkan ukuran dan latency.

Biasanya tidak sepadan (sudah dikompresi)

Banyak format sudah terkompresi secara internal. Menerapkan kompresi respons HTTP di atasnya biasanya memberi sedikit penghematan dan dapat menambah waktu respons.

  • Gambar: JPEG, PNG, WebP
  • Video/audio: MP4 (dan sejenisnya)
  • Arsip: ZIP, gzip files
  • PDF: seringkali sudah menggunakan kompresi

Untuk ini, umum menonaktifkan kompresi berdasarkan tipe konten.

Heuristik praktis (jaga sederhana)

Pendekatan sederhana adalah hanya mengompresi ketika respons melewati ukuran minimum.

  • Tetapkan ambang ukuran respons (mis. beberapa KB) sebelum menambahkan Content-Encoding.
  • Selalu kompres respons teks besar; pertimbangkan melewatkan kompresi untuk JSON kecil di mana header mendominasi.

Ini menjaga CPU fokus pada payload tempat kompresi benar-benar mengurangi bandwidth dan memperbaiki performa end-to-end.

Header HTTP dan Negosiasi: Menyusun dengan Benar

Kompresi hanya berjalan mulus ketika klien dan server sepakat pada encoding. Kesepakatan itu terjadi lewat Accept-Encoding (dikirim klien) dan Content-Encoding (dikirim server).

Accept-Encoding dan Content-Encoding (contoh sederhana)

A client mengiklankan apa yang bisa didekodekan:

GET /v1/orders HTTP/1.1
Host: api.example
Accept-Encoding: zstd, br, gzip

Server memilih salah satu dan menyatakan apa yang ia gunakan:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Encoding: zstd

Jika klien mengirim Accept-Encoding: gzip dan Anda merespons dengan Content-Encoding: br, klien itu mungkin gagal mem-parse body. Jika klien tidak mengirim Accept-Encoding, default paling aman adalah tidak mengirim kompresi.

Memilih urutan prioritas sisi server

Urutan praktis untuk API sering kali:

  • zstd pertama (keseimbangan kecepatan/rasio yang bagus)
  • lalu br (sering lebih kecil, kadang lebih lambat)
  • lalu gzip (kompatibilitas terluas)

Dengan kata lain: zstd > br > gzip.

Jangan menganggap ini universal: jika trafik Anda kebanyakan browser, br mungkin pantas diprioritaskan lebih tinggi; jika Anda punya klien mobile lama, gzip mungkin pilihan “terbaik” yang paling aman.

Vary: Accept-Encoding dan caching

Jika respons dapat disajikan dalam beberapa encoding, tambahkan:

Vary: Accept-Encoding

Tanpa itu, CDN atau proxy mungkin meng-cache versi gzip (atau zstd) dan keliru menyajikannya ke klien yang tidak meminta (atau tidak bisa menangani) encoding tersebut.

Edge case dan fallback aman

Beberapa klien mengaku mendukung tapi mempunyai decoder yang buggy. Untuk tetap tahan banting:

  • Favoritkan fallback yang sudah teruji: jika error decoding melonjak untuk zstd, fallback sementara ke gzip.
  • Pertimbangkan allowlist untuk user-agent atau versi SDK yang bermasalah.
  • Untuk endpoint kritis (auth, webhooks), pertimbangkan menonaktifkan kompresi atau hanya menggunakan opsi yang paling kompatibel.

Negosiasi kurang tentang mengeruk setiap byte dan lebih tentang tidak pernah merusak klien.

HTTP/2, HTTP/3, CDN, dan Gateway

Kompresi API tidak berjalan sendiri. Protokol transport, overhead TLS, dan CDN atau gateway di antaranya dapat mengubah hasil dunia nyata—atau bahkan merusak jika salah konfigurasi.

HTTP/2 dan HTTP/3: multiplexing, head-of-line, dan apa yang diubah kompresi

Dengan HTTP/2, beberapa request berbagi satu koneksi TCP. Itu mengurangi overhead koneksi, tetapi kehilangan paket bisa menahan semua stream karena head-of-line blocking TCP. Kompresi dapat membantu dengan memperkecil body respons, mengurangi jumlah data yang “terjebak” di balik event loss.

HTTP/3 berjalan di atas QUIC (UDP) dan menghindari head-of-line blocking TCP antar stream. Ukuran payload tetap penting, tetapi penalti kehilangan biasanya kurang dramatis per koneksi. Dalam praktiknya, kompresi tetap bernilai—manfaatnya cenderung muncul sebagai penghematan bandwidth dan lebih cepat “time to last byte” daripada penurunan latency yang dramatis.

Interaksi TLS: jangan abaikan anggaran CPU

TLS sudah mengonsumsi CPU (handshake, enkripsi/dekripsi). Menambahkan kompresi (terutama di level tinggi) dapat mendorong Anda melewati batas CPU saat lonjakan. Ini sebabnya pengaturan “kompresi cepat dengan rasio layak” seringkali mengungguli “rasio maksimal” di produksi.

CDN dan API gateway: auto-compress, pass-through, atau strip

Beberapa CDN/gateway otomatis mengompresi tipe MIME tertentu, sementara yang lain meneruskan apa yang origin kirim. Beberapa mungkin menormalisasi atau bahkan menghapus Content-Encoding jika salah konfigurasi.

Verifikasi perilaku per route, dan pastikan Vary: Accept-Encoding dipertahankan agar cache tidak menyajikan varian terkompresi ke klien yang tidak memintanya.

Strategi caching: edge vs origin (dan banyak varian)

Jika Anda cache di edge, pertimbangkan menyimpan varian terpisah per encoding (gzip/br/zstd) daripada merekompres pada setiap hit. Jika Anda cache di origin, Anda masih mungkin ingin edge menegosiasikan dan menyimpan beberapa encoding.

Kuncinya konsistensi: Content-Encoding yang benar, Vary yang benar, dan kepemilikan yang jelas di mana kompresi terjadi.

Default yang Direkomendasikan dan Playbook Tuning

Atur tanpa khawatir
Sesuaikan level kompresi dan rollback instan jika tail latency memburuk.

Default yang disarankan menurut skenario

Untuk API yang berhadapan dengan browser, prioritaskan Brotli ketika klien mengiklankan itu (Accept-Encoding: br). Browser biasanya mendekode Brotli secara efisien, dan sering memberikan pengurangan ukuran yang lebih baik pada respons teks.

Untuk API internal antar-layanan, default ke ZSTD ketika kedua sisi berada di bawah kontrol Anda. Ia biasanya lebih cepat pada rasio yang setara dibanding GZIP, dan negosiasi mudah.

Untuk API publik yang digunakan oleh SDK beragam, pertahankan GZIP sebagai baseline universal dan tambahkan ZSTD secara opt-in untuk klien yang eksplisit mendukungnya. Itu menghindari merusak stack HTTP lama.

Level konservatif untuk mulai

Mulailah dengan level yang mudah diukur dan tidak mengejutkan:

  • Brotli: level 4–6 untuk respons API dinamis (level lebih tinggi dapat menambah CPU server secara nyata)
  • ZSTD: level 3–5 untuk payload API serbaguna
  • GZIP: level 5–6 (level lebih tinggi sering memberikan pengembalian yang menurun)

Jika Anda butuh rasio lebih kuat, validasi dengan sampel payload mirip produksi dan pantau p95/p99 latency sebelum menaikkan level.

Ambang ukuran minimum (dan tuning)

Mengompresi respons kecil bisa menelan CPU lebih banyak daripada penghematan di jaringan. Titik awal praktis:

  • Jangan kompres di bawah 1–2 KB untuk sebagian besar API
  • Pertimbangkan 4 KB jika Anda terikat CPU atau respons sangat chatty

Tuning dengan membandingkan: (1) byte yang dihemat, (2) waktu server tambahan, (3) perubahan end-to-end latency.

Cara aman mengekspos kontrol

Rollout kompresi di balik feature flag, lalu tambahkan konfigurasi per-route (aktifkan untuk /v1/search, nonaktifkan untuk endpoint yang sudah kecil). Sediakan client opt-out menggunakan Accept-Encoding: identity untuk troubleshooting dan klien edge. Selalu sertakan Vary: Accept-Encoding agar cache tetap benar.

Di mana ini muncul dalam workflow build-and-ship modern

Jika Anda menghasilkan API cepat (mis. memutar frontend React dengan backend Go + PostgreSQL, lalu iterasi berdasarkan trafik nyata), kompresi menjadi salah satu knob “konfigurasi kecil, dampak besar”.

Di Koder.ai, tim sering mencapai titik ini lebih awal karena dapat mem-prototype dan deploy full-stack apps cepat, lalu menyetel perilaku produksi (termasuk kompresi respons dan header cache) setelah endpoint dan bentuk payload stabil. Intinya tetap: anggap kompresi sebagai fitur performa, rilis di balik flag, dan ukur p95/p99 sebelum menyatakan kemenangan.

Rollout, Monitoring, dan Troubleshooting

Perubahan kompresi mudah dipakai dan cukup mudah salah. Perlakukan seperti fitur produksi: rollout bertahap, ukur dampak, dan sediakan rollback sederhana.

Rencana rollout yang aman

Mulai dengan canary: aktifkan Content-Encoding baru (mis. zstd) untuk sebagian kecil trafik atau satu klien internal.

Lalu naikkan bertahap (mis. 1% → 5% → 25% → 50% → 100%), berhenti jika metrik kunci bergerak ke arah yang buruk.

Simpan jalur rollback yang mudah:

  • Feature flag di gateway/service untuk menonaktifkan kompresi (atau fallback ke gzip).
  • Cara mengecualikan endpoint tertentu (download file, media yang sudah terkompresi).
  • Deploy konfigurasi cepat, bukan deploy kode.

Apa yang dipantau (dan kenapa)

Lacak kompresi sebagai perubahan performa dan reliabilitas:

  • CPU (server dan, jika bisa, klien): level kompresi tinggi dapat memicu lonjakan CPU.
  • Percentile latency (p50/p95/p99): kompresi sering membantu rata-rata latency tetapi bisa merugikan tail.
  • Ukuran respons: byte di wire per endpoint, plus delta “terkompresi vs tidak”.
  • Tingkat error: pantau 4xx/5xx, error decode klien, dan timeout.

Checklist troubleshooting

Saat sesuatu rusak, ini biasanya penyebabnya:

  • Double-compression: layanan upstream mengompresi lalu gateway mengompresi lagi.
  • Header salah: Content-Encoding disetel tapi body tidak terkompresi (atau sebaliknya).
  • Negosiasi buruk: mengabaikan Accept-Encoding, atau mengembalikan encoding yang klien tidak iklankan.
  • Stream korup: body terpotong, Content-Length salah, atau intervensi proxy/CDN.

Dokumentasikan ekspektasi klien

Jelaskan encodings yang didukung di dokumentasi Anda, termasuk contoh:

  • Apa yang harus dikirim klien: Accept-Encoding: zstd, br, gzip
  • Apa yang akan mereka terima: Content-Encoding: zstd (atau fallback)

Jika Anda mengirim SDK, tambahkan contoh decode copy-pasteable kecil dan nyatakan versi minimum yang mendukung Brotli atau Zstandard jika relevan.

Pertanyaan umum

Kapan kompresi respons API benar-benar layak diaktifkan?

Gunakan kompresi respons ketika respons bersifat berat teks (JSON/GraphQL/XML/HTML), berukuran sedang hingga besar, dan pengguna Anda berada di jaringan yang lambat/mahal atau Anda membayar biaya egress yang signifikan. Lewati (atau tetapkan ambang tinggi) untuk respons sangat kecil, media yang sudah terkompresi (JPEG/MP4/ZIP/PDF), dan layanan yang terikat CPU di mana pekerjaan per-request tambahan akan merusak p95/p99 latency.

Mengapa kompresi bisa membuat API lebih lambat meskipun respons menjadi lebih kecil?

Karena kompresi menukar bandwidth dengan CPU (dan kadang memori). Waktu kompresi dapat menunda kapan server mulai mengirim byte (TTFB), dan di bawah beban hal ini dapat memperbesar antrean—seringkali merugikan tail latency meskipun rata-rata latency membaik. Pengaturan terbaik adalah yang mengurangi waktu end-to-end, bukan hanya ukuran payload.

Bagaimana saya memilih antara ZSTD, Brotli, dan GZIP?

Prioritas praktis untuk banyak API adalah:

  • zstd pertama (cepat, rasio bagus)
  • lalu br (sering kali paling kecil untuk teks, dapat lebih mahal CPU)
  • lalu gzip (kompatibilitas paling luas)

Selalu dasarkan pilihan akhir pada apa yang diiklankan klien di Accept-Encoding, dan sediakan fallback aman (biasanya gzip atau identity).

Level kompresi apa yang masuk akal sebagai default untuk respons API dinamis?

Mulailah dari rendah dan ukur.

  • ZSTD: level 1–3 (atau hingga 3–5) untuk sebagian besar API JSON dinamis
  • Brotli: level 1–4 untuk kompresi runtime; simpan 8–11 untuk konten yang sudah diprekompresi/statis
  • GZIP: level 5–6 sebagai default yang baik

Level yang lebih tinggi biasanya memberi keuntungan ukuran yang berkurang namun dapat memicu lonjakan CPU dan memperburuk p95/p99.

Haruskah saya mengompresi setiap respons, atau hanya di atas ukuran tertentu?

Gunakan ambang ukuran respons minimum sehingga Anda tidak membakar CPU untuk payload kecil.

  • Titik awal umum: 1–2 KB
  • Jika Anda terikat CPU atau sangat chatty: pertimbangkan 4 KB

Tuning per-endpoint dengan membandingkan byte yang dihemat vs waktu server tambahan dan dampaknya terhadap p50/p95/p99 latency.

Tipe payload apa yang bagus dikompresi (dan mana yang biasanya tidak)?

Fokus pada tipe konten yang terstruktur dan berulang:

  • Hebat: JSON, GraphQL, XML, HTML, log teks besar
  • “Mungkin”: Protobuf/MessagePack (sering masih bisa dikompresi—ukur terlebih dahulu)
  • Biasanya tidak sepadan: JPEG/PNG/WebP, MP4, ZIP/gz, banyak PDF

Pendekatan umum: aktifkan kompresi hanya untuk nilai Content-Type yang menyerupai teks dan nonaktifkan untuk format yang sudah dikompresi.

Bagaimana Accept-Encoding dan Content-Encoding bekerja untuk API?

Kompresi harus mengikuti negosiasi HTTP:

  • Klien mengirim Accept-Encoding (mis. zstd, br, gzip)
  • Server merespons dengan Content-Encoding yang didukung

Jika klien tidak mengirim Accept-Encoding, respons paling aman biasanya tanpa kompresi. Jangan pernah mengembalikan Content-Encoding yang tidak diiklankan klien, atau Anda berisiko membuat klien gagal.

Mengapa Vary: Accept-Encoding penting saat menggunakan kompresi?

Tambahkan:

  • Vary: Accept-Encoding

Header ini mencegah CDN/proxy meng-cache (mis. sebuah respons gzip) dan keliru menyajikannya ke klien yang tidak meminta atau tidak dapat mendekode gzip (atau zstd/br). Jika Anda mendukung banyak encoding, header ini penting untuk perilaku caching yang benar.

Apa bug kompresi yang paling umum di produksi?

Mode kegagalan umum meliputi:

  • Double compression (origin mengompresi lalu gateway/CDN mengompresi lagi)
  • Header/body mismatch (Content-Encoding mengatakan gzip tetapi body tidak dikompresi)
  • Negosiasi yang salah (mengabaikan Accept-Encoding)
  • Interferensi proxy/CDN (menghapus atau mengubah header)
  • Content-Length yang salah saat streaming/kompresi

Saat debugging, tangkap header respons mentah dan verifikasi dekompresi dengan tool/klien yang diketahui baik.

Bagaimana cara merilis dan memantau kompresi API dengan aman?

Rollout seperti fitur performa:

  • Canary atau potongan kecil terlebih dahulu, lalu naikkan (mis. 1% → 5% → 25% → 100%)
  • Simpan jalur rollback cepat (feature flag atau konfigurasi gateway)
  • Pantau:
    • Utilisasi/saturasi CPU
    • p50/p95/p99 latency dan TTFB
    • wire bytes (terkompresi vs tidak terkompresi)
    • error/timeouts dan kegagalan dekompresi klien

Jika tail latency naik di bawah beban, turunkan level, naikkan ambang, atau pindah ke codec yang lebih cepat (seringkali ZSTD).

Related posts