Apa Itu Trunk Based Development? Panduan Platform Engineer
Summary
Trunk based development berarti semua developer menggabungkan perubahan kecil ke satu branch bersama, minimal sekali sehari, dan menjaga branch itu tetap siap rilis. Model ini bekerja karena batch kecil membuat review lebih teliti dan konflik lebih mudah dikendalikan. Syaratnya: build dan test yang cepat, test yang andal, review yang tidak lambat, dan cara aman mengirim pekerjaan belum selesai lewat feature flag. Model ini tidak cocok untuk setiap tim.
Jam 3 pagi dan release branch tidak bisa di-merge. Empat puluh commit, sudah tiga minggu, dan menyentuh file yang sama dengan main. Rasa sakit seperti inilah alasan trunk based development ada. Lalu, apa itu trunk based development? Ini adalah model branching ketika semua developer menggabungkan perubahan kecil ke satu branch bersama, yang disebut trunk atau main, minimal sekali sehari, dan branch itu selalu dalam kondisi siap rilis.
Panduan ini ditujukan untuk platform engineer yang sudah paham Git. Isinya membahas apa yang dituntut model ini, apa yang ia lindungi dari Anda, dan di mana ia diam-diam gagal.
Apa itu trunk based development secara operasional?
Mari kita pangkas definisinya sampai tinggal batasannya. Semua developer terintegrasi ke satu branch. Branch lain hanya hidup hitungan jam, bukan minggu. Trunk harus lolos build dan test di setiap commit, sehingga kapan pun bisa dikirim ke produksi.
Halaman kapabilitas DORA memberi angka untuk ini: tidak lebih dari tiga branch aktif di repositori, merge ke trunk minimal sekali sehari, tanpa code freeze, dan siklus build serta test yang selesai dalam hitungan menit. Angka-angka itu justru intinya. Model ini adalah anggaran feedback loop, bukan preferensi gaya branching.

Tim kecil kadang commit langsung ke trunk. Tim yang lebih besar memakai branch berumur pendek dan pull request untuk review serta pengecekan build, tetapi tidak pernah untuk menahan pekerjaan dari integrasi. Referensi trunkbaseddevelopment.com membahas kedua mode ini dan menyebut Google, yang menjalankan sekitar 35.000 developer di satu trunk dalam sebuah monorepo.
Mengapa branch berumur panjang gagal sesuai jadwal yang bisa diprediksi
Feature branch itu seperti pinjaman. Bunganya berupa merge conflict, dan bunga itu berbunga setiap kali ada commit baru yang masuk ke main selama Anda pergi. Makin lama branch hidup, makin besar diff-nya, dan makin besar diff, makin kecil kemungkinan ada yang membacanya dengan teliti.
Ini berdampak langsung pada change failure rate Anda. Merge 2.000 baris hanya di-skim lalu di-approve. Merge 60 baris benar-benar dibaca. Reviewer bukan malas, mereka sedang membagi perhatian yang terbatas. Batch kecil adalah satu-satunya mekanisme yang bisa menjaga kualitas review tetap konsisten ketika tim membesar.
Biaya kedua tidak terlihat sampai saat rilis. Dua branch yang masing-masing lolos CI tetap bisa saling merusak ketika digabungkan. Anda baru tahu saat integrasi, momen terburuk, dengan tenggat yang sudah menempel.
Apa yang harus ada di trunk sebelum Anda bisa mempercayainya
Pindah ke trunk tanpa praktik pendukungnya adalah cara tercepat agar tim kembali ke feature branch dalam satu kuartal. Ada empat hal yang harus tersedia lebih dulu.
Build dan test yang selesai dalam sekitar sepuluh menit. Jika CI memakan 40 menit, developer akan membatch perubahan, dan batching menggagalkan model ini.
Test yang gagal karena alasan yang nyata. Suite yang flaky melatih orang untuk retry lalu tetap merge.
Proses review yang cepat dan jujur. DORA mencatat review kode yang berat dan asinkron sebagai hambatan umum, karena hal itu mendorong developer untuk membatch pekerjaan.
Cara yang aman untuk mengirim pekerjaan yang belum selesai. Ini dibahas di bagian berikutnya.
Lewatkan salah satu dari ini, dan trunk menjadi tempat kerusakan menumpuk, bukan tempat kerusakan tertangkap.
Bagaimana menggabungkan pekerjaan yang belum selesai tanpa mengirimkannya?
Ini pertanyaan yang selalu diajukan para skeptis, dan jawabannya membosankan: pisahkan deploy dari release. Kode sampai ke produksi dalam kondisi gelap. Sebuah flag yang memutuskan siapa yang melihatnya.
// checkout.ts
import { flags } from "./flags";
export async function renderCheckout(user: User) {
if (await flags.isEnabled("new-payment-flow", { userId: user.id })) {
return renderNewPaymentFlow(user); // sudah di-merge ke trunk, nonaktif secara default
}
return renderLegacyCheckout(user);
}Alur baru di-merge pada hari pertama, di balik flag yang nonaktif. Anda menyalakannya untuk pengguna internal, lalu 1 persen, lalu 10 persen, dengan gerbang SLO di setiap langkah. Jika error rate melewati anggaran, flag dimatikan dan perubahan efektif dibatalkan tanpa deploy. Tim yang mengevaluasi layanan flag terkelola sering memulai dengan LaunchDarkly, meski pola ini bisa dipakai dengan penyedia mana pun atau config store buatan sendiri.
Teknik kedua adalah branch by abstraction, untuk refactor besar. Anda memperkenalkan sebuah interface, mengarahkan pemanggil lewat interface itu, membangun implementasi baru di baliknya, lalu menukarnya ketika siap. Tidak ada branch berumur panjang, tidak ada merge big-bang.

Biaya yang jujur: flag adalah utang dengan masa paruh
Tidak ada yang mau membahas ini di konferensi. Setiap flag yang Anda tambahkan adalah kondisional di produksi yang harus dihapus oleh seseorang. Kami pernah melihat tim berisi 80 engineer membawa beberapa ratus flag usang, masing-masing menjadi cabang di kode yang tidak bisa diuji secara menyeluruh oleh siapa pun.
Perlakukan flag sebagai sesuatu yang berumur pendek, dan jadikan itu kontrak. Beri setiap flag seorang pemilik dan tanggal kedaluwarsa saat dibuat. Pasang alert untuk flag yang melewati masa berlakunya. Hapus jalur kode mati di pull request yang sama dengan penghapusan flag.
Risiko kombinatorialnya juga nyata. Sepuluh flag boolean independen menghasilkan 1.024 kemungkinan konfigurasi, dan Anda tidak akan pernah menguji semuanya. Jaga interaksi antarflag tetap sedikit, dan pisahkan release flag dari toggle operasional jangka panjang seperti kill switch.
Strategi rilis dan observabilitas di atas trunk
Ada dua cara umum untuk memotong rilis dari trunk, dan keduanya tidak membutuhkan branch berumur panjang.
Rilis langsung dari trunk. Setiap commit yang hijau adalah kandidat. Bug diperbaiki ke depan, dengan commit baru, bukan dengan menambal branch lama. Ini cocok untuk tim dengan test otomatis yang kuat dan deploy yang cepat.
Potong release branch tepat waktu. Anda membuat branch dari commit trunk yang sudah teruji, mengerasnya, merilis, lalu menghapusnya. Perbaikan masuk ke trunk dulu, lalu di-cherry-pick kembali. Ini cocok untuk tim dengan gerbang rilis yang lebih lambat atau persetujuan yang diatur regulasi.
Pilihan Anda bergantung pada detection time. Jika Anda bisa menyadari deploy yang buruk dalam lima menit dan membatalkannya dalam dua menit, perbaiki ke depan. Jika mean time to detect Anda satu jam, release branch memberi Anda pijakan.

Trunk based development menaikkan frekuensi deploy, dan itu menaikkan jumlah momen ketika sesuatu bisa rusak. Model ini hanya berhasil jika Anda bisa melihat regresi dalam hitungan menit setelah merge. Artinya error rate, persentil latensi, dan saturasi yang terikat pada rilis tertentu, bukan dashboard yang baru dicek seseorang hari Senin.
Tes sederhananya: setelah merge, bisakah Anda menjawab "apakah perubahan ini menggeser p99 atau error rate?" tanpa membuka lima tab? Jika tidak, Anda belum siap untuk merge sepuluh kali sehari.
Apa pun stack yang Anda pakai, syaratnya sama. Penanda deploy di grafik, alert burn-rate SLO, dan jalur revert yang bisa dijalankan oleh orang yang lelah pada jam 3 pagi tanpa perlu berpikir panjang.
Sinyal yang sama juga harus tersedia di jalur deploy Anda, termasuk pemeriksaan kesehatan setelah setiap rollout.
Trunk based development vs GitFlow vs GitHub Flow
Ketiganya sering tercampur, jadi pisahkan dengan satu properti: berapa lama pekerjaan tetap berada di luar branch bersama.
GitFlow memelihara branch develop, feature, release, dan hotfix. Pekerjaan bisa terisolasi selama berminggu-minggu. Model ini dirancang untuk rilis terjadwal dan berversi, dan kelemahannya terlihat ketika Anda ingin deploy sepuluh kali sehari.
GitHub Flow sangat dekat dengan trunk. Branch berumur pendek, pull request, merge ke main, lalu deploy. Perbedaan yang ditarik situs referensi sebagian besar soal asal rilis.
Trunk based development paling ketat dari ketiganya soal umur branch, dan ia mengandalkan feature flag atau branch by abstraction untuk apa pun yang tidak bisa dikirim dalam satu perubahan kecil.
Jika tim Anda sudah memakai GitHub Flow dengan branch yang hidup kurang dari dua hari, Anda lebih dekat ke trunk daripada yang Anda kira. Celahnya biasanya ada pada disiplin flag dan latensi review, bukan pada tooling.
Instrumentasikan metrik DORA ini sebelum mulai, atau Anda nanti akan berdebat berdasarkan perasaan. Deployment frequency dan lead time for changes bereaksi lebih dulu, karena batch yang lebih kecil mengalir lebih cepat melewati pipeline. Change failure rate dan time to restore menyusul, dan keduanya bergantung pada observabilitas serta jalur revert, bukan hanya pada model branching.
Jangan jadikan angka-angka ini rapor individu. Angka ini menggambarkan sistem. Ketika lead time naik, periksa antrean review dan durasi CI sebelum memeriksa orangnya.
Kapan trunk based development adalah pilihan yang salah, dan cara memulainya
Lewati model ini, atau setidaknya tunda, dalam beberapa kasus. Jujurlah tentang kasus mana yang sedang Anda hadapi.
Suite test Anda memakan satu jam dan tidak bisa diparalelkan. Anda akan membatch, dan batching merusak model.
Anda merilis artefak berversi ke pelanggan yang bertahan di versi lama selama bertahun-tahun. Anda membutuhkan maintenance branch. Itu sah, dan Anda tetap bisa berintegrasi setiap hari di trunk.
Anda tidak punya sistem flag dan tidak berniat membangunnya. Pekerjaan yang setengah jadi akan bocor ke rilis.
Tim Anda tidak percaya pada build. Perbaiki test dulu, karena trunk tidak akan menyelesaikannya.
Trunk based development juga bukan jaminan apa pun. Temuan DORA adalah korelasi dari data 2016 dan 2017, dengan tim yang menjalankan praktik ini menunjukkan performa pengiriman dan operasional yang lebih baik. Model ini tidak mengatakan bahwa mengganti nama branch akan memperbaiki pipeline Anda.
Jangan umumkan kebijakan dulu. Ukur, lalu persempit.
Catat umur branch saat ini dan ukuran median pull request. Ini baseline Anda.
Tetapkan batas, misalnya tidak ada branch yang lebih tua dari dua hari, dan tampilkan batas itu di dashboard.
Perbaiki bagian CI yang paling lambat. Jika build memakan 30 menit, tidak ada hal lain yang penting dulu.
Perkenalkan satu flag untuk satu fitur nyata. Kirim dalam kondisi gelap. Hapus flag itu dalam satu sprint.
Hilangkan code freeze paling akhir, setelah jalur revert pernah benar-benar diuji dalam kondisi nyata.
Tinjau ulang dalam sebulan. Angka yang biasanya bergerak lebih dulu adalah ukuran pull request dan waktu sampai merge. Change failure rate butuh waktu lebih lama, dan kadang memburuk sebelum membaik, karena Anda akhirnya melihat kerusakan lebih awal.
Apa yang akan dikatakan post-mortem Anda? Itu pertanyaan yang berguna sebelum Anda mengirim perubahan. Jika insiden terakhir berawal dari merge yang tidak sempat di-review, branch yang menyimpang selama tiga minggu, atau rilis yang membungkus empat puluh perubahan, Anda sudah tahu di mana utang itu akan jatuh tempo. Lihat tiga outage terakhir Anda. Berapa banyak yang melibatkan integrasi besar dan terlambat? Jumlah itu adalah business case Anda.