Ada momen di mana saya berhenti ngetik, lean back di kursi, dan sadar: “Ini bukan lagi soal refactor.”
Waktu itu saya lagi nge-debug satu bug di sistem GPS tracker yang sudah jalan bertahun-tahun1. Bug-nya simple — laporan posisi kendaraan tidak update di dashboard. Tapi untuk memperbaikinya, saya harus trace lewat empat file berbeda, dua layer business logic yang nyangkut satu sama lain, dan satu query yang ditulis tanpa index. Satu jam kemudian, fix-nya cuma dua baris. Dua baris.
Bukan bug-nya yang bikin saya berpikir ulang. Tapi waktu yang dibutuhkan untuk menemukan dua baris itu. Rasanya seperti mencari jarum di tumpukan jerami, tapi jarumnya ternyata ada di kantong celana sendiri hehe~
Nganu, tulisan ini bukan tentang bahasa pemrograman tertentu atau solusi teknis tertentu. Ini catatan pribadi tentang proses berpikir di balik keputusan migrasi tech stack — kapan saatnya, kapan belum, dan bagaimana saya menilainya dari sisi yang bukan cuma teknis. Soalnya sering banget kan denger diskusi teknis yang ujung-ujungnya jadi debat bahasa pemrograman A vs B, padahal masalahnya bukan di situ hahaha.
Kondisi Sistem Saat Itu #
Proyek GPS tracker yang saya tangani bukan proyek kecil. Angkanya kurang lebih begini:
- 370+ API endpoint yang melayani berbagai kebutuhan — dari real-time tracking sampai report generation
- 33 database entity yang saling berhubungan
- ~194.000 baris kode yang sudah ditulis bertahun-tahun oleh beberapa developer2
Tapi angka-angka itu sebenarnya bukan masalahnya. Ya ampun, jumlah baris kode itu memang terlihat banyak, tapi percaya deh itu bukan yang bikin pusing. Masalahnya ada di gejala-gejala yang muncul:
1. Fitur Baru yang Seharusnya Cepat, Jadi Lambat #
Fitur yang dulu bisa dikirim dalam dua hari, sekarang butuh dua minggu. Bukan karena developer-nya lambat — tapi karena setiap perubahan berdampak ke bagian yang tidak terduga. Satu field baru di satu entity bisa merambat ke lima file berbeda.
Dari sisi bisnis, ini berarti kecepatan deliver value ke user menurun. Fitur yang client minta makin lama datang, dan jendela kompetitif makin mengecil.
2. Bug yang Hanya Muncul di Production #
Kalau di lokal aman, tapi di production error — dimana harusnya saya cari? (pertanyaan yang sering bikin saya begadang sambil scrolling Stack Overflow hahaha)
Ini classic symptom dari sistem yang tightly coupled. Kode yang berjalan di satu environment tidak berjalan sama di environment lain karena ada side effect yang tidak terduga. Debug-nya bukan soal logika — tapi soal mengapa konteks production berbeda dari ekspektasi. Pernah waktu itu saya sampai remote ke server production jam 2 pagi cuma buat check satu environment variable yang ternyata… memang belum di-set. Facepalm.
Dari sisi bisnis, ini artinya tidak ada kepastian. Client bisa get laporan yang salah di pagi hari, dan tidak ada yang tahu kenapa sampai siang.
3. Onboarding Developer Baru Makin Lama #
Dulu, developer baru bisa mulai contribute dalam seminggu. Saat itu, butuh hampir sebulan baru mereka nyaman ngode tanpa takut merusak sesuatu. Bukan karena mereka kurang skill — tapi karena codebase butuh context yang banyak untuk dipahami. Saya masih ingat ekspresi salah satu developer baru waktu dia baru pertama kali buka codebase-nya. Mukanya… yah, seperti orang yang baru bangun tidur terus langsung disuruh lari marathon hehe~
Dari sisi bisnis, ini berarti biaya menambah kapasitas tim meningkat. Setiap developer baru butuh waktu lebih lama sebelum jadi produktif.
4. Fear Setiap Deploy #
Setiap kali mau deploy, ada feeling “semoga kali ini tidak ada yang break”. Bukan karena tidak ada testing — tapi karena testing yang ada tidak cover semua edge case. Dan di sistem yang tightly coupled, satu perubahan kecil bisa punya efek domino. Seperti menarik satu benang di sweater, eh taunya yang lain ikut rontok juga. Deploy di hari Jumat sore? Amit-amit jabang bayi, jangan sampai hahaha.
Dari sisi bisnis, ini artinya tim jadi konservatif. Fitur yang sebenarnya aman ditunda karena takut efek sampingnya. Inovasi melambat bukan karena kurang ide, tapi karena takut break.
Pertanyaan-Pertanyaan yang Saya Ajukan #
Setelah sadar bahwa gejala-gejala di atas bukan normal, saya mulai mengajukan pertanyaan-pertanyaan ini ke diri saya sendiri. Bukan pertanyaan teknis — tapi pertanyaan yang membantu saya memahami apakah masalahnya bisa diselesaikan tanpa migrasi.
“Apakah Masalahnya di Tool atau di Cara Kita Pakai?” #
Ini pertanyaan pertama dan paling penting. Kalau masalahnya cara kita menulis kode — misalnya, tidak ada layering, tidak ada testing, tidak ada code review — maka migrasi tech stack tidak akan menyelesaikan apa-apa. Kita cuma pindah masalah ke tool baru.
Dalam kasus GPS tracker ini, jawabannya: keduanya. Cara kode ditulis memang perlu diperbaiki — tapi bahasa dan framework yang dipakai juga punya limitation yang membuat penulisan kode yang clean jadi lebih sulit dari seharusnya. Dynamically typed language3 tanpa enforcement di runtime membuat bug type-related muncul di production, bukan saat development. Dan bug type-related di production itu… hadeh, bikin hati dag-dig-dug setiap kali ada notifikasi error hehe.
“Kalau Kita Refactor Saja, Apakah Cukup?” #
Pertanyaan kedua: kalau kita invest waktu untuk merapikan arsitektur di tech stack yang ada, apakah hasilnya sepadan?
Di kasus ini, saya calculate kasar: untuk refactor 370+ endpoint dengan arsitektur yang proper di PHP, butuh waktu yang hampir sama dengan migrasi ke stack baru. Bedanya, kalau refactor di PHP, kita tetap stuck dengan beberapa limitation fundamental (type safety, concurrency, deployment complexity). Kalau migrasi, kita unlock hal-hal baru.
Tapi ini kasus saya, ya. Bukan berarti refactor selalu salah. Kalau sistemnya lebih kecil, atau kalau limitation stack-nya tidak terlalu menghambat, refactor adalah pilihan yang jauh lebih bijak. Jangan sampai karena baca tulisan ini terus langsung migrasi semua sistem tanpa pikir panjang. Nanti malah jadi seperti cerita horor yang pernah saya dengar — 2 tahun migrasi, eh akhirnya balik lagi ke sistem lama hahaha.
“Berapa Biaya dari TIDAK Melakukan Apa-apa?” #
Ini pertanyaan yang sering luput. Kita sering hitung biaya migrasi — waktu, uang, risiko — tapi jarang hitung biaya dari tetap stagnan.
Dalam kasus GPS tracker:
- Fitur yang makin lambat dikirim = client mungkin pindah ke kompetitor
- Bug yang muncul di production = trust client menurun
- Onboarding yang makin lama = biaya rekrutmen efektif meningkat
- Fear saat deploy = inovasi melambat
Kalau total biaya inaction dalam satu tahun melebihi estimasi biaya migrasi — secara bisnis, keputusannya cukup jelas.
“Apakah Tim Kita Bisa Menangani Migrasi?” #
Migrasi tech stack butuh skill baru. Tim harus belajar stack yang mungkin belum familiar. Ada ramp-up time. Ada mistakes yang pasti terjadi.
Pertanyaannya bukan “bisakah?” tapi “apakah kita punya ruang untuk melakukannya?” Kalau tim sudah overwhelmed dengan deadline dan bug fix, migrasi hanya akan menambah beban. Tapi kalau ada window — entah itu antar proyek, atau saat kapasitas sedang cukup — itu saat yang tepat untuk mulai.
Dalam kasus saya, kami tidak migrasi semua sekaligus. Kami mulai dari satu module, satu endpoint pada satu waktu — sambil tetap menjalankan business as usual. Pelan-pelan asal kenceng, begitu kata teman saya hehe. Detail teknisnya ada di catatan migrasi saya yang lain.
“Kapan Kita Tahu Migrasi Itu Berhasil?” #
Kalau kita tidak punya definisi “berhasil”, kita tidak bisa tahu kapan harus berhenti. Untuk saya, success criteria-nya:
- Fitur baru bisa dikirim lebih cepat dari sebelumnya
- Bug production berkurang secara terukur
- Developer baru bisa onboard lebih cepat
- Deploy tidak lagi ditakuti
Kalau setelah migrasi, angka-angka ini membaik — maka migrasi berhasil. Kalau tidak — maka kita perlu evaluasi ulang.
Kerangka Berpikir: Bukan Soal Bahasa, Soal Momentum #
Setelah melewati proses tanya-jawab di atas, saya menyimpulkan kerangka berpikir sederhana: tiga kondisi yang harus dipenuhi sebelum migrasi masuk akal.
1. Masalahnya Struktural, Bukan Masalah Skill #
Kalau masalahnya cuma “kita belum paham cara pakai tool ini dengan baik” — maka solusinya belajar, bukan pindah. Migrasi cuma masuk akal ketika arsitektur sistem itu sendiri yang menjadi penghambat, bukan kemampuan tim.
2. Biaya Inaction Sudah Terukur dan Nyata #
Bukan feeling “kayaknya sih makin lambat” — tapi data. Fitur yang dulu 2 hari sekarang 2 minggu. Bug production naik 30% dalam 6 bulan. Onboarding makan 4 minggu bukan 1 minggu. Kalau datanya tidak ada, kumpulkan dulu. Jangan migrasi berdasarkan assumption.
3. Tim Punya Kapasitas untuk Menjalankan #
Migrasi butuh waktu, energi, dan fokus. Kalau tim sedang di peak season, atau kalau tidak ada budget untuk learning curve, lebih baik tunda. Migrasi yang force di waktu yang salah bisa lebih merusak daripada codebase yang legacy.
Kalau ketiga kondisi terpenuhi: migrasi masuk akal. Kalau satu saja tidak terpenuhi: lebih baik refactor, atau tahan dulu sampai kondisinya mendukung.
Keputusan dan Apa yang Terjadi #
Saya memutuskan untuk migrasi. Bukan keputusan dalam semalam — tapi proses beberapa minggu setelah mengumpulkan data dan berdiskusi dengan tim. Ada moment di mana saya sempat ragu juga sih, “Apa beneran harus migrasi? Apa nggak cukup di-refactor aja?” Tapi setelah melihat datanya, ya udah, keputusan diambil.
Hasilnya? Alhamdulillah. Fitur baru yang dulu butuh dua minggu sekarang bisa dikirim dalam hitungan hari. Bug production menurun. Onboarding developer baru lebih cepat. Dan yang paling penting: deploy tidak lagi ditakuti. Sekarang deploy di hari Jumat sore pun… yah, masih agak deg-degan sih, tapi nggak separah dulu hahaha.
Untuk detail teknis bagaimana migrasi dilakukan — pendekatan per-module, pattern yang dipakai, dan pelajaran teknisnya — ada di catatan terpisah yang saya tulis khusus untuk sisi implementasinya.
Pelajaran #
1. Kumpulkan Data Dulu, Keputusan Kemudian #
Jangan migrasi karena “kayaknya sih butuh” atau karena tech stack baru lagi trending4. Kumpulkan datanya — berapa lama fitur baru dikirim, berapa sering bug muncul, berapa lama onboarding. Kalau datanya mendukung, keputusannya jauh lebih mudah dijual ke stakeholder. Percayalah, bilang ke atasan “kita harus migrasi karena Go itu keren” itu nggak akan berhasil. Tapi kalau bilang “fitur yang dulu 2 hari sekarang 2 minggu, ini datanya”, baru deh ngobrol hehe.
2. Migrasi Itu Keputusan Bisnis, Bukan Cuma Teknis #
Sering kali diskusi migrasi stuck di “bahasa A lebih baik dari bahasa B”. Padahal pertanyaan yang seharusnya diajukan: “apakah tech stack saat ini masih memungkinkan kita deliver value dengan kecepatan yang dibutuhkan?” Kalau jawabannya tidak — maka saatnya bicara migrasi. Soalnya kan tujuan akhirnya bikin produk yang berguna buat user, bukan menang debat di forum online hahaha.
3. Refactor vs Migrasi Bukan Binary #
Bukan pilihan antara “refactor semua” atau “migrasi semua”. Kadang jawabannya refactor dulu, kemudian migrasi bertahap. Kadang jawabannya refactor saja sudah cukup. Konteks dan skala sistem menentukan. Life is not always black and white, begitu juga dengan keputusan teknis hehe~
4. Hitung Juga Biaya Tidak Berbuat Apa-apa #
Kita sering fokus pada “berapa biaya migrasi” dan lupa bertanya “berapa biaya kalau kita tidak migrasi?” Kadang, biaya tetap diam jauh lebih mahal dalam jangka panjang. Seperti kata pepatah, “kalau sakit gigi, mending langsung ke dokter gigi daripada nahan-nahan sampai parah”. Eh, ada pepatah kayak gitu nggak sih? Yah, pokoknya kalian paham maksud saya hahaha.
Penutup #
Keputusan migrasi tech stack itu personal — tergantung pada konteks, tim, timeline, dan banyak faktor lain. Tidak ada framework yang bisa menjawab semua situasi. Tapi dengan mengajukan pertanyaan yang tepat dan mengumpulkan data yang cukup, keputusan yang diambil jauh lebih sound daripada mengikuti hype.
Semoga catatan ini bermanfaat buat yang lagi galau mau migrasi atau nggak. Kalau kamu sedang menghadapi dilema serupa dan ingin mendiskusikannya, hubungi saya. Atau lihat layanan yang bisa saya bantu.
Tag: catatan · arsitektur · migration
-
Sistem GPS tracker yang sudah berjalan sejak beberapa tahun lalu, dengan berbagai penambahan fitur dan patch di sana-sini. ↩︎
-
Banyak developer yang datang dan pergi selama bertahun-tahun. Masing-masing punya gaya coding sendiri. Jadinya… yah, mixed styles hehe. ↩︎
-
Bukan berarti dynamically typed language itu jelek, ya. Cuma untuk kasus tertentu, static typing bisa sangat membantu. ↩︎
-
FOMO (Fear of Missing Out) dalam dunia tech itu nyata. Tapi jangan sampai keputusan teknis diambil cuma karena takut ketinggalan trend. ↩︎