North Star Arsitektur adalah prinsip keputusan yang membantu tim memilih bentuk sistem yang paling sesuai dengan kebutuhan nyata, bukan sekadar mengikuti tren seperti microservices atau event-driven. Sebelum memecah aplikasi menjadi banyak service, tim perlu tahu sistem ini sebenarnya sedang dioptimalkan untuk apa: kecepatan delivery, reliabilitas tinggi, isolasi kegagalan, skala traffic tertentu, atau koordinasi banyak tim.
Tanpa north star yang jelas, keputusan arsitektur mudah berubah menjadi chaos: boundary service dipilih terlalu cepat, observability meledak, deployment makin rumit, dan maintainability justru memburuk. Ide intinya sederhana: jangan mulai dari bentuk arsitektur, mulai dari constraint dan tujuan operasional sistem. Dari sana, baru tentukan apakah modular monolith, service terpisah, atau event-driven memang layak.
Apa itu “north star” arsitektur?
Dalam konteks engineering, north star arsitektur adalah seperangkat prioritas yang konsisten untuk memandu keputusan teknis harian. Ini bukan slogan abstrak, melainkan jawaban konkret untuk pertanyaan seperti:
- Apakah sistem harus memaksimalkan kecepatan perubahan atau stabilitas operasional?
- Apakah bottleneck terbesar ada di tim, traffic, reliabilitas, atau kompleksitas domain?
- Apakah organisasi mampu menanggung biaya tambahan dari distributed system?
Kerangka ini sejalan dengan pemikiran bahwa arsitektur yang baik bukan yang terlihat paling canggih, tetapi yang paling selaras dengan constraint sistem dan organisasi. Banyak tim terlalu cepat memilih microservices karena ingin “siap skala”, padahal masalah terbesarnya belum tentu skala teknis. Sering kali masalah sebenarnya adalah boundary domain yang belum matang, test coverage lemah, CI lambat, atau ownership tim belum jelas.
Catatan penting: Memilih arsitektur adalah memilih jenis masalah yang ingin Anda hadapi. Monolith punya masalahnya sendiri, tetapi distributed system menambah kategori masalah baru: network failure, retry, idempotency, tracing, schema evolution, dan koordinasi operasional lintas service.
Mulai dari pertanyaan yang benar, bukan dari pola arsitektur
Sebelum membandingkan modular monolith, service terpisah, dan event-driven, mulai dari lima sumbu evaluasi ini.
1. Ukuran dan struktur tim
Arsitektur harus sesuai dengan cara tim bekerja. Jika Anda punya 3-6 engineer backend yang masih sering menyentuh domain yang sama, memecah menjadi banyak service biasanya justru menambah friction. Tiap perubahan kecil berubah menjadi koordinasi antar-repo, antar-pipeline, antar-kontrak API, dan sering memerlukan sinkronisasi deployment.
Service terpisah mulai masuk akal saat ada beberapa tim yang benar-benar dapat memiliki domain berbeda dengan batas yang relatif stabil. Jika ownership masih cair, memecah terlalu cepat hanya memindahkan kompleksitas dari kode ke organisasi.
2. Pola traffic dan karakter beban
Jangan menilai skala hanya dari jumlah request. Yang lebih penting adalah bentuk traffic:
- Apakah beban dominan read-heavy atau write-heavy?
- Apakah ada lonjakan periodik, misalnya saat promo atau batch sinkronisasi?
- Apakah seluruh sistem tumbuh merata, atau hanya satu area seperti pencarian, pembayaran, atau notifikasi?
- Apakah latency antar-komponen sangat sensitif?
Jika bottleneck hanya ada pada satu modul, modular monolith masih bisa sehat dengan optimasi terarah: caching, background job, read replica, atau ekstraksi satu komponen yang benar-benar panas. Anda tidak perlu memecah seluruh sistem untuk satu hotspot.
3. Kebutuhan reliabilitas
Reliabilitas bukan sekadar uptime global. Anda perlu tahu:
- Bagian mana yang wajib sangat andal?
- Kegagalan seperti apa yang bisa ditoleransi?
- Apakah proses boleh asynchronous?
- Apakah operasi harus atomic lintas domain?
Monolith sering lebih sederhana untuk menjaga konsistensi transaksi karena banyak hal bisa dilakukan dalam satu boundary database. Begitu Anda masuk ke banyak service, transaksi lintas service menjadi jauh lebih sulit. Anda harus memilih antara eventual consistency, saga orchestration, kompensasi, atau desain ulang alur bisnis.
4. Batas anggaran operasional
Microservices bukan hanya biaya komputasi. Biaya utamanya sering muncul di operasional:
- lebih banyak pipeline CI/CD,
- lebih banyak dashboard dan alert,
- lebih banyak dependency runtime,
- lebih banyak titik kegagalan,
- lebih banyak effort on-call dan debugging.
Jika anggaran terbatas, pendekatan yang lebih sederhana biasanya memberi rasio nilai terhadap biaya yang lebih baik. Kompleksitas operasional adalah utang yang harus dibayar terus-menerus.
5. Kompleksitas domain
Domain yang benar-benar kompleks sering membutuhkan boundary yang jelas. Tetapi boundary yang belum dipahami biasanya belum layak dipisah. Jika tim masih sering memperdebatkan apakah fitur tertentu milik billing, order, atau customer, maka memecah service sekarang berisiko menghasilkan coupling lintas service yang buruk dan kontrak API yang terus berubah.
Dalam kondisi seperti ini, modular monolith biasanya lebih aman: domain tetap dipisah secara internal, tetapi refactor boundary masih murah karena semuanya berada dalam satu proses dan satu repositori.
Membandingkan pilihan: modular monolith, service terpisah, dan event-driven
Modular monolith
Modular monolith adalah aplikasi tunggal yang dibangun dengan boundary modul yang tegas. Semua berjalan dalam satu deployment unit, tetapi kode tidak dibiarkan bercampur bebas. Tiap modul punya API internal yang jelas, aturan dependency, dan idealnya ownership yang tegas.
Kapan cocok:
- tim masih kecil atau menengah,
- domain masih berkembang,
- butuh delivery cepat dengan overhead operasional rendah,
- konsistensi transaksi masih penting,
- belum ada alasan kuat untuk scaling independen per domain.
Keuntungan utama:
- refactor murah,
- debugging lebih mudah,
- deployment sederhana,
- observability lebih ringan,
- test end-to-end lebih langsung.
Kelemahan utama:
- risiko coupling internal jika disiplin boundary lemah,
- scale unit masih bersama-sama,
- satu proses bisa menjadi area blast radius yang lebih besar jika kualitas isolasi rendah.
Service terpisah
Service terpisah berarti domain atau kapabilitas tertentu dijalankan sebagai deployment unit mandiri, biasanya dengan API atau messaging sebagai mekanisme komunikasi.
Kapan cocok:
- ada domain dengan kebutuhan scaling, reliabilitas, atau lifecycle yang berbeda jelas,
- ada tim yang dapat benar-benar memiliki service secara mandiri,
- boundary domain relatif matang,
- organisasi siap mengelola observability dan operasional distributed system.
Keuntungan utama:
- isolasi deployment,
- scaling lebih selektif,
- ownership tim lebih jelas bila boundary tepat,
- blast radius bisa lebih kecil pada level tertentu.
Kelemahan utama:
- kompleksitas jaringan,
- latency dan failure mode baru,
- kontrak antar-service harus dikelola ketat,
- testing integrasi lebih mahal,
- debugging lintas service jauh lebih sulit.
Event-driven
Event-driven architecture cocok ketika sistem perlu loose coupling, pemrosesan asynchronous, atau integrasi banyak konsumen terhadap perubahan state. Namun event-driven bukan pengganti desain domain yang buruk. Ia hanya efektif bila event merepresentasikan fakta domain yang jelas dan stabil.
Kapan cocok:
- alur asynchronous memang natural,
- banyak downstream consumer membutuhkan notifikasi perubahan state,
- throughput dan decoupling lebih penting daripada respons sinkron langsung,
- tim siap mengelola idempotency, ordering, retry, dan observability event.
Keuntungan utama:
- decoupling waktu dan eksekusi,
- lebih mudah menambah consumer baru,
- bagus untuk workload background dan pipeline data operasional.
Kelemahan utama:
- alur sistem lebih sulit dipahami,
- debugging lebih kompleks,
- event schema evolution perlu disiplin,
- eventual consistency harus diterima di level bisnis.
Trade-off yang sering diremehkan
Biaya observability
Satu monolith dengan logging terstruktur, metrics dasar, dan tracing ringan sudah cukup untuk banyak tim. Saat beralih ke banyak service, kebutuhan observability meningkat drastis. Anda perlu correlation ID, distributed tracing, dashboard per service, alert yang tidak bising, dan kemampuan menelusuri request lintas boundary.
Jika observability belum matang, microservices sering membuat insiden lebih lama selesai karena gejala terlihat di satu service, akar masalahnya di service lain, dan kegagalan awalnya mungkin terjadi di message broker atau timeout jaringan.
Coupling tim vs coupling kode
Tim sering ingin mengurangi coupling kode dengan memecah service, tetapi tanpa sadar meningkatkan coupling organisasi. Perubahan satu flow bisnis bisa memerlukan perubahan serentak di tiga tim, tiga backlog, dan tiga jadwal deployment. Hasilnya, lead time justru naik.
Coupling tidak hilang; ia hanya berpindah tempat. North star yang baik membantu Anda memilih coupling yang paling murah untuk konteks saat ini.
Kecepatan delivery
Modular monolith sering menang untuk fase pertumbuhan produk karena perubahan lintas domain masih cepat dilakukan. Jika kebutuhan bisnis bergerak cepat dan domain masih dipelajari, biaya koordinasi antar-service bisa menghambat iterasi.
Service terpisah baru unggul ketika perubahan bisa benar-benar dipisahkan dan dilakukan paralel oleh tim berbeda tanpa saling menunggu terlalu sering.
Maintainability jangka panjang
Maintainability bukan berarti kode sekecil mungkin per service. Yang lebih penting adalah seberapa mudah sistem dipahami, diuji, dimodifikasi, dan dioperasikan. Sepuluh service kecil dengan boundary buruk bisa lebih sulit dipelihara dibanding satu modular monolith dengan dependency rule yang disiplin.
Kapan modular monolith lebih sehat daripada microservices?
Berikut pola yang sangat umum tetapi sering diabaikan:
- Tim backend masih kurang dari 8-10 engineer dan ownership domain belum stabil.
- Perubahan fitur sering menyentuh order, pembayaran, inventori, dan notifikasi sekaligus.
- Traffic naik, tetapi bottleneck nyata hanya pada satu atau dua workflow.
- Konsistensi transaksi masih kritikal untuk banyak use case inti.
- Tooling observability, contract testing, dan incident response belum matang.
- Budget operasional ketat dan tim platform belum ada.
Dalam situasi ini, memaksa microservices terlalu cepat biasanya menghasilkan:
- duplikasi model domain antar-service,
- API chatty dan coupling sinkron yang tinggi,
- banyak timeout dan retry yang sulit ditelusuri,
- antrian backlog karena perubahan lintas service harus dikordinasikan,
- lebih banyak pekerjaan operasional dibanding nilai bisnis yang dihasilkan.
Pendekatan yang lebih sehat adalah memperkuat modular monolith lebih dulu:
- Definisikan boundary modul berdasarkan domain, bukan layer teknis semata.
- Terapkan aturan dependency antar-modul.
- Pisahkan read model, background job, dan integrasi eksternal dengan jelas.
- Gunakan event internal atau outbox bila perlu, tanpa langsung memecah deployment.
- Ukur hotspot nyata sebelum mengekstrak service.
Contoh struktur modular monolith
Contoh berikut bukan template baku, tetapi menunjukkan bagaimana boundary bisa dijaga dalam satu aplikasi:
src/
modules/
order/
application/
domain/
infrastructure/
api/
billing/
application/
domain/
infrastructure/
api/
inventory/
application/
domain/
infrastructure/
api/
shared/
logging/
db/
messaging/
Poin pentingnya bukan nama folder, melainkan aturan bahwa modul order tidak langsung menyentuh detail internal billing. Akses dilakukan melalui interface atau API internal yang eksplisit. Dengan begitu, saat satu hari nanti billing perlu diekstrak menjadi service, boundary-nya sudah lebih siap.
Cara menurunkan north star ke keputusan engineering harian
1. Tulis prioritas arsitektur dalam bentuk yang bisa diuji
Hindari kalimat seperti “kita ingin scalable”. Tulis sebagai pernyataan operasional, misalnya:
- Kita memprioritaskan lead time perubahan fitur di atas scaling independen per domain untuk 12 bulan ke depan.
- Kita memprioritaskan konsistensi transaksi untuk order dan pembayaran inti.
- Kita menerima eventual consistency untuk notifikasi dan sinkronisasi analitik.
- Kita membatasi penambahan komponen operasional baru kecuali ada bottleneck terukur.
Pernyataan seperti ini dapat dipakai untuk menilai keputusan konkret, misalnya apakah perlu memecah service notifikasi, apakah perlu menambahkan broker, atau apakah cukup dengan job queue internal.
2. Gunakan ekstraksi service sebagai respons terhadap bukti, bukan dugaan
Ekstraksi service idealnya dilakukan ketika ada sinyal nyata, misalnya:
- deployment area tertentu terlalu sering mengganggu area lain,
- kebutuhan scaling sangat berbeda dan terus berulang,
- ownership tim sudah stabil dan terpisah,
- boundary domain cukup matang,
- profil reliabilitas modul berbeda signifikan.
Jika bukti ini belum ada, modular monolith yang rapi biasanya masih menjadi pilihan paling rasional.
3. Bedakan asynchronous processing dari event-driven architecture
Banyak tim mengira mereka harus mengadopsi event-driven penuh hanya karena ada proses background. Padahal kebutuhan awal bisa saja cukup dengan queue internal dan job worker. Ini memberi manfaat pemrosesan asynchronous tanpa langsung menambah kerumitan event contract publik dan consumer yang banyak.
Pola sederhana:
HTTP request -> simpan transaksi utama -> enqueue job -> worker kirim email / sinkronisasi non-kritis
Bukan langsung:
HTTP request -> publish banyak event -> beberapa consumer saling bergantung -> debugging jadi sulit
Pilih event-driven jika memang ada alasan domain dan operasional yang kuat, bukan karena “terlihat modern”.
4. Rancang observability sebelum memecah sistem
Jika Anda menuju service terpisah atau event-driven, siapkan minimal:
- request ID atau correlation ID,
- logging terstruktur yang konsisten,
- metrics per endpoint dan per dependency,
- trace lintas service bila memungkinkan,
- dashboard error rate, latency, queue depth, retry, dan dead-letter.
Tanpa ini, kemampuan tim untuk mengoperasikan sistem akan tertinggal jauh dari kompleksitas arsitektur yang dibangun.
Kerangka evaluasi praktis sebelum memilih pola arsitektur
Gunakan pertanyaan berikut dalam diskusi tim backend. Bukan untuk mendapat jawaban sempurna, tetapi untuk memaksa keputusan tetap berbasis konteks.
A. Ukuran tim
- Berapa engineer yang aktif menjaga backend?
- Apakah ada owner jelas per domain?
- Apakah perubahan lintas domain masih sering dan cepat?
B. Pola traffic
- Bagian mana yang benar-benar panas?
- Apakah bottleneck bisa diatasi dengan caching, queue, atau optimasi query?
- Apakah semua modul perlu scaling independen, atau hanya satu?
C. Reliabilitas
- Flow mana yang harus sinkron dan transactional?
- Flow mana yang aman dibuat asynchronous?
- Apa dampak bisnis jika satu domain terlambat memproses data beberapa detik atau menit?
D. Anggaran
- Apakah tim mampu menanggung biaya operasional tambahan?
- Apakah sudah ada tooling untuk tracing, alerting, dan contract testing?
- Apakah ada kapasitas on-call untuk banyak service?
E. Kompleksitas domain
- Apakah boundary domain sudah cukup stabil?
- Apakah model data sering berubah lintas area?
- Apakah tim paham event apa yang benar-benar merepresentasikan fakta domain?
Pola transisi yang lebih aman
Jika Anda yakin suatu saat perlu bergerak dari modular monolith ke service terpisah, lakukan transisi bertahap.
- Rapikan boundary internal lebih dulu. Ini mengurangi risiko mengekstrak service dari kode yang masih saling tergantung erat.
- Tambahkan interface eksplisit antar-modul. Jangan biarkan akses langsung ke tabel atau detail internal modul lain.
- Pisahkan proses asynchronous non-kritis. Gunakan queue untuk pekerjaan seperti email, webhook, sinkronisasi, atau indexing.
- Ukur bottleneck operasional. Lihat area mana yang paling sering menyebabkan insiden atau memperlambat deployment.
- Ekstrak satu service yang paling jelas kebutuhannya. Hindari big-bang migration.
Transisi bertahap biasanya lebih aman karena memberi umpan balik nyata. Jika ekstraksi pertama saja sudah menambah overhead besar tanpa manfaat jelas, itu sinyal bahwa north star Anda mungkin masih lebih cocok ke sistem yang sederhana.
Kesalahan umum
- Memilih microservices untuk “future-proofing”. Masa depan tidak pasti, sedangkan kompleksitas operasional harus dibayar sekarang.
- Menganggap event-driven otomatis lebih loosely coupled. Event bisa tetap sangat coupled bila schema dan alur bisnis tidak stabil.
- Menyamakan scaling dengan pemecahan service. Banyak masalah scale selesai dengan cache, queue, indexing, atau read replica.
- Mengabaikan biaya debugging. Sistem yang sulit ditelusuri akan memakan waktu engineer lebih banyak daripada yang diperkirakan.
- Memecah berdasarkan layer teknis, bukan domain. Service “user-service”, “api-service”, “db-service” tanpa boundary bisnis yang jelas biasanya berakhir buruk.
Checklist keputusan untuk tim backend
Gunakan checklist ini sebelum memutuskan arah utama sistem:
- Apakah north star arsitektur kami tertulis jelas dalam 3-5 prioritas operasional?
- Apakah masalah yang ingin diselesaikan adalah masalah nyata saat ini, bukan dugaan masa depan?
- Apakah ukuran tim dan ownership domain sudah mendukung service terpisah?
- Apakah boundary domain sudah cukup stabil untuk dijadikan kontrak antar-service?
- Apakah kebutuhan reliabilitas menuntut isolasi deployment atau cukup dengan modularisasi internal?
- Apakah eventual consistency dapat diterima untuk flow tertentu?
- Apakah bottleneck traffic benar-benar membutuhkan scaling independen?
- Apakah observability kami cukup matang untuk debugging lintas service atau lintas event?
- Apakah biaya operasional tambahan sebanding dengan manfaatnya?
- Apakah modular monolith yang disiplin masih bisa menyelesaikan 80% kebutuhan dengan risiko lebih rendah?
Jika banyak jawaban masih ragu, itu bukan tanda kegagalan. Justru itu sinyal bahwa modular monolith kemungkinan adalah pilihan paling sehat untuk saat ini. Arsitektur yang baik tidak ditentukan oleh seberapa banyak komponen yang dipakai, tetapi oleh seberapa tepat sistem tersebut membantu tim bergerak cepat tanpa kehilangan kendali.
Pada akhirnya, north star arsitektur bukan tentang memilih monolith atau microservices sebagai identitas. Ia adalah disiplin untuk terus bertanya: sistem ini sedang dioptimalkan untuk apa, dan apakah biaya kompleksitasnya sepadan? Jika tim bisa menjawab itu dengan jujur, keputusan engineering harian akan jauh lebih konsisten dan sistem dapat tumbuh tanpa chaos.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!