Kenapa Golang Cocok Buat Bikin Tools VPN dan Remote Desktop

Selain aplikasi desktop yang saya tulis pakai Avalonia/C#, sebagian besar logic networking di proyek-proyek saya justru saya tulis pakai Go. Bukan karena saya fanboy bahasa tertentu — lebih karena tiap kali saya coba bandingin langsung, Go yang paling gampang dipakai buat kasus penggunaan spesifik ini: koneksi banyak, harus reliable, dan harus gampang di-deploy ke mesin yang saya nggak kontrol penuh.
Goroutine bikin concurrency berasa “gratis”
Alasan paling konkret: goroutines dan channel bikin nulis kode yang handle banyak koneksi sekaligus — tunnel VPN, sesi remote desktop, atau sekadar proxy — jauh lebih gampang dibanding thread-based concurrency di bahasa lain. Saya pernah nyoba nulis prototype fitur serupa di C# pakai Task dan async/await biasa, dan secara fungsional sih jalan, tapi begitu jumlah koneksi simultan naik (waktu itu saya stress-test sampai sekitar 500 koneksi tiruan sekaligus), overhead thread pool .NET mulai kerasa, dan saya harus mulai mikirin SemaphoreSlim buat throttling manual. Versi Go-nya, dengan jumlah goroutine yang sama, nggak butuh tuning tambahan sama sekali — scheduler-nya emang didesain buat pola beban kerja kayak gini dari awal.
Single binary itu bukan fitur kecil
Go compile jadi satu binary tanpa dependency runtime tambahan. Buat tools yang perlu di-deploy ke berbagai environment client — kadang VPS Ubuntu lama, kadang Windows Server yang instalasinya dibatasi IT policy — ini penting banget. Nggak perlu mikirin lagi versi .NET runtime apa yang terpasang, atau nge-push installer yang gagal gara-gara dependency yang hilang. scp satu file, chmod +x, jalan.
Standard library yang udah “cukup” dari sononya
Standard library Go juga udah kuat banget buat networking — net, crypto/tls, sampai raw socket handling — jadi nggak perlu banyak dependency eksternal buat hal-hal dasar. Ini ngurangin attack surface, yang penting banget buat tools yang berurusan dengan koneksi aman kayak VPN. Setelah nulis beberapa checklist soal insiden supply-chain npm belakangan ini, saya makin sadar: makin sedikit dependency eksternal yang saya pasang di tools yang nyentuh koneksi sensitif, makin sedikit juga hal yang harus saya khawatirin kalau ada advisory baru muncul.
Trade-off yang beneran saya rasain
Error handling Go lumayan verbose — banyak if err != nil yang keulang di hampir tiap fungsi, dan awal-awal pindah dari C# yang punya exception, ini kerasa kayak mundur. Generics-nya juga masih relatif baru dibanding bahasa lain, jadi beberapa pola yang biasa saya pakai di C# (generic constraint yang kompleks) harus saya tulis ulang dengan cara yang lebih verbose atau pakai interface{}/any yang kurang type-safe.
Tapi buat kebutuhan networking tools yang butuh reliable dan gampang di-deploy ke mesin yang nggak selalu saya kontrol, Go tetap jadi pilihan pertama saya. Verbosity-nya itu harga yang saya rela bayar demi nggak harus mikirin runtime dependency tiap kali deploy ke server baru.