2 poin oleh GN⁺ 2025-07-07 | 1 komentar | Bagikan ke WhatsApp
  • Jake Gold menjalankan program CGI Go + SQLite pada AMD 3700X 16 thread untuk melihat sejauh mana CGI ala 1990-an dapat bertahan di hardware modern
  • Hasilnya menunjukkan bahwa bahkan dengan hardware biasa, CGI mampu memproses lebih dari 2.400 request per detik, atau lebih dari 200 juta request per hari
  • Karena CGI memulai, menjalankan, lalu mengakhiri proses untuk setiap request, overhead-nya dulu besar; untuk menguranginya, pendekatan seperti PHP dan FastCGI muncul
  • Pada 2020, Simon Willison menggunakan datasette-ripgrep untuk memproses pencarian dengan memanggil CLI ripgrep berbasis Rust, dan pengalamannya mengubah keyakinan lama bahwa menjalankan proses saat request web harus dihindari
  • Dengan bahasa yang cepat saat startup seperti Go dan Rust serta lingkungan multi-CPU, pemrosesan ala CGI bisa menjadi opsi yang lebih realistis dibanding dulu, meski bukan pendekatan yang umumnya direkomendasikan

Meninjau Ulang Performa CGI di Hardware Modern

  • Serving 200 million requests per day with a cgi-bin adalah tulisan Jake Gold yang menguji performa CGI ala 1990-an dengan program CGI Go + SQLite
  • Lingkungan pengujiannya adalah sistem berbasis AMD 3700X 16 thread
  • Hasil utamanya: bahkan dengan CGI, hardware biasa dapat memproses lebih dari 2.400 request per detik, atau lebih dari 200 juta request per hari
  • CGI bekerja dengan memulai proses terpisah untuk setiap request masuk, menjalankannya, lalu mengakhirinya
  • Untuk menghindari overhead ini, komunitas web awal membuat PHP dan FastCGI, yang menempatkan kode tetap di memori agar biaya tambahan berkurang

Mengapa CGI Mungkin Tidak Seburuk Dulu

  • Salah satu bottleneck CGI di masa lalu adalah skrip web ditulis dengan bahasa seperti Perl, Python, Java yang tidak dirancang dengan tujuan utama memiliki startup yang sangat cepat
  • Saat ini, dengan Go dan Rust, pemrosesan request bergaya CGI dapat berjalan jauh lebih efektif
  • Pada 2020, saat membuat datasette-ripgrep, Simon Willison menjalankan pencarian dengan memanggil tool CLI ripgrep yang ditulis dalam Rust melalui shell, dan memperoleh hasil yang baik
  • Karena program CGI berjalan sebagai proses terpisah, strukturnya juga dapat cocok untuk memanfaatkan banyak CPU
    • Server modern dapat memiliki 384 thread CPU
    • VM kecil pun dapat memiliki 16 CPU
    • Performa CPU dan memori juga jauh lebih cepat dibanding masa lalu
  • Cara menulis aplikasi web ala 1998 pun menjadi eksperimen yang menarik ketika bertemu Go dan Rust, tetapi bukan pilihan default yang sebaiknya diikuti sebagian besar layanan

1 komentar

 
GN⁺ 2025-07-07
Komentar Hacker News
  • Bahkan jika memakai sesuatu seperti Python, CGI saat ini cukup cepat
    Jika memulai skrip CGI memakan CPU 400ms dan server punya 64 core, itu berarti 160 request per detik, atau 14 juta hit per hari per server
    Jika sebuah layanan web kesulitan menangani beberapa juta request per hari di luar aset statis, bottleneck-nya bukan waktu startup proses CGI
    Dulu saya mungkin akan menyebutnya “teknologi membosankan yang sudah lama didukung di pustaka standar Python”, tetapi para maintainer Python yang tersisa tampaknya menganggap stabilitas dan kompatibilitas mundur sebagai sesuatu yang merugikan, dan terus menghapus modul yang terlalu membosankan dan stabil dari pustaka standar
    Modul cgi dihapus pada Python 3.13
    Saya sudah memakainya hampir setiap hari selama sebagian besar 25 tahun terakhir, jadi masih punya kebiasaan memakai Python untuk prototyping, tetapi sekarang rasanya disayangkan dan saya sedang bimbang antara JS dan Lua

    • Alasan penghapusan cgi ada di https://peps.python.org/pep-0594/#cgi
      Menariknya, di sana ditautkan https://peps.python.org/pep-0206/ dari 14 Juli 2000, yaitu 25 tahun lalu, dan bahkan saat itu paket cgi sudah digambarkan sebagai “dirancang dengan buruk dan sekarang hampir mustahil diperbaiki”
      Paket https://github.com/jackrosenthal/legacy-cgi tampaknya menyediakan pengganti drop-in untuk modul pustaka standar tersebut
    • Yang dihapus para maintainer Python adalah modul bernama cgi, bukan dukungan untuk implementasi skrip CGI itu sendiri
      Dukungan itu masih ada di CGIHTTPRequestHandler dalam modul http.server
      Yang ada di modul cgi hanyalah beberapa fungsi untuk mem-parsing data formulir HTML
    • Wajar kalau orang tidak senang Python menghapus CGI dari pustaka standarnya
      Tetapi saya kurang paham kalau alternatif berikutnya yang dipertimbangkan justru JS, yang bahkan tidak punya pustaka standar itu sendiri
      Lua juga tidak punya modul CGI di pustaka standarnya
    • Dulu web berperforma tinggi itu semacam seni teknis
      Sekarang lebih mirip mencari bagian yang benar-benar boros dan tidak masuk akal yang dimasukkan demi cepat rilis, lalu menghentikannya
      Jika dikerjakan dengan benar, aplikasi bisa jadi hampir tidak menambah latensi selain akses ke penyimpanan
    • Dalam kasus seperti ini saya lebih memilih PHP atau JS yang JIT-nya aktif secara default
      Saya belajar Python sejak 1.6, tetapi selama ini lebih banyak memakainya untuk scripting sistem operasi
      Pada 1999~2003 saya memakai Tcl di modul Apache dan IIS, lalu terus menulis ulang modulnya dalam C, dan terlalu banyak pelajaran yang saya pelajari dengan susah payah
  • Baru-baru ini saya menguji binary Golang, RabbitMQ, Redis, dan MySQL semuanya di mesin mini server seharga 350 dolar, dan itu mampu menangani 5.000 request per detik secara berkelanjutan
    Kalau dihitung 24 jam sehari, itu berarti 400 juta request
    Luar biasa melihat betapa bagusnya alat-alat gratis saat ini, dan sekaligus luar biasa bahwa kita tetap membayar penyedia cloud begitu banyak uang
    Ini memang bukan perbandingan yang benar-benar setara, tetapi saya sangat menikmati proses mengembangkan dan men-tuning semuanya sendiri di perangkat yang ada di ruang bawah tanah

    • Saya terlalu sering melihat orang tidak sadar bahwa server bisa menangani jauh lebih dari 1 request per detik, lalu malah menerapkan monster microservice Kubernetes yang memperlambat kecepatan pengembangan 10 kali lipat
      Aneh bahwa orang terus menerima overhead seperti ini tanpa alasan selain “karena Google juga melakukannya”
      Saya benar-benar harus menulis tentang arsitektur monolit modular yang kami pakai dengan baik
    • Sebenarnya tidak wajib membayar penyedia cloud
      Anda bisa menyewa server dedicated dari perusahaan hosting dan memakainya sesuka hati, hanya saja biasanya sangat dibatasi oleh bandwidth atau kuota transfer
      Saya paham kenapa cloud dipakai: ada banyak kepentingan di situ. Misalnya VC dan investor juga punya saham di perusahaan cloud, dan mereka takut investasi gagal gara-gara lonjakan trafik imajiner yang sebenarnya tidak akan pernah datang
      Tim penjualan cloud sangat piawai memainkan kecemasan investor
    • Saya pernah mempertimbangkan meng-host side project di ruang bawah tanah, tetapi itu membuatnya rentan terhadap listrik padam dan gangguan ISP
      Kalau drive rusak saat saya sedang bepergian, habislah sudah, dan kalau saya tidak sengaja menguncinya, saya bahkan tidak punya terminal serial cadangan untuk fallback
      Saya bisa saja menyiapkannya seperti orang-orang di r/homelab, tetapi kalau begitu juga belum jelas apakah benar-benar menghemat uang, terutama kalau waktu saya sendiri ikut dihitung
      Pada akhirnya saya melihat penyedia cloud sebagai transaksi yang cukup bagus berkat skala ekonominya
    • Kalau melihat biaya VM, tingginya bukan karena komputasinya besar, melainkan karena saya butuh server dengan banyak disk lokal
      Anehnya, saya tidak bisa mendapatkan itu saja secara terpisah
      Bayangkan seberapa besar bisnis atau layanan yang bisa dijalankan hanya dengan 4 drive 20TB dan CPU yang lumayan
      Tidak mudah mendapatkan konfigurasi seperti itu dari penyedia cloud
  • Bagian yang mengatakan “komunitas web awal cepat belajar bahwa ini ide buruk lalu menemukan teknologi seperti PHP” secara teknis inti teknologinya adalah mod_php
    PHP sendiri tidak berbeda dari Perl dalam cara eksekusinya, tetapi berkat pilihan desain mod_php dibanding mod_perl, skrip PHP bisa berjalan cepat hanya dengan dilempar begitu saja ke server, sedangkan mod_perl butuh sedikit pemikiran dan sihir agar bisa bekerja

    • Pada masa itu saya dan seorang teman sedang mengembangkan sesuatu yang belakangan akan disebut sistem manajemen pembelajaran
      Ada manajemen konten, unggah tugas, kalender acara, manajemen nilai, chat real-time, forum, dan semuanya dibuat dalam C murni di atas CGI, dan rasanya seperti neraka untuk dikerjakan
      Hari ketika saya menemukan PHP saya hampir menangis, karena semua hal yang sebelumnya harus saya bangun dari nol dengan susah payah sambil membaca RFC atau merekayasa balik HTTP, di PHP ternyata cuma berupa pemanggilan fungsi sederhana
      Saya tidak perlu lagi men-debug implementasi urlencode yang amburadul atau kehilangan satu hari hanya karena satu carriage return aneh di header HTTP
    • Betul, tetapi mod_php ditambahkan ke ekosistem PHP sejak awal dan dengan cepat menjadi cara deployment default
      Sepertinya versi pertama modul Apache itu adalah untuk PHP/FI Version 2.0 pada 1996: https://www.php.net/manual/phpfi2.php#module
  • Jika cgi-bin perlu mengakses DB, koneksi harus dibuka setiap kali proses dimulai
    Menyimpan kode tetap berada di memori seperti FastCGI bukan hanya untuk menghindari biaya waktu startup, tetapi juga karena bisa memiliki pool koneksi DB atau setidaknya koneksi persisten per thread

    • Saat skala membesar, database akan kewalahan karena jumlah koneksi
      Hal itu terjadi ketika “Python itu single-threaded, jadi mari jalankan banyak instance” dan “Python itu lambat, jadi mari jalankan banyak instance” dilakukan bersamaan
      Pada skala besar, pada akhirnya harus memakai pool koneksi bersama di luar Python seperti pgbouncer dan banyak tuning agar bisa menangani beban tanpa membunuh DB
      Tentu saja setelah itu, ketika diimplementasikan ulang dalam bahasa multithread dengan performa yang lumayan, semuanya kembali menjadi sangat sederhana
    • Karena itu, CGI pada akhirnya berevolusi menjadi model yang mempertahankan sebagian state di antara request
    • Ada juga cara standar untuk menanganinya
      Pada dasarnya dengan menjalankan daemon terpisah yang berperan seperti proxy
      Jika memakai socket Unix alih-alih TCP/IP, biaya koneksi relatif lebih rendah
    • Pakai UDP saja
  • Jika di hardware ini aplikasi hello world hanya mampu 2.400 request per detik, bukankah itu agak buruk
    Saya juga tidak paham, dengan mengorbankan performa, tepatnya apa yang didapat. Kodenya juga tidak jadi lebih sederhana

    • Itu hanya angka buruk jika memang harus melewati 2.000 request per detik
      Situs seperti itu hanya sebagian kecil dari keseluruhan
    • Memang tidak hebat, tetapi cukup untuk banyak kasus penggunaan
      Sepertinya bahkan bisa menahan ledakan trafik HN
  • Ini juga sudah dibahas kemarin: https://news.ycombinator.com/item?id=44464272

  • Di perusahaan, kami kadang masih menyajikan direktori cgi-bin untuk aplikasi web internal yang perlu dibuat cepat
    Menjaganya tetap sederhana membuatnya nyaman digunakan
    CGI tidak berarti Anda harus langsung print HTTP/1.0 ke stdout
    Misalnya, dengan Python bawaan wsgiref.handlers.CGIHandler, aplikasi WSGI apa pun bisa dijalankan sebagai skrip CGI
    import wsgiref.handlers, flask
    app = flask.Flask(name)
    wsgiref.handlers.CGIHandler().run(app)
    Kami menjalankan skrip dengan uwsgi dan plugin CGI-nya[1]
    Rasanya lebih sederhana dan fleksibel daripada menjalankan Apache atau lighttpd hanya karena mod_cgi
    Karena uwsgi dijalankan sebagai unit systemd, kami juga bisa memanfaatkan penuh fitur hardening dan sandboxing dari systemd
    Salah satu hal praktis pada penanganan CGI di uwsgi yang tidak ada di mod_cgi adalah Anda bisa menentukan interpreter untuk format file tertentu
    cgi = /cgi-bin=/webapps/cgi-bin/src
    cgi-allowed-ext = .py
    cgi-helper = .py=/webapps/cgi-bin/venv/bin/python3 # all dependencies go here
    Waktu sampai byte pertama adalah 250~350ms, dan itu bisa diterima untuk kebutuhan kami
    [1]: https://uwsgi-docs.readthedocs.io/en/latest/CGI.html

    • Info yang bagus, dan wsgiref.handlers.CGIHandler tampaknya masih belum dijadwalkan untuk deprecated
  • Saya baru-baru ini memakai Apache untuk proyek sampingan, dan salah satu alasannya adalah fitur .htaccess, jadi kami sempat membahas hal serupa
    Anda bisa meletakkan file .htaccess di mana saja dan Apache akan membacanya sebagai konfigurasi server tambahan pada setiap request: https://httpd.apache.org/docs/2.4/howto/htaccess.html
    Alasan besar dulu untuk menghindarinya adalah performa. Setiap request memerlukan akses disk tambahan, dan kalau memungkinkan selalu lebih baik menaruhnya di file konfigurasi utama
    Tetapi sekarang sebagian besar server memakai SSD, dan kemungkinan Linux juga punya RAM luang untuk dipakai sebagai cache file system
    Tentu saja performanya masih sedikit lebih buruk karena Apache harus me-parse konfigurasi pada setiap request, bukan hanya sekali
    Meski begitu, melihat CPU server modern yang jauh lebih kuat, untuk banyak kasus penggunaan hal itu masih bisa ditoleransi
    Proyek sampingan itu masih sangat awal, tetapi sudah dipakai: https://github.com/StaticPatch/StaticPatch/tree/main

    • Mengutip kata-kata Rasmus Lerdorf:
      “Saya bukan programmer sungguhan. Saya hanya mencoba-coba sampai berhasil lalu lanjut. Programmer sungguhan akan berkata, ‘Ya, ini memang jalan, tapi ada kebocoran memori di mana-mana. Mungkin harus diperbaiki?’ Saya cukup me-restart Apache setiap 10 request.”
      Sejak itu PHP sudah berkembang sangat jauh, tetapi sebagian besar perjalanan itu adalah proses memperbaiki kesalahan awal
      “Alasan PHP 8 jauh lebih baik adalah karena kode saya di dalamnya jauh lebih sedikit.”
    • Saya tidak paham kenapa Apache tidak sekalian memantau file system saja
      Karena pilihan ini, 99,99% request HTTP jadi melambat akibat pembacaan disk yang sebenarnya tidak perlu
  • Saya jadi lebih sering memikirkan ini sebagai bagian dari alur kerja pembuatan prototipe cepat
    Bahasa JIT modern tampaknya waktu start-up-nya akan sebagian besar didominasi oleh import, kecuali jika memakai model FastCGI
    Saya mulai memikirkan ini setelah mulai memakai web server h2o untuk skrip lokal; dengan mruby dan handler FastCGI, file konfigurasi bisa ditulis dengan rapi dan cepat, dan kinerjanya juga sangat cepat: https://h2o.examp1e.net/configure/fastcgi_directives.html
    Kegunaan lain yang bermanfaat adalah ketika pelanggan memperluas perangkat lunak lokal dengan kode mereka sendiri
    Misalnya, alih-alih menyuruh mereka memakai MCP untuk memperluas alat AI, kita bisa meminta mereka mengimplementasikan struktur permintaan tertentu dengan CGI

    • Frontend MCP untuk program CGI di lingkungan pengguna akhir bukan ide yang buruk
      Saya jadi penasaran apakah layanan MCP itu sendiri juga bisa diimplementasikan dengan CGI
      Framework MCP mungkin juga bisa mengekspos fungsionalitas dalam bentuk program yang mendukung kedua mode eksekusi
      Saya perlu menggali spesifikasinya lebih jauh
    • FastCGI cenderung kehilangan hampir semua kelebihan CGI
  • Bagi saya, inetd itulah CGI
    Itu membuat internet jauh lebih menyenangkan
    Saya sendiri pernah meng-host berbagai skrip shell lewat inetd, dan bahkan punya server HTTP yang sepenuhnya ditulis dalam Bash
    VPS itu sudah lama hilang, dan waktu itu saya juga belum memakai version control
    Laptop tempat saya menulisnya pun sudah tidak ada
    Tapi tetap saja, itu sangat menyenangkan
    Deploy semudah Makefile + scp, dan pengujiannya adalah skrip Bash lain yang mencampurkan beberapa netcat dan grep
    Benar-benar masa yang indah