Buffer & Timeout

Buffer & Timeout #

Dua hal yang sering diabaikan saat mengkonfigurasi reverse proxy adalah buffering dan timeout. Keduanya berdampak langsung pada bagaimana Nginx berperilaku saat trafik tinggi atau saat backend lambat — dan salah konfigurasi di sini bisa menyebabkan error yang sulit didiagnosis.

Bagaimana Buffering Bekerja #

Ketika Nginx menerima response dari backend, ia bisa bekerja dalam dua mode:

Dengan buffering (default): Nginx membaca seluruh response dari backend ke memori (atau ke file sementara jika terlalu besar) sebelum mulai mengirim ke klien. Backend selesai lebih cepat dan bisa menangani request lain, sementara Nginx mengurus pengiriman ke klien yang mungkin lambat.

Tanpa buffering: Nginx langsung meneruskan data dari backend ke klien secara real-time, tanpa menyimpan di memori. Berguna untuk streaming atau Server-Sent Events.

Dengan buffering:
Backend → [Nginx Buffer] → Klien
          (backend selesai, buffer pegang data)

Tanpa buffering:
Backend → Nginx → Klien (real-time, langsung)

Directive Buffering #

location / {
    proxy_pass http://backend;

    # Aktifkan/nonaktifkan buffering (default: on)
    proxy_buffering on;

    # Jumlah dan ukuran buffer untuk membaca response awal dari backend
    # (termasuk header dan awal body)
    proxy_buffers 16 4k;

    # Ukuran buffer untuk bagian pertama response
    # (biasanya untuk header saja)
    proxy_buffer_size 4k;

    # Batas data yang di-buffer sebelum mulai dikirim ke klien
    proxy_busy_buffers_size 8k;

    # Jika response melebihi buffer, simpan sementara ke file
    proxy_temp_path /var/cache/nginx/temp;
    proxy_max_temp_file_size 1024m;
}

Untuk sebagian besar aplikasi web biasa, nilai default sudah cukup. Tuning buffer diperlukan saat:

  • Aplikasi mengembalikan response besar (JSON besar, file)
  • Backend sangat cepat merespons tapi klien lambat mengunduh
  • Kamu ingin mengoptimalkan memori usage

Nonaktifkan buffering untuk streaming #

location /stream/ {
    proxy_pass http://streaming_backend;
    proxy_buffering off;         # Real-time streaming
    proxy_cache off;             # Jangan cache stream
    proxy_read_timeout 3600s;    # Timeout panjang untuk koneksi long-lived
}

# Contoh untuk Server-Sent Events (SSE)
location /events {
    proxy_pass http://sse_backend;
    proxy_buffering off;
    proxy_set_header Connection '';
    proxy_http_version 1.1;
    chunked_transfer_encoding on;
}

Timeout: Lima Nilai yang Perlu Dipahami #

Nginx memiliki beberapa jenis timeout untuk koneksi ke backend, masing-masing mengukur hal yang berbeda:

location / {
    proxy_pass http://backend;

    # Timeout untuk MEMBUKA koneksi ke backend
    # Jika backend tidak merespons koneksi dalam waktu ini → 502
    proxy_connect_timeout 10s;

    # Timeout untuk MEMBACA data dari backend
    # Waktu maksimum antara dua paket yang diterima dari backend
    # BUKAN total waktu response — ini per-paket
    proxy_read_timeout 60s;

    # Timeout untuk MENGIRIM request ke backend
    # Waktu maksimum antara dua write ke backend
    proxy_send_timeout 60s;
}

Perbedaan penting: proxy_read_timeout bukan batas waktu total untuk backend memproses request. Ia mengukur waktu idle antara dua paket data — selama backend terus mengirim data (meski lambat), timeout tidak terpicu.

Timeout untuk klien #

server {
    # Timeout untuk membaca body request dari klien
    client_body_timeout 30s;

    # Timeout untuk membaca header request dari klien
    client_header_timeout 30s;

    # Berapa lama koneksi keep-alive dijaga tetap terbuka
    keepalive_timeout 65s;

    # Timeout untuk mengirim response ke klien
    send_timeout 30s;
}

Nilai Timeout yang Tepat untuk Berbagai Skenario #

Tidak ada nilai “satu untuk semua” — nilai timeout yang tepat bergantung pada karakteristik aplikasi:

# API dengan response cepat (< 5 detik)
proxy_connect_timeout  5s;
proxy_read_timeout    10s;
proxy_send_timeout    10s;

# Aplikasi yang kadang punya operasi berat (laporan, export data)
proxy_connect_timeout  10s;
proxy_read_timeout    120s;   # 2 menit untuk operasi berat
proxy_send_timeout     60s;

# Long-polling atau WebSocket
proxy_connect_timeout  10s;
proxy_read_timeout   3600s;   # 1 jam untuk koneksi persisten
proxy_send_timeout   3600s;

Keepalive ke Backend #

Membuka koneksi TCP baru ke backend untuk setiap request memiliki overhead. Nginx bisa mempertahankan pool koneksi ke backend yang bisa digunakan ulang:

upstream backend {
    server localhost:3000;
    # Pertahankan 32 koneksi keepalive ke backend ini
    keepalive 32;
}

server {
    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;      # Keepalive butuh HTTP/1.1
        proxy_set_header Connection ""; # Hapus header Connection dari klien
    }
}

Dengan keepalive, Nginx tidak membuka koneksi TCP baru ke backend untuk setiap request — ia menggunakan koneksi yang sudah ada dari pool. Ini mengurangi latency terutama untuk aplikasi dengan banyak request kecil.


Diagnosis: Apa Arti Berbagai Error #

Memahami kode error yang terkait buffering dan timeout memudahkan debugging:

502 Bad Gateway
→ Backend tidak merespons atau koneksi ditolak
→ Cek: apakah backend berjalan? proxy_connect_timeout terlalu singkat?

504 Gateway Timeout
→ Backend terlalu lama merespons
→ Cek: proxy_read_timeout terlalu singkat untuk operasi ini?
        Backend ada bottleneck?

413 Request Entity Too Large
→ Request body melebihi client_max_body_size
→ Cek: apakah perlu upload file besar? Naikkan client_max_body_size.

499 (Nginx-specific, bukan HTTP standar)
→ Klien memutus koneksi sebelum backend selesai merespons
→ Bisa jadi klien timeout di sisi mereka, atau koneksi tidak stabil

Ringkasan #

  • Buffering on (default): backend selesai cepat, Nginx urus pengiriman ke klien — baik untuk aplikasi normal. Nonaktifkan untuk streaming/SSE.
  • proxy_connect_timeout: timeout membuka koneksi ke backend. proxy_read_timeout: timeout idle antar paket, bukan total waktu — set lebih tinggi untuk operasi berat.
  • Gunakan keepalive di upstream block untuk mengurangi overhead pembukaan koneksi TCP ke backend.
  • 502 = backend tidak bisa dihubungi; 504 = backend terlalu lambat — keduanya terkait timeout tapi penyebabnya berbeda.

← Sebelumnya: Proxy Headers   Berikutnya: Proxy Cache →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact