Hijrah Backend (1): Hari Pertama Disodori Warisan 370+ Endpoint

10 September 2026 oleh Faiq Najib Al-Aziz


Cerita ini sebenarnya dimulai sebelum saya diterima kerja.

Di sebuah perusahaan GPS tracking di Surabaya, salah satu senior tim mendapat mandat me-rewrite sistem eksisting. Sampai hari ini saya tidak tahu persis apa yang dibicarakan di rapat internalnya; yang saya tahu hanya hasilnya: mereka memutuskan pindah ke Go. Dan baru setelah keputusan itu mantap, lowongan pun dibuka.

Jadi posisi saya di rekrutmen itu unik: saya tidak melamar sebuah pekerjaan, saya melamar sebuah keputusan yang sudah diambil orang lain hehe.

Di interview, pertanyaan utamanya wajar: bisa tidak, me-migrasi Laravel ke Go? Sempat ada tawaran tes, semacam “nanti kami tunjukkan contoh aplikasi kami, coba kerjakan dalam seminggu”. Tawaran itu akhirnya tidak jadi. Ya sudah, interview pun berjalan seperti biasa, dan saya diterima.

Lalu, entah kapan tepatnya lahirnya, ada satu kesepakatan yang sudah menunggu saya sejak sebelum hari pertama: para pengambil keputusan sepakat, proyek migrasi ini harus tuntas develop plus testing dalam tiga bulan.

Tiga bulan. Untuk 370+ endpoint.1

Angka itu lahir dari satu keyakinan yang terdengar masuk akal di rapat: migrasi Laravel ke Go itu cepat dan mudah, tinggal pindahin, dan hasilnya langsung siap pakai di production. Cukup export-import, kan? Yang belum sempat ditanya, kenapa satu-satunya orang di rapat yang paham pekerjaannya, yang tugasnya kan cukup mengiyakan, tidak menambahkan satu kalimat saja: “sebentar, ini beda kategori” hahaha.

Mari hitung bersama: itu sekitar empat endpoint per hari, tujuh hari seminggu, tanpa akhir pekan, tanpa libur nasional, dan tanpa waktu untuk bertanya “kok bisa ya semantap itu menetapkan angkanya?” hahaha. Angka yang indah di slide; kurang indah di keyboard hehe~

Nah, tulisan ini episode pertama dari seri Hijrah Backend: catatan personal perjalanan memindahkan backend GPS dari PHP ke Go, perjalanan yang tenggat aslinya sudah lama terbang entah ke planet mana. Kalau Anda cari versi teknisnya (kenapa Go, bagaimana pendekatannya, pelajaran apa yang didapat), itu sudah saya tulis di tulisan April kemarin. Seri ini isinya cerita di balik layar angka-angka itu: keputusan, kekeliruan, dan hal-hal yang tidak muat di catatan teknis hehe~

Struktur Pasukan (dan Proporsinya) #

Awal 2025, tim IT terbagi tiga: dua rekan merawat aplikasi eksisting, dua lagi membangun backoffice admin, dan satu sub-tim khusus migrasi. Sub-tim migrasi beranggotakan dua orang: satu senior yang menyandang mandat, dan satu saya.

Proporsi pengerjaannya, seperti mungkin sudah Anda duga dari nada tulisan ini, tidak sepenuhnya seimbang hahaha.

Dalam praktiknya, seluruh kode Go yang saya ceritakan di seri ini saya tulis sendiri. Kontribusi sang pemegang mandat lebih banyak ke arah menanyakan kabar: “kok error?”, “kok responsnya beda?”, “kok makin lemot? Go kan katanya lebih cepat?” Pertanyaan-pertanyaan itu sah-sah saja sebagai feedback. Hanya saja, sang penanya bukan orang yang membuka editor hehe~

Dan saat isu kecepatan itu ramai, saya sempat menimpali dengan satu catatan teknis: menyebutnya “migrasi Laravel ke Go” sebenarnya tidak apple to apple. Laravel itu framework, Go itu bahasa. Kalau mau adil membandingkan framework, bandingkan Laravel dengan CodeIgniter. Kalau mau adil membandingkan bahasa, bandingkan PHP native dengan Go native. Yang terjadi di mandat kami: mengambil bahasanya dari satu sisi dan framework-nya dari sisi lain, lalu menagih kecepatannya hehe.

Warisan yang Diterima #

Sistem yang saya terima terdiri dari dua dunia PHP yang hidup berdampingan.

Dunia pertama: API berbasis Laravel 8 dengan sekitar 290 endpoint, angkanya jadi 370+ kalau cron job ikut dihitung.1 Dunia kedua: aplikasi CodeIgniter 3 yang jadi pintu masuk data, TCP listener yang menerima paket dari puluhan tipe GPS tracker (Teltonika, GT06, JT808, dan puluhan kerabatnya), ditambah 100-an cron job yang mengolah data itu tiap malam.

Datanya juga tidak main-main. Puluhan ribu unit GPS yang live tracking, puluhan juta baris data lokasi dan alert, semuanya bermuara ke MySQL.

Dan gejalanya sudah terasa sejak minggu-minggu awal. Salah satunya di halaman dashboard estimasi bahan bakar per grup kendaraan. Untuk 30 kendaraan, halaman itu menjalankan ratusan query: ambil device, ambil tipe device-nya, lalu loop tujuh hari ambil ringkasan harian. Database-nya kerja rodi, user-nya nunggu sambil ngopi. Hadeh.

Masih ada lagi sih: endpoint yang bisa makan 15 detik sekali panggil. Tapi cerita lengkapnya, lengkap dengan semua hipotesis salah saya, saya simpan buat episode berikutnya. Stay tuned hehe.

Godaan Rewrite Total #

Dengan warisan segitu, godaan pertama yang datang itu manis sekali: “rewrite semuanya dari nol aja. Bersih, modern, enak dibaca.”

Amit-amit. Untung godaan itu saya tolak, setelah sempat tergiur sebentar, jujur. Rewrite total itu artinya berjudi dengan perilaku sistem yang selama ini dipercaya puluhan ribu user. Perilaku yang kadang aneh, kadang tidak terdokumentasi, tapi sudah jadi kenyataan sehari-hari mereka.

Jadi saya pilih jalan yang kurang glamor: parity-first, kode lama diperlakukan sebagai executable spec. Endpoint baru di Go harus berperilaku identik dengan yang lama, termasuk quirk-nya. Kecuali quirk yang jelas-jelas tidak dipakai frontend, itu dibersihkan sambil mikir dua kali. Perlahan, satu endpoint pada satu waktu, sambil sistem lama tetap melayani. Business as usual, gitu loh.

Keputusan ini yang paling menentukan arah semua episode ke depan. Dan detail kenapa parity-first itu justru menyelamatkan banyak waktu (plus contoh quirk yang bikin saya garuk-garuk kepala) saya bedah tuntas di episode keempat.

Peta Perjalanan #

Seri ini berisi delapan episode plus satu epilog. Kalau Anda baca tulisan ini dan episode selanjutnya sudah terbit, berarti semuanya tayang serentak sesuai rencana hehe:

  1. Anatomi endpoint 15 detik: perjalanan empat hipotesis salah sampai penyebab asli ketemu di tempat yang sama sekali tidak terduga.
  2. Mem-port puluhan parser protokol GPS: bagaimana mengganti kode yang membaca paket biner dari tracker bermerek-ragam, tanpa merusak data armada yang sudah jalan.
  3. Kode lama sebagai executable spec: parity-first lebih dalam: apa yang harus identik, apa yang boleh dibuang.
  4. Query yang bilang “pakai index-ku”: pelajaran sargable di tabel puluhan juta baris.
  5. Merapikan monolith jadi 14 modul domain: restrukturisasi sambil pesawatnya terbang.
  6. Dari paket TCP ke time-series database: bagaimana data lokasi berpindah dari listener sampai tersimpan rapi.
  7. Refleksi 18 bulan: yang akan saya lakukan beda kalau mengulang, plus satu rencana mengajar Go yang menunggu jadwal hehe.
  8. Epilog: MySQL, PostgreSQL, lalu MySQL lagi: kisah mesin database yang pindah haluan dua kali, dan siapa yang membayar ongkosnya.

Penutup #

Mandat yang menunggu saya sejak sebelum hari pertama itu tenggangnya tiga bulan. Saat tulisan ini disusun, perjalanan ini sudah jauh melampaui angka itu. Selisihnya bukan kelambanan; itu ukuran jarak antara angka di slide dan realita di keyboard. Dan sebagian besar jarak itu saya tempuh sendirian, dengan bantuan Allah, doa keluarga, dan dukungan istri saya. Tanpa semuanya, seri ini tidak akan ada.

Episode berikutnya kita masuk ke bagian yang paling sering ditanyakan: kok bisa sih satu endpoint makan 15 detik? Sampai ketemu di sana.

Terima kasih sudah tersasar ke sini dan membaca hehe. Semoga harimu menyenangkan!

Sekian. Salam.


  1. Sekitar 290 endpoint API di Laravel, plus 100-an cron job dan endpoint di aplikasi CodeIgniter 3. Angka “370+” yang saya pakai di tulisan April berasal dari jumlahan keduanya. ↩︎ ↩︎