Jawaban singkatnya: untuk banyak produk yang masih bertumbuh, modular monolith biasanya adalah pilihan paling waras. Microservice masuk akal ketika batas domain sudah jelas, tim sudah terpisah, dan bottleneck memang tidak bisa lagi diselesaikan di dalam satu deployment. Self-hosted AI layak dipertimbangkan ketika kontrol data, biaya inferensi jangka panjang, dan kemandirian stack lebih penting daripada kenyamanan API pihak ketiga.

Tren seperti “Open source AI must win” relevan bukan karena slogan, tetapi karena memaksa tim engineering berpikir lebih serius tentang vendor lock-in, kontrol biaya, dan kepemilikan jalur operasional. Namun, kemandirian stack juga berarti Anda ikut menanggung beban deployment, observability, keamanan, dan kapasitas operasional. Karena itu, keputusan arsitektur harus dibuat berdasarkan bentuk produk, ukuran tim, pola trafik, sensitivitas data, dan kemampuan menjalankan sistem dalam produksi.

Masalah yang Sebenarnya: Bukan Soal Tren, tapi Soal Biaya Koordinasi

Banyak tim terlalu cepat pindah ke microservice karena mengira scaling selalu identik dengan memecah aplikasi. Di sisi lain, ada juga yang terlalu lama bertahan dengan monolith yang tidak modular sampai perubahan kecil pun berisiko merusak area lain. Untuk AI, pola yang sama muncul: memakai API vendor itu cepat, tetapi bisa mahal dan sulit diprediksi; self-hosting memberi kontrol lebih besar, tetapi menambah kompleksitas operasional.

Pertanyaan yang lebih tepat bukan “arsitektur mana yang terbaik?”, melainkan:

  • Di mana bottleneck utama saat ini: deploy, database, latency, throughput, atau koordinasi antar tim?
  • Apakah masalah itu benar-benar struktural, atau masih bisa diselesaikan dengan perbaikan desain modul, caching, queue, dan observability?
  • Apakah kebutuhan AI Anda cukup kritis sehingga kontrol terhadap model, data, dan biaya inferensi layak diambil alih sendiri?

Pilihan 1: Modular Monolith untuk Mayoritas Produk yang Baru Bertumbuh

Modular monolith adalah aplikasi tunggal yang dijalankan sebagai satu deployable unit, tetapi kode dan dependensinya dipisah secara disiplin berdasarkan domain atau modul. Ini berbeda dengan monolith yang berantakan. Tujuannya bukan sekadar “satu repo”, tetapi batas internal yang jelas.

Kapan modular monolith paling masuk akal

  • Tim masih kecil sampai menengah, misalnya satu tim produk atau beberapa engineer yang masih sering menyentuh area yang sama.
  • Domain bisnis belum stabil dan masih sering berubah.
  • Deployment masih bisa ditoleransi sebagai satu unit.
  • Bottleneck utama belum terbukti berasal dari arsitektur tunggal.
  • Anda ingin menjaga kompleksitas operasional tetap rendah.

Kenapa pendekatan ini sering lebih waras

  • Lebih mudah di-debug: alur request masih lokal, tanpa hop antar service yang memperumit tracing.
  • Lebih sederhana untuk deployment: satu pipeline, satu artefak, satu rollback path.
  • Konsistensi data lebih mudah: transaksi database lokal biasanya lebih sederhana dibanding sinkronisasi lintas service.
  • Biaya observability lebih rendah: logging, metrics, dan tracing belum tersebar ke banyak komponen.

Trade-off modular monolith

  • Scaling masih cenderung satu unit, meski beberapa bottleneck bisa dibantu dengan cache, queue, atau worker terpisah.
  • Jika boundary modul buruk, tim akan saling mengganggu di codebase yang sama.
  • Database tunggal dapat menjadi bottleneck organisasi dan teknis bila semua domain saling tergantung.

Praktik yang membuat monolith tetap sehat

  • Pisahkan domain ke modul yang jelas: misalnya billing, catalog, auth, analytics.
  • Larangan akses tabel lintas modul secara bebas. Gunakan service layer atau interface internal.
  • Pakai event internal atau queue untuk pekerjaan asinkron seperti email, indexing, dan notifikasi.
  • Buat test per modul dan kontrak internal agar refactor tidak merusak area lain.
// Contoh struktur modular monolith yang lebih sehat
/src
  /modules
    /auth
      application/
      domain/
      infrastructure/
      api/
    /billing
      application/
      domain/
      infrastructure/
      api/
    /ai
      application/
      providers/
      api/
  /shared
    logging/
    db/
    queue/

Struktur seperti ini membantu karena jika suatu hari modul ai atau billing perlu dipisah menjadi service sendiri, Anda sudah punya boundary yang lebih realistis.

Pilihan 2: Microservice jika Masalah Anda Memang Sudah Lintas Tim dan Lintas Beban

Microservice bukan solusi universal. Ia efektif jika memecahkan masalah nyata: kebutuhan scaling yang berbeda antar domain, kecepatan deploy tim yang independen, atau isolasi kegagalan yang tidak bisa dicapai secara memadai dalam monolith.

Sinyal kuat bahwa Anda mulai perlu memecah service

  • Satu deployment terlalu berisiko dan terlalu sering menghambat banyak tim.
  • Profil scaling antar domain berbeda jauh, misalnya pencarian atau AI inference jauh lebih berat daripada CRUD admin.
  • Domain dan ownership tim sudah cukup stabil.
  • Ketergantungan kode antar domain sudah bisa diputus dengan kontrak API atau event.
  • Kegagalan pada satu area tidak boleh menjatuhkan area lain.

Trade-off teknis microservice yang sering diremehkan

  • Observability wajib matang: tanpa distributed tracing, korelasi log, dan metrics per service, debugging akan jauh lebih sulit.
  • Data consistency menjadi lebih rumit: transaksi lintas service biasanya berubah menjadi pola eventual consistency.
  • Deployment bertambah kompleks: lebih banyak pipeline, artefak, environment variable, secret, dan rollback scenario.
  • Latensi jaringan nyata: panggilan lokal berubah menjadi RPC/HTTP dengan timeout, retry, idempotency, dan potensi partial failure.
  • Biaya koordinasi meningkat: API contract, versioning, backward compatibility, dan ownership service harus dikelola secara disiplin.

Contoh keputusan pemecahan yang masuk akal

Misalnya Anda punya produk SaaS dengan modul:

  • Auth dan user management
  • Billing dan subscription
  • Core transaction workflow
  • Document processing berbasis AI

Jika beban terbesar ada di document processing berbasis AI, jangan buru-buru memecah semuanya. Sangat mungkin yang paling masuk akal adalah:

  • Core app tetap modular monolith
  • AI processing dipisah menjadi worker/service tersendiri
  • Komunikasi memakai queue atau job system, bukan request sinkron untuk semua kasus

Pendekatan ini mengisolasi beban berat tanpa memaksa seluruh organisasi pindah ke arsitektur terdistribusi penuh.

Pola implementasi yang lebih aman daripada “langsung pecah semua”

  1. Rapikan boundary di monolith terlebih dulu.
  2. Identifikasi modul dengan kebutuhan scaling atau dependency yang unik.
  3. Pisahkan yang paling jelas nilai bisnis dan operasionalnya, biasanya worker, search, media processing, atau AI inference.
  4. Tetapkan kontrak API/event yang sempit dan stabil.
  5. Tambahkan observability sebelum menambah service berikutnya.

Pilihan 3: Self-Hosted/Open-Source AI saat Kontrol Lebih Penting daripada Kenyamanan

Self-hosted AI berarti Anda menjalankan model dan komponen AI sendiri, baik di server on-premise, VM, Kubernetes, maupun GPU provider yang Anda kendalikan. Ini bisa mencakup model inferensi, embedding service, vector database, pipeline retrieval, dan komponen orkestrasi internal.

Dalam konteks open source AI, inti pertimbangannya adalah: apakah nilai dari kontrol dan kemandirian stack lebih besar daripada biaya menjalankannya?

Kapan self-hosted AI masuk akal

  • Data sensitif: dokumen internal, data pelanggan, kontrak, PII, atau data yang tidak boleh keluar ke vendor eksternal.
  • Biaya inferensi jangka panjang: volume request cukup besar sehingga biaya API eksternal mulai sulit diprediksi atau terlalu tinggi.
  • Kebutuhan customisasi: Anda butuh model, prompt pipeline, atau retrieval stack yang lebih dapat diatur.
  • Ketahanan terhadap vendor lock-in: Anda ingin bebas pindah model atau penyedia infrastruktur tanpa mengubah seluruh aplikasi.
  • Kebutuhan latency lokal tertentu: misalnya inferensi dekat dengan data atau region yang tidak ideal untuk vendor tertentu.

Kapan self-hosted AI belum layak

  • Use case AI Anda belum terbukti menghasilkan nilai bisnis yang konsisten.
  • Traffic masih rendah dan biaya API vendor masih kecil dibanding biaya engineer dan operasi.
  • Tim belum siap mengelola model serving, monitoring kualitas output, dan kapasitas GPU/CPU.
  • Anda belum punya mekanisme fallback ketika model lokal gagal atau performanya turun.

Komponen operasional yang sering terlupakan

  • Model serving: proses load model, concurrency, memory pressure, timeout, dan autoscaling.
  • Observability AI: latency per request, token/input size, cache hit, error rate, kualitas jawaban, dan drift perilaku.
  • Security: enkripsi data, isolasi network, audit access, secret management, dan sanitasi prompt/input.
  • Lifecycle model: update model, rollback, evaluasi kualitas, dan kompatibilitas output.
  • Storage pendukung: object storage, vector index, metadata DB, dan log retention.

Pola integrasi yang pragmatis

Untuk banyak tim, langkah yang paling waras bukan langsung memindahkan seluruh AI stack ke self-hosted, melainkan membuat provider abstraction. Dengan cara ini aplikasi Anda tidak tergantung langsung pada satu vendor atau satu model lokal.

interface LlmProvider {
  generate(input: {
    prompt: string;
    systemPrompt?: string;
    temperature?: number;
  }): Promise<{ text: string }>;
}

class ExternalApiProvider implements LlmProvider {
  async generate(input) {
    // Panggil vendor eksternal
    return { text: "..." };
  }
}

class SelfHostedProvider implements LlmProvider {
  async generate(input) {
    // Panggil endpoint internal model serving
    return { text: "..." };
  }
}

Abstraksi seperti ini bekerja karena Anda bisa:

  • mulai cepat dengan vendor API,
  • mengalihkan use case sensitif ke self-hosted,
  • membuat fallback antar provider,
  • mengukur biaya dan kualitas secara lebih objektif.

Matriks Keputusan: Monolith, Microservice, atau Self-Hosted AI?

FaktorModular MonolithMicroserviceSelf-Hosted AI
Ukuran timKecil sampai menengahMenengah sampai multi-timButuh engineer aplikasi + infra/ML ops yang cukup
Kompleksitas operasionalRendahTinggiMenengah sampai tinggi
Kecepatan perubahan domainCocok untuk domain yang masih berubahCocok bila boundary domain stabilCocok bila use case AI sudah jelas
Observability yang dibutuhkanBasic sampai menengahTinggi, wajib tracing lintas serviceTinggi untuk latency, kualitas, dan resource usage
ScalingSkala aplikasi sebagai satu unit, bisa dibantu worker/cacheSkala per service lebih fleksibelSkala sesuai beban inferensi dan retrieval
LatensiUmumnya paling sederhanaNaik karena komunikasi jaringanTergantung model, hardware, dan arsitektur serving
Keamanan dataLebih sederhana dikelola internalButuh kontrol antar service lebih ketatKontrol tinggi, tetapi tanggung jawab keamanan ikut naik
Vendor lock-inRendah sampai sedangTergantung implementasiBisa lebih rendah jika desain provider netral
MaintainabilityBaik jika modularitas disiplinBaik jika ownership tim dan kontrak matangBaik hanya jika operasi model dikelola serius

Sinyal Praktis: Tetap Monolith, Pecah Service, atau Masuk ke Self-Hosted AI

Tetap di modular monolith jika:

  • Masalah utama Anda masih ada di kualitas desain kode, bukan di batas deployment.
  • Bug lebih sering berasal dari coupling internal daripada beban trafik ekstrem.
  • Satu tim masih mengerjakan hampir semua domain.
  • Anda belum punya tracing, metrics, dan incident handling yang baik.
  • Query lambat, cache buruk, atau job sinkron masih bisa dioptimalkan tanpa pecah service.

Mulai pecah service jika:

  • Ada modul dengan pola beban sangat berbeda dan mengganggu modul lain.
  • Release cadence antar domain bertabrakan terus.
  • Kegagalan di satu area harus diisolasi secara teknis.
  • Ownership tim sudah cukup jelas dan tidak terus berubah.
  • Anda siap menanggung overhead network, observability, dan contract management.

Masuk ke self-hosted AI jika:

  • Data atau compliance menuntut kontrol lebih ketat.
  • Biaya AI vendor sudah mulai menjadi item biaya besar dan tidak stabil.
  • Anda ingin bisa mengganti model tanpa merombak aplikasi utama.
  • Use case AI cukup penting terhadap produk, bukan fitur sampingan yang jarang dipakai.
  • Tim mampu mengelola serving, evaluasi output, fallback, dan keamanan.

Skenario Nyata yang Lebih Relevan daripada Debat Teoretis

Skenario 1: SaaS B2B dengan fitur AI ringkas dokumen

Produk inti adalah workflow dan approval. Fitur AI hanya dipakai untuk ringkasan dokumen dan pencarian semantik. Tim terdiri dari 5 engineer.

Pilihan waras: tetap gunakan modular monolith untuk core app. Pisahkan AI processing sebagai worker asinkron. Gunakan abstraction provider agar bisa mulai dari vendor API, lalu pindah ke self-hosted untuk dokumen sensitif atau volume besar.

Kenapa: kebutuhan scaling AI dan core app berbeda, tetapi organisasi belum butuh microservice penuh.

Skenario 2: Marketplace internal perusahaan besar dengan banyak domain stabil

Ada tim terpisah untuk catalog, order, payment, fulfillment, dan analytics. Deploy monolith mulai menghambat karena perubahan kecil memicu regression di area lain.

Pilihan waras: pecah service secara bertahap berdasarkan domain yang ownership-nya paling jelas. Jangan mulai dari domain yang masih sering berubah. Siapkan tracing, API contract, dan event schema sejak awal.

Kenapa: masalah utamanya sudah bergeser dari coding ke koordinasi lintas tim dan isolasi deployment.

Skenario 3: Produk legal-tech dengan dokumen sangat sensitif

Pengguna mengunggah kontrak dan dokumen hukum. Fitur AI dipakai untuk ekstraksi klausul dan tanya jawab berbasis dokumen.

Pilihan waras: pertimbangkan self-hosted AI lebih awal untuk use case sensitif, terutama jika kebijakan data pelanggan ketat. Namun core app belum tentu perlu microservice. Sangat mungkin arsitektur terbaik adalah modular monolith + AI service internal yang terisolasi.

Kenapa: driver utama bukan skala tim, melainkan keamanan data dan kontrol jalur pemrosesan.

Observability dan Debugging: Ini yang Akan Menentukan Apakah Arsitektur Anda Tahan Produksi

Jika tetap monolith

  • Tambahkan request ID di semua log.
  • Ukur latency endpoint, query database lambat, queue backlog, dan error rate.
  • Pisahkan metrics per modul agar bottleneck domain terlihat.

Jika pakai microservice

  • Wajib punya distributed tracing agar request lintas service bisa diikuti.
  • Tetapkan timeout dan retry dengan hati-hati; retry tanpa idempotency bisa menciptakan duplikasi kerja.
  • Monitor dependency map: service mana yang paling sering jadi sumber timeout atau cascading failure.

Jika pakai self-hosted AI

  • Catat input size, latency inferensi, error model serving, dan saturasi resource.
  • Bedakan error aplikasi, error retrieval, dan error model.
  • Simpan sampel evaluasi output secara aman untuk audit kualitas, bukan hanya log teknis.

Kesalahan umum adalah menganggap observability sebagai pekerjaan setelah deployment. Untuk microservice dan self-hosted AI, itu hampir selalu terlambat.

Checklist Evaluasi Arsitektur

  1. Apakah bottleneck saat ini terukur?

    Jika belum ada angka latency, error rate, queue lag, dan titik resource yang penuh, keputusan arsitektur Anda masih berbasis asumsi.

  2. Apakah domain bisnis sudah punya boundary yang stabil?

    Jika boundary masih berubah tiap sprint, memecah service terlalu dini biasanya menambah friksi.

  3. Apakah tim siap mengelola kompleksitas operasional?

    Lebih banyak service atau self-hosted AI berarti lebih banyak alert, deployment, secret, dan failure mode.

  4. Apakah kebutuhan data sensitif atau compliance benar-benar mendorong kontrol lebih tinggi?

    Jika ya, self-hosted AI atau minimal provider abstraction patut diprioritaskan.

  5. Apakah biaya vendor sudah menjadi masalah nyata?

    Jangan pindah ke self-hosted hanya karena takut mahal. Bandingkan biaya aktual dengan biaya engineer, operasi, dan risiko downtime.

  6. Apakah ada kebutuhan scaling yang berbeda antar komponen?

    Jika ya, pecah komponen yang memang berbeda profilnya, bukan seluruh sistem sekaligus.

  7. Apakah rollback dan debugging sudah dipikirkan?

    Arsitektur yang tampak elegan di diagram bisa menjadi mimpi buruk saat insiden jika jalur rollback tidak jelas.

Rekomendasi Praktis yang Paling Aman

Jika produk Anda mulai tumbuh, strategi yang paling sering berhasil adalah:

  1. Mulai dari modular monolith yang disiplin.
  2. Pisahkan beban berat atau domain khusus menjadi worker/service terbatas hanya jika ada alasan teknis yang terukur.
  3. Untuk AI, bangun provider abstraction sejak awal agar tidak terkunci ke satu vendor.
  4. Masuk ke self-hosted/open-source AI stack saat data, biaya, atau kebutuhan kontrol memang membenarkannya.

Dengan kata lain, pilih arsitektur yang mengurangi biaya koordinasi total, bukan yang terlihat paling modern. Monolith yang modular bisa jauh lebih sehat daripada microservice yang prematur. Self-hosted AI bisa menjadi langkah strategis, tetapi hanya jika tim Anda siap mengelola konsekuensi operasionalnya. Yang waras bukan yang paling sederhana selamanya, melainkan yang paling sesuai dengan bentuk masalah Anda hari ini dan cukup fleksibel untuk esok.