Sebuah penjelasan singkat sebelum kita membahas perintah-perintahnya: kami adalah Geonode dan kami menjual layanan proxy; artinya, sejujurnya perlu disampaikan sejak awal bahwa timeout curl hampir tidak pernah disebabkan oleh masalah proxy. Jika permintaan Anda mengalami timeout terhadap server yang sekadar lambat, atau host yang sedang down, atau firewall yang memblokir paket secara diam-diam, mengarahkan permintaan tersebut melalui kami tidak akan mengubah apa pun kecuali tagihan Anda. Proksi berguna ketika masalahnya terletak pada dari mana permintaan Anda tampaknya berasal — konten yang dibatasi secara geografis, batasan laju yang terkait dengan alamat Anda, atau alamat IP yang diblokir. Proksi tidak akan membuat server yang lambat menjadi cepat. Atur batas waktu Anda dengan benar terlebih dahulu; Anda mungkin akan menyadari bahwa Anda tidak memerlukan hal lain.
Benar. Inilah hal yang kebanyakan orang temukan dengan cara yang sulit: curl tidak memiliki batas waktu keseluruhan bawaan. Ia memiliki batas waktu koneksi bawaan sebesar 300 detik, tetapi begitu koneksi terjalin, curl akan dengan senang hati menunggu tanpa batas waktu untuk respons yang tidak pernah sepenuhnya tiba. Dalam skrip shell yang berjalan di cron, hal itu berarti tugas yang tidak pernah selesai dan berkas kunci yang tidak pernah dihapus oleh siapa pun.
Dua Batas Waktu yang Penting
Seluruh hal lainnya hanyalah penyempurnaan dari kedua hal ini.
--max-time
(bentuk singkat -m
) menjadi batas akhir dari seluruh proses. Dari panduan curl: "Waktu maksimum dalam detik yang Anda izinkan untuk proses transfer berlangsung." Mulai dari koneksi, handshake, permintaan, hingga respons—semuanya. Saat batas tersebut tercapai, curl akan menghentikan proses dan keluar dengan kode 28.
curl -m 10 https://example.com
Total sepuluh detik, kemudian curl akan berhenti terlepas dari tahap mana pun yang telah dicapainya.
--connect-timeout
hanya membatasi fase penyiapan. Manual tersebut menjelaskan dengan tepat apa saja yang termasuk di dalamnya: "Fase koneksi dianggap selesai ketika pencarian DNS dan proses handshake TCP, TLS, atau QUIC yang diminta telah selesai." Setelah koneksi terjalin, opsi ini tidak lagi berlaku.
curl --connect-timeout 3 https://example.com
Tiga detik untuk menyelesaikan pencarian nama dan proses handshake. Setelah itu, curl akan menunggu selama waktu yang dibutuhkan untuk transfer.
Dalam praktiknya, Anda memerlukan keduanya, dan masing-masing menjawab pertanyaan yang berbeda:
| Opsi | Mencakup | Nilai Umum | Melindungi dari |
|---|
--connect-timeout | | | |
| Jabat tangan DNS + TCP/TLS/QUIC | 3–10 detik | Host mati, paket terbuang, kegagalan DNS |
| --max-time
| Seluruh operasi | 10–60 detik, tergantung beban kerja | Respons lambat, transfer terhenti, aliran data tak berujung |
Secara keseluruhan:
curl --connect-timeout 5 -m 30 https://example.com
Lima detik untuk terhubung, tiga puluh detik untuk keseluruhan proses. Jika host tidak dapat dijangkau, Anda akan gagal dalam lima detik, bukan tiga puluh detik, yang sangat berpengaruh saat Anda mengiterasi daftar seribu URL.
Memilih Nilai yang Bukan Sekadar Tebakan
Pendekatan yang umum dilakukan adalah memilih angka bulat dan menaikkan nilainya setiap kali terjadi kegagalan. Hal ini akan mengarah pada nilai yang begitu besar sehingga batas waktu (timeout) tidak lagi berguna.
Metode yang lebih baik hanya memerlukan satu perintah tambahan. curl dapat melaporkan ke mana waktu tersebut sebenarnya terpakai: `
curl -o /dev/null -s -w "dns: %{time_namelookup}\nconnect: %{time_connect}\ntls: %{time_appconnect}\nttfb: %{time_starttransfer}\ntotal: %{time_total}\n" https://example.com
Jalankan perintah tersebut terhadap target Anda yang sebenarnya sebanyak dua puluh atau tiga puluh kali, dan Anda akan mendapatkan distribusi, bukan sekadar tebakan. Kemudian:
Tetapkan --connect-timeout dari time_appconnect. Ambil nilai p95 dan kalikan kira-kira dua kali lipat. Waktu koneksi didominasi oleh waktu bolak-balik jaringan dan relatif stabil; jika memakan waktu dua kali lipat dari biasanya, berarti ada masalah serius, bukan sekadar lambat.
Atur --max-time dari time_total. Di sini, faktor pengali sebaiknya lebih besar — tiga hingga lima kali nilai p95 — karena waktu total bergantung pada ukuran respons dan beban server, yang keduanya memang bervariasi. Nilai --max-time yang terlalu ketat akan menghasilkan skrip yang tidak stabil dan gagal pada hari-hari buruk biasa.
Dua penyesuaian khusus beban kerja. Jika Anda mengunduh file besar, --max-time sama sekali bukan alat yang tepat, karena unduhan yang sah dapat melebihi batas tetap yang wajar — gunakan opsi berbasis kecepatan di bawah ini sebagai gantinya. Dan jika Anda memanggil API yang melakukan pekerjaan nyata di sisi server, tanyakan berapa batas waktu (timeout) layanannya dan atur batas waktu Anda sedikit lebih tinggi; jika batas waktu Anda 10 detik sedangkan layanan tersebut mengembalikan respons dalam 12 detik, berarti Anda telah membayar biaya pemrosesan tetapi membuang hasilnya.
Desimal Detik dan Presisi Milidetik
Kedua opsi tersebut mendukung angka desimal, dengan menggunakan titik sebagai pemisah terlepas dari pengaturan wilayah Anda. Fitur ini telah didukung sejak curl 7.32.0.
curl --connect-timeout 0.5 -m 2.5 https://example.com
Setengah detik untuk terhubung, total dua setengah detik. Berguna untuk pemeriksaan kesehatan dan untuk loop apa pun di mana penambahan waktu tunggu satu detik penuh per kegagalan dapat menjadi signifikan.
Satu hal yang perlu diperhatikan: presisi akan menurun seiring bertambahnya nilai. Dokumentasi curl menyebutkan bahwa akurasi batas waktu aktual akan menurun seiring meningkatnya presisi desimal pada batas waktu yang ditentukan. Menulis --max-time 30.001 tidak jauh berbeda artinya dengan --max-time 30. Bilangan desimal digunakan untuk nilai di bawah satu detik; di atas beberapa detik, gunakan bilangan bulat.
Opsi terkait --expect100-timeout juga menerima nilai desimal. Opsi ini mengontrol berapa lama curl menunggu respons 100 Continue sebelum mengirim badan permintaan, dengan nilai default satu detik. Jika Anda mengirim badan permintaan besar melalui POST ke server yang tidak pernah mengirim 100 Continue, Anda akan menghabiskan satu detik pada setiap permintaan — kurangi nilainya atau nonaktifkan ekspektasi tersebut dengan -H "Expect:".
Mengatasi Transfer yang Terhenti dan Tidak Pernah Mencapai Batas Waktu
Inilah masalahnya. Transfer yang mengirimkan satu byte setiap beberapa detik tidak pernah dalam keadaan idle, sehingga batas waktu di tingkat koneksi tidak akan terpicu; dan jika nilai ``--max-time`
` diatur cukup tinggi untuk unduhan besar yang sah, batas waktu tersebut juga tidak akan terpicu. Permintaan tersebut hanya berjalan sangat lambat.
Opsi ``--speed-limit`
dan ``--speed-time
menangani hal ini. Dari manual: "Jika kecepatan unduhan lebih lambat dari ``--speed-limit
byte per detik selama periode ``--speed-time
`, transfer akan dihentikan."
curl --speed-limit 1000 --speed-time 30 -O https://example.com/large-file.zip
Jika throughput tetap di bawah 1000 byte per detik selama 30 detik berturut-turut, curl akan membatalkan proses — sekali lagi dengan kode keluar 28. Unduhan yang berjalan selama enam jam dengan kecepatan yang stabil tidak akan terpengaruh. Unduhan yang terhenti akan dihentikan dalam waktu tiga puluh detik.
Ini adalah batas waktu yang tepat untuk apa pun yang ukurannya tidak dapat diprediksi, dan pola ini bekerja dengan baik:
curl --connect-timeout 5 --speed-limit 1000 --speed-time 30 -O https://example.com/large-file.zip
Kegagalan cepat pada host yang mati, tanpa batasan keseluruhan, tetapi dilengkapi dengan detektor kemacetan sepanjang proses. Khusus untuk pengunduhan berkas, pola ini harus ada di setiap skrip — lihat panduan kami tentang mengunduh berkas dengan curl untuk opsi-opsi terkait.
Batas Waktu dan Upaya Ulang Berinteraksi dengan Buruk Secara Default
Inilah bagian yang sering membingungkan orang. Opsi `
--retry N
membuat curl mencoba kembali mengatasi kesalahan sementara hingga N kali. Yang mudah terlewatkan adalah bahwa opsi ``--max-time
` berlaku untuk setiap upaya, bukan untuk perintah secara keseluruhan, dan bahwa curl menunggu di antara upaya-upaya tersebut dengan penundaan eksponensial yang dimulai dari satu detik dan berlipat ganda.
Jadi, ini:
curl -m 10 --retry 5 https://example.com
bisa memakan waktu lebih dari satu menit: lima upaya masing-masing hingga sepuluh detik, ditambah jeda backoff selama 1, 2, 4, 8, dan 16 detik. Jika Anda menulisnya dengan mengharapkan batas waktu sepuluh detik, Anda salah perhitungan hingga enam kali lipat.
--retry-max-time
adalah solusinya. Ini membatasi total waktu yang dihabiskan untuk mencoba ulang:
curl -m 10 --retry 5 --retry-max-time 40 https://example.com
Sekarang curl berhenti memulai upaya baru setelah 40 detik berlalu. Perhatikan redaksinya — curl tidak akan memulai upaya ulang baru setelah batas tersebut, tetapi upaya yang sudah berjalan akan berlanjut hingga mencapai batas waktu (--max-time
) masing-masing. Skenario terburuk yang sebenarnya adalah --retry-max-time
ditambah satu --max-time
.
--retry-delay
mengganti penundaan eksponensial dengan waktu tunggu tetap, yang membuat total waktu eksekusi dapat diprediksi:
curl -m 10 --retry 3 --retry-delay 2 --retry-max-time 40 https://example.com
Satu lagi opsi yang perlu diketahui: secara default, --retry
hanya terpicu pada sekumpulan kondisi sementara yang terbatas. --retry-all-errors
memperluas cakupannya secara signifikan — manualnya menjelaskannya sebagai upaya ulang "semua kesalahan sementara termasuk kode respons FTP 4xx dan 5xx". Fitur ini benar-benar berguna dalam skrip yang beroperasi di jaringan yang tidak stabil, namun juga sangat berbahaya jika digunakan pada permintaan POST yang tidak idempoten. Pertimbangkan dengan matang sebelum mengaktifkannya.
Batas Waktu Saat Menggunakan Proksi
Tambahkan -x
dan pola waktu akan berubah, karena kini terdapat dua koneksi, bukan satu: koneksi Anda ke proksi, dan koneksi proksi ke tujuan.
curl -x http://user:pass@proxy.example.com:9000 --connect-timeout 10 -m 45 https://example.com
Ada tiga hal yang berperilaku berbeda dibandingkan saat koneksi langsung.
**--connect-timeout
mengukur waktu yang dibutuhkan untuk mencapai proksi, bukan waktu yang dibutuhkan proksi untuk mencapai tujuan.** Untuk HTTPS, curl mengirimkan permintaan "CONNECT
" dan proxy yang membangun koneksi lanjutan; waktu yang dibutuhkan dihitung sebagai bagian dari "--max-time
", bukan "--connect-timeout
". Oleh karena itu, waktu tunggu koneksi yang singkat tidak akan melindungi Anda dari proxy yang menerima koneksi Anda dengan cepat namun membutuhkan waktu dua puluh detik untuk mencapai target.
Proxy residensial memang lebih lambat, secara wajar. Lalu lintas keluar melalui koneksi konsumen yang sebenarnya, sehingga penambahan beberapa ratus milidetik adalah hal yang normal, bukan kesalahan. Nilai batas waktu yang disesuaikan untuk koneksi langsung akan menghasilkan kegagalan yang tampak seperti proxy rusak, padahal sebenarnya hanya karena faktor fisik. Ukur melalui proxy dengan perintah ``-w`
` di atas dan tetapkan nilai berdasarkan pengukuran tersebut, bukan berdasarkan angka koneksi langsung Anda.
Kegagalan bersifat ambigu. Kode keluar 28 melalui proxy bisa berarti proxy-nya lambat, targetnya lambat, atau target sengaja menunda permintaan Anda. Untuk membedakannya, Anda perlu menguji komponen-komponen tersebut secara terpisah, yang merupakan topik yang cukup luas sehingga kami menulis panduan terpisah tentang pengujian proxy.
Pola praktis untuk permintaan melalui proxy: waktu tunggu yang cukup lama (--connect-timeout
) (10 detik), waktu tunggu antar-upaya (--max-time
) yang ditetapkan berdasarkan perilaku yang terukur, bukan sekadar harapan, dan jangan gunakan waktu tunggu antar-upaya (--retry-all-errors
), karena melalui proxy, kode 5xx sering kali berarti target menolak Anda, bukan sedang mengalami masalah sementara, dan mencoba ulang hanya akan memperburuk situasi.
Membaca Kode Keluar
Kode keluar curl memberi tahu Anda tahap mana yang gagal, yang merupakan informasi lebih banyak daripada yang biasanya dimanfaatkan oleh kebanyakan skrip.
| Kode | Nama | Arti |
|---|
| 6 | CURLE_COULDNT_RESOLVE_HOST | DNS gagal — tidak ada batas waktu yang terlibat |
| 7 | CURLE_COULDNT_CONNECT | "Gagal melakukan connect() ke host atau proxy" |
| 28 | CURLE_OPERATION_TIMEDOUT | "Batas waktu yang ditentukan telah tercapai" |
| 56 | CURLE_RECV_ERROR | Kegagalan menerima data jaringan — koneksi terputus di tengah proses transfer |
Deskripsi diambil dari referensi kesalahan libcurl.
Perbedaan antara kode 7 dan 28 sangat berguna. Kode 7 berarti koneksi ditolak secara aktif — ada respons yang mengatakan "tidak" dengan cepat. Kode 28 berarti tidak ada respons yang diterima tepat waktu. Yang pertama biasanya menandakan port yang salah atau layanan yang ditutup; yang kedua menandakan paket yang terputus, firewall yang menyaring secara diam-diam, atau host yang benar-benar kelebihan beban. Mencoba kembali adalah langkah yang wajar untuk kode 28 dan biasanya tidak berguna untuk kode 7.
Dalam skrip:
curl --connect-timeout 5 -m 30 -sS https://example.com > out.txt
case $? in
0) echo "ok" ;;
6) echo "dns failure" ;;
7) echo "connection refused" ;;
28) echo "timed out" ;;
*) echo "other failure" ;;
esac
Perhatikan bahwa ketiga mekanisme batas waktu — --max-time, --connect-timeout, dan pasangan batas kecepatan — mengembalikan kode 28. Kode keluar tersebut memberitahu Anda bahwa batas telah tercapai, bukan batas mana yang tercapai. Jika Anda perlu mengetahuinya, gunakan -w "%{time_total}" dan bandingkan dengan nilai yang Anda konfigurasikan.
Kapan Tidak Perlu Menetapkan Batas Waktu
Meskipun bertentangan dengan saran umum, ada beberapa kasus di mana batas waktu bukanlah solusi yang tepat.
Unduhan interaktif. Jika Anda mengetik perintah curl di terminal untuk mengunduh berkas berukuran besar, Anda sendiri yang menentukan batas waktunya. Anda dapat melihat bilah kemajuan dan menekan Ctrl-C. Menambahkan -m di sini hanya akan menimbulkan ketidaknyamanan karena unduhan terhenti di 90%.
Aliran data yang berlangsung lama. Peristiwa yang dikirim server, pemantauan log secara real-time, respons bertahap yang dirancang untuk tetap terbuka — --max-time akan menghentikan aliran ini tepat pada saat yang salah. Gunakan --speed-limit dan --speed-time jika Anda memerlukan detektor kemacetan, atau jangan gunakan apa pun.
Apa pun yang sudah dibatasi oleh batasan eksternal. Jika curl berjalan di bawah timeout(1), unit systemd dengan RuntimeMaxSec, atau langkah CI dengan kuota sendiri, lapisan kedua hanya akan menambah angka kedua yang harus disinkronkan. Pilih lapisan yang menghasilkan pesan kesalahan yang ingin Anda baca dan atur di sana.
Sebagai solusi untuk target yang lambat. Batas waktu (timeout) membuat permintaan yang lambat gagal lebih cepat. Hal itu tidak membuatnya berhasil. Jika masalah sebenarnya adalah server membutuhkan 40 detik untuk merespons, opsi yang tersedia adalah caching, pagination, endpoint yang berbeda, atau berdiskusi dengan pihak yang mengelolanya — dan di sinilah kami akan mengulangi pernyataan penafian dari bagian atas, karena ini adalah masalah paling umum yang ingin diselesaikan orang dengan membeli proxy dan salah satu dari sedikit hal yang sama sekali tidak dapat diselesaikan oleh proxy. Harga kami mulai dari $0,79/GB untuk lalu lintas perumahan dan $0,14/GB untuk pusat data, diperiksa per September 2026, dan tidak ada satupun dari harga tersebut yang akan mempercepat server asal yang lambat.
Pertanyaan Lainnya
Berapa batas waktu default di curl?
Tidak ada batas waktu keseluruhan default — curl akan menunggu respons tanpa batas waktu setelah terhubung. Fase koneksi memang memiliki batas waktu default sebesar 300 detik. Inilah mengapa opsi -m penting dalam skrip: tanpa opsi ini, permintaan yang macet akan membuat skrip juga macet.
Apa perbedaan antara --max-time dan --connect-timeout?
--connect-timeout hanya mencakup resolusi DNS dan proses handshake TCP/TLS/QUIC, serta berhenti berlaku begitu koneksi terjalin. --max-time mencakup seluruh operasi dari awal hingga akhir, termasuk transfer respons. Gunakan keduanya — waktu tunggu koneksi yang singkat untuk kegagalan cepat pada host yang mati, dan waktu maksimum yang lebih lama sebagai batas atas keseluruhan.
Mengapa perintah curl saya memakan waktu lebih lama daripada batas waktu yang saya tetapkan?
Hampir selalu karena upaya ulang. --max-time berlaku per upaya, dan --retry menambahkan upaya tambahan serta penundaan eksponensial di antara upaya-upaya tersebut. Tambahkan --retry-max-time untuk membatasi totalnya, dan ingat bahwa skenario terburuk adalah nilai tersebut ditambah satu lagi --max-time.
Bagaimana cara mengatur batas waktu curl dalam milidetik?
Gunakan nilai desimal: --connect-timeout 0.25 setara dengan 250 milidetik. Baik --max-time maupun --connect-timeout menerima nilai desimal dengan pemisah titik, yang didukung sejak curl 7.32.0. Presisi terbaik dicapai pada nilai di bawah beberapa detik; untuk nilai yang lebih besar, akurasi bagian pecahan akan menurun.
Kode keluar apa yang dikembalikan oleh curl saat terjadi timeout?
28, CURLE_OPERATION_TIMEDOUT. Ketiga mekanisme timeout mengembalikan kode ini, sehingga kode tersebut menunjukkan bahwa batas telah tercapai, tetapi tidak menyebutkan mekanisme mana yang menyebabkan hal tersebut. Bandingkan dengan kode 7 (koneksi ditolak) dan 6 (kegagalan DNS), yang memiliki arti berbeda dan biasanya tidak boleh dicoba ulang.
Bagaimana cara menetapkan batas waktu untuk unduhan yang lambat tanpa menghentikan file berukuran besar?
Gunakan --speed-limit dan --speed-time alih-alih --max-time. Opsi ini hanya akan menghentikan unduhan jika throughput tetap di bawah ambang batas selama periode yang berkelanjutan, sehingga unduhan yang sah yang memakan waktu berjam-jam tidak terpengaruh, sementara unduhan yang macet akan segera dihentikan.
Apakah pengaturan batas waktu bekerja secara berbeda melalui proxy?
Ya. --connect-timeout hanya mengukur koneksi Anda ke proxy; koneksi lanjutan proxy ke target dihitung melalui --max-time. Proxy residensial juga menambah latensi yang nyata, sehingga nilai yang disesuaikan untuk koneksi langsung akan menghasilkan kegagalan palsu. Lakukan pengukuran melalui proxy dan atur nilai berdasarkan hasil tersebut.
Bisakah saya mengatur batas waktu hanya untuk resolusi DNS?
Tidak sebagai opsi terpisah — DNS sudah termasuk dalam --connect-timeout. Jika Anda memerlukan batasan khusus untuk DNS, lakukan resolusi secara terpisah dan kirimkan hasilnya dengan --resolve, yang sepenuhnya melewati proses pencarian DNS bawaan curl.
Kesimpulan
Ada dua opsi yang mencakup hampir semua kasus: --connect-timeout untuk kegagalan cepat saat host tidak dapat dijangkau, dan --max-time untuk batas maksimum secara keseluruhan. Atur keduanya, di setiap skrip, setiap saat. Pengaturan default yang menunggu selamanya merupakan pilihan yang wajar untuk alat interaktif, namun sangat buruk untuk otomatisasi.
Dua hal yang sering membuat orang kebingungan layak untuk diulang. --max-time berlaku per upaya, jadi setiap penggunaan --retry harus disertai dengan --retry-max-time; jika tidak, perintah sepuluh detik Anda akan berubah menjadi perintah satu menit. Dan batas waktu tetap bukanlah alat yang tepat untuk transfer berukuran tak terduga — gunakan --speed-limit bersama --speed-time, dan Anda akan mendapatkan detektor kemacetan yang tidak mengganggu unduhan panjang yang sah.
Tentukan nilai-nilai berdasarkan pengukuran, bukan dari angka bulat yang sekadar terasa tepat. Satu kali menjalankan curl -w terhadap target Anda yang sebenarnya akan memberikan distribusi, dan batas waktu yang diturunkan dari distribusi tersebut akan gagal hanya ketika ada masalah yang benar-benar serius, bukan sekadar saat jaringan sedang mengalami gangguan biasa.