System Design #1 , Architecture for a Side Project That (Might) Go Viral
How to design an architecture for a side project with unclear scale? From monolith to microservices , a practical guide for solo developers.
Banyak developer ngalamin kesalahan yang sama dua kali.
Pertama, pernah bikin REST API pake microservices dari awal. Beberapa service, beberapa database, lebih dari satu bahasa pemrograman. Butuh berbulan-bulan , dan pas launch, cuma segelintir orang yang pake. Service-nya lebih sering down daripada serving request. Kenapa? Karena waktunya habis buat debugging masalah networking, bukan masalah user.
Kedua, side project lain. Kali ini pake monolith. Satu binary, satu database. Launch 2 minggu , dan anehnya, ini yang survive sampe sekarang.
Side project yang gak pernah launch punya arsitektur terbaik di dunia , dan 0 user.
Instagram cuma punya 3 engineer waktu diakuisisi Facebook dengan 30 juta user. Twitter mulai sebagai monolith. Shopify juga. Polanya gak berubah.
Artikel ini ditulis karena banyak waktu pertama sia-sia mikirin microservices. Anda gak perlu ngulangin kesalahan yang sama.
Mulai dari Monolith , Kenapa Bukan Microservices
Monolith itu bukan dosa. Ini titik awal yang bener. Alasan semua orang pake monolith bukan karena males belajar , karena biaya distribusi (network latency, data consistency, debugging antar-service) jauh lebih mahal daripada keuntungan skalabilitas yang gak Anda butuhin.
Yang penting bukan monolith vs microservices. Yang penting adalah: apakah kode Anda separation of concern-nya rapi atau spaghetti?
Lihat: domain dipisahin berdasarkan business logic, bukan deployment unit. Ini penting , karena nanti kalo Anda butuh mindahin satu domain ke service terpisah, yang Anda butuh hanyalah ganti import, bukan refactor ulang.
Modular Monolith: Batasi dengan Interface, Bukan Service
Pas udah punya 200 user aktif, satu binary mulai terasa berat. Bukan skalanya , tapi ada feature image processing yang pake CPU gila-gilaan. API response jadi 3 detik.
Pertama kali mikir: "Ini waktunya pisah service." Ternyata jawabannya lebih sederhana: pisahin interface, bukan pisahin deployment. Modular monolith.
Caranya: setiap domain cuma bisa akses domain lain lewat interface yang terdefinisi. Payment module gak bisa langsung akses database User , cuma lewat UserService interface.
Kalau nanti Anda beneran perlu pisahin Payment jadi service sendiri, Anda tinggal bikin implementasi remote dari interface yang sama. Kode bisnis gak berubah.
Pilih Stack yang Anda Kuasai, Bukan yang Lagi Hype
Ini pelajaran yang dibayar mahal: jangan pake bahasa baru untuk side project pertama Anda. Lihat Hacker News , Zig, Gleam, Bun , langsung pengen pake. Hasilnya: 2 minggu belajar syntax, 2 minggu debugging tooling, side project gak jadi.
Saya pake Go bukan karena paling keren, tapi karena udah dipake 3 tahun. Saya tau cara deploy, cara debug memory leak, cara setup CI/CD. Stack yang Anda kuasai > stack yang lagi hype.
Untuk 2026: Go atau TypeScript buat backend. Postgres buat database. VPS $4/bulan dari Hetzner. Done.
Desain Database: Keputusan yang Paling Berdampak Jangka Panjang
Dari semua yang pernah di-refactor , framework, API, frontend , refactor database di production adalah yang paling sakit. Gak ada cari dan replace buat database.
Aturan saya sekarang: normalisasi sampe 3NF dulu. Denormalisasi cuma kalo ada benchmark yang jelas. UUID v7, bukan auto-increment. Timestamptz, bukan timestamp. Soft delete dengan deleted_at.
Schema yang baik bisa dijelaskan dalam 3 kalimat. Kalo butuh 3 paragraf, terlalu kompleks.
Observability dari Hari Pertama, Bukan Nanti-nanti
Side project Anda punya 0 user. Anda pikir: "Buat apa log?" Anda launch. Ada error. Anda gak tau error apa. Nyari-nyari manual. 3 jam hilang. Ini kejadian yang banyak dialami , dan sebaiknya gak diulangi.
Dari day 1: structured logging (JSON format), request ID yang nembus semua log, health check endpoint (/healthz). Butuh 10 menit setup , menghemat berjam-jam debugging.
Automation: Karena Solo, Harus Efisien
Kalo sendiri, waktu adalah musuh. Setiap menit buat manual deploy, manual testing, manual backup adalah menit yang gak dipake buat nulis fitur , atau lebih penting, istirahat.
Commit pertama: langsung setup CI/CD. Otomatis test + deploy tiap push ke main. Backup database tiap 6 jam. One-command deploy. Health check monitoring.
Kapan Split ke Microservices? (Jawaban Singkat: Hampir Gak Pernah)
Split pertama yang impactful bukan split service , tapi split process. Pisahin background worker dari web server. Itu cukup buat 99% side project.
Evolution path: monolith (0-100 user) โ +worker (100-1000) โ modular (ribuan). Indikator Anda beneran butuh microservices: deploy cycle conflict. Kalo cuma 1 orang developer, ini gak akan terjadi.
Kalau side project Anda punya 100 user dan udah mikirin microservices , Anda mikirin masalah yang gak Anda punya.
Cheat Sheet: Checklist Sebelum Nulis Baris Kode Pertama
- Mulai dari monolith , satu binary, satu database
- Pake Postgres , bukan MongoDB, bukan Redis sebagai primary DB
- UUID v7 untuk primary key, bukan auto-increment
- Soft delete dengan kolom deleted_at , jangan hard delete
- Structured logging pake log/slog , jangan fmt.Println
- CI/CD dari commit pertama , otomatis test + deploy tiap push ke main
- Satu endpoint health check di /healthz
- One-command deploy , satu perintah dari kode ke production
Penutup , Yang Dipelajari dari Waktu yang Terbuang
Banyak waktu pertama dihabisin bikin microservices yang gak kepake. Apa yang dipelajari: arsitektur yang baik bukan yang paling scalable. Arsitektur yang baik adalah yang bikin Anda launch cepat, gampang diubah, dan , paling penting , gak bikin pengen quit.
Mulai dengan monolith. Pake Postgres. Observability dari hari pertama. Automation everything.
Karena side project yang gak pernah launch punya arsitektur terbaik di dunia , dan 0 user.
