Arsitektur Microservices vs Monolith

Setiap beberapa bulan muncul tren baru: "perusahaan besar memakai microservices, jadi kita juga harus." Padahal sebagian besar aplikasi bisnis, termasuk sistem kasir, absensi, dan...

Arsitektur Microservices vs Monolith

Setiap beberapa bulan muncul tren baru: "perusahaan besar memakai microservices, jadi kita juga harus." Padahal sebagian besar aplikasi bisnis, termasuk sistem kasir, absensi, dan booking, berjalan baik sebagai satu aplikasi Laravel yang rapi. Artikel ini membantu Anda memutuskan berdasarkan kondisi tim dan beban nyata, bukan berdasarkan kesan modern.

Dua Istilah, Dijelaskan Tanpa Jargon

Monolith

Seluruh fitur berada dalam satu basis kode dan satu proses deploy. Modul pelanggan, produk, pembayaran, dan laporan berbagi database yang sama. Satu git push dan seluruh aplikasi diperbarui. Laravel standar adalah monolith.

Microservices

Aplikasi dipecah menjadi layanan-layanan kecil yang masing-masing punya kode, database, dan deploy sendiri, lalu saling berbicara lewat API atau antrean pesan. Layanan pembayaran bisa memakai bahasa dan skala berbeda dari layanan notifikasi.

Perbandingan yang Jujur

AspekMonolithMicroservices
Kecepatan membangun awalCepatLambat (butuh infrastruktur dulu)
DebuggingSatu log, satu stack traceHarus menelusuri request lintas layanan
Transaksi dataMudah, satu databaseSulit, konsistensi harus dirancang
Skala per fiturSeluruh aplikasi diskalakan bersamaTiap layanan diskalakan sendiri
Biaya serverRendahTinggi (banyak proses, gateway, monitoring)
Kebutuhan timSatu orang bisa menguasai semuaBeberapa tim dengan kontrak antarlayanan
Risiko utamaKode berantakan seiring waktuKompleksitas operasional

Kenapa Microservices Sering Menjadi Kesalahan Awal

Memecah layanan memindahkan kompleksitas dari kode ke jaringan. Panggilan fungsi yang dulu selesai dalam mikrodetik kini menjadi request HTTP yang bisa lambat, timeout, atau gagal sebagian. Anda perlu menangani retry, versi API, trace terdistribusi, dan deploy yang harus kompatibel satu sama lain.

Contoh sederhana. Di monolith, membuat pesanan lalu mengurangi stok cukup satu transaksi database:

DB::transaction(function () use ($data) {
    $pesanan = Pesanan::create($data);
    Produk::whereKey($data['produk_id'])->decrement('stok', $data['qty']);
});

Jika pesanan dan stok berada di dua layanan berbeda, tidak ada transaksi tunggal. Bila layanan stok gagal setelah pesanan tersimpan, Anda butuh mekanisme kompensasi (saga) untuk membatalkannya. Itu pekerjaan tambahan yang besar untuk manfaat yang belum tentu Anda perlukan.

Jalan Tengah: Modular Monolith

Untuk kebanyakan tim kecil, pilihan terbaik adalah tetap satu aplikasi tetapi dengan batas modul yang tegas. Kode dikelompokkan per domain, bukan per jenis file:

app/
  Modules/
    Pesanan/
      Models/
      Actions/
      Http/Controllers/
      Events/
    Pembayaran/
      Models/
      Actions/
      Http/Controllers/
    Laporan/
      ...

Aturannya sederhana:

  • Modul tidak boleh langsung membaca tabel modul lain. Komunikasi lewat kelas Action atau event publik.
  • Satu modul punya kelas pintu masuk yang jelas, misalnya BuatPesanan::jalankan().
  • Gunakan event untuk efek samping lintas modul, bukan pemanggilan langsung.
// Modul Pembayaran mengabari yang lain tanpa saling ketergantungan
event(new PembayaranBerhasil($pesananId));

// Modul Pesanan mendengarkan
Event::listen(PembayaranBerhasil::class, TandaiPesananLunas::class);

Dengan pola ini Anda mendapat batas yang rapi hari ini, dan bila suatu saat modul tertentu memang harus dipisah, kode sudah terisolasi sehingga ekstraksinya jauh lebih mudah.

Sinyal Bahwa Sudah Waktunya Memecah

Pertimbangkan memisahkan sebuah modul menjadi layanan sendiri hanya jika beberapa kondisi ini benar sekaligus:

  1. Satu bagian punya kebutuhan skala yang sangat berbeda, misalnya pemrosesan gambar yang menghabiskan CPU sementara bagian lain ringan.
  2. Ada beberapa tim yang sering saling menghambat saat deploy karena berbagi satu kode.
  3. Bagian itu butuh teknologi berbeda yang tidak cocok dengan PHP.
  4. Anda sudah punya monitoring, CI/CD, dan kemampuan operasional untuk mengelola banyak layanan.

Jika jawabannya "belum", teruskan dengan monolith dan optimalkan lewat cache, queue, dan indeks database yang tepat.

Contoh Kasus: Aplikasi Kasir yang Tumbuh

Bayangkan aplikasi kasir untuk satu toko yang kemudian dipakai tiga puluh cabang. Di awal, semua fitur berada dalam satu aplikasi Laravel: transaksi, stok, pelanggan, dan laporan. Tiga masalah biasanya muncul berurutan, dan masing-masing punya obat yang berbeda.

Laporan membuat halaman kasir melambat

Query laporan bulanan yang berat berjalan pada database yang sama dengan transaksi. Obatnya bukan microservices. Pindahkan pembuatan laporan ke job queue, simpan hasilnya ke tabel ringkasan, dan tampilkan dari sana. Pemakai kasir tidak lagi menunggu query panjang.

Cetak struk dan kirim WhatsApp menahan respons

Efek samping seperti kirim notifikasi cukup dijalankan sebagai listener yang di-queue. Respons ke kasir selesai lebih dulu, dan pengiriman dilakukan di belakang layar. Tidak ada layanan baru yang perlu dibangun.

Cabang butuh sinkronisasi dengan sistem akuntansi lain

Di sinilah batas yang jelas menolong. Karena modul Pembayaran sudah punya Action dan event publik, Anda cukup menambahkan endpoint API read-only atau webhook di monolith yang sama. Bila suatu hari volume integrasi membengkak, modul itulah yang paling mudah dipisahkan karena ketergantungannya sudah terdokumentasi lewat event.

Perhatikan bahwa dalam ketiga kasus, masalah selesai dengan teknik yang sudah ada di Laravel. Microservices baru benar-benar masuk akal jika queue, cache, dan modularisasi sudah dipakai habis dan hambatan masih ada.

Biaya Tersembunyi yang Perlu Dihitung

  • Infrastruktur: setiap layanan butuh proses, konfigurasi, dan sertifikatnya sendiri. Tagihan server cepat bertambah.
  • Observabilitas: Anda butuh log terpusat dan trace antarlayanan, jika tidak, mencari penyebab error menjadi tebak-tebakan.
  • Pengembangan lokal: menjalankan semua layanan di laptop memerlukan Docker Compose dan sumber daya yang cukup.
  • Pengujian: test integrasi lintas layanan lebih lambat dan lebih rapuh daripada test di dalam satu aplikasi.
  • Onboarding: anggota tim baru harus memahami banyak repositori sekaligus.

Jika biaya-biaya ini belum sebanding dengan masalah yang ingin diselesaikan, tetap pada monolith yang modular adalah keputusan teknis yang sehat, bukan kemunduran.

Langkah Pengambilan Keputusan

  • Tim kurang dari sepuluh orang dan satu produk: modular monolith.
  • Satu fitur berat (laporan, media, AI): jalankan sebagai job queue atau worker terpisah dulu, belum perlu layanan penuh.
  • Butuh integrasi dengan sistem lain: sediakan API dari monolith, tidak perlu memecah seluruh aplikasi.
  • Ragu: mulai monolith. Memecah monolith yang sehat jauh lebih mudah daripada menyatukan microservices yang salah potong.
Ingin langsung mempraktikkannya?

Buat akun gratis untuk mengunduh contoh aplikasi Laravel, menyimpan tutorial favorit, dan mencoba kursus. Gratis, bisa daftar dengan akun Google.

Daftar Gratis Lihat katalog aplikasi
Yudhi
Ditulis oleh
Yudhi
Founder & Lead Developer, GudangCode

Yudhi adalah founder GudangCode dan developer Laravel dengan pengalaman membangun puluhan sistem informasi bisnis siap pakai — mulai dari POS, HRIS, hingga aplikasi manajemen. Ia menulis panduan dan artikel di GudangCode untuk membantu developer Indonesia menjalankan, memahami, dan men-deploy source code Laravel dengan benar.

Laravel PHP MySQL Sistem Informasi Bisnis
Lihat semua artikel Yudhi
Microservices Monolith Teknologi & Development
Bacaan Paling Dicari
📚 Free Learning Hub

Learn Coding for Free at DhieCoderWeb

Explore Laravel, PHP, JavaScript tutorials, source code, web development guides, and practical programming tips.

DhieCoderWeb
100+
Tutorials
Free
Learning
SEO
Tips
Visit Dhiecoderweb.com →