← Back to Cecep Azhar
Cecep Azhar #saas#architecture#multi-tenant#golang#database

Multi-Tenant Architecture: Rahasia Scalability SaaS

Cecep Saeful Azhar • 16 Oct 2026
Multi-Tenant Architecture: Rahasia Scalability SaaS
Pelajari multi-tenant architecture untuk SaaS. Pool database vs database-per-tenant, implementasi di Go.

Apa Itu Multi-Tenant Architecture?

Multi-tenant artinya satu instance aplikasi melayani banyak customer sekaligus. Ini adalah fondasi utama SaaS yang efisien. Tanpa multi-tenant, Anda harus deploy instance terpisah untuk setiap customer.

Saya sudah implement multi-tenant di beberapa produk dan ada 3 pendekatan utama yang perlu Anda pahami.

3 Pendekatan Multi-Tenant

1. Pool Database Shared Schema

Semua tenant share database yang sama, dibedakan oleh column tenant_id. Ini paling murah dan paling umum untuk SaaS kecil-menengah.

// Contoh query dengan tenant_id
func GetProjects(db *gorm.DB, tenantID uint) ([]Project, error) {
    var projects []Project
    err := db.Where("tenant_id = ?", tenantID).Find(&projects).Error
    return projects, err
}

2. Pool Database Separate Schemas

Setiap tenant punya schema sendiri dalam database yang sama. Lebih aman tapi lebih kompleks.

3. Database per Tenant

Full isolation. Cocok untuk enterprise SaaS yang handle data sensitif. Tapi cost-nya jauh lebih tinggi.

Implementasi di Go Tenant Middleware

Di Go, saya biasanya pakai middleware untuk inject tenant context di setiap request:

func TenantMiddleware(c *fiber.Ctx) error {
    tenantID := c.Get("X-Tenant-ID")
    if tenantID == "" {
        return c.Status(400).JSON(fiber.Map{"error": "tenant ID required"})
    }
    c.Locals("tenantID", tenantID)
    return c.Next()
}

Dengan approach ini, setiap handler bisa langsung akses tenant ID tanpa perlu parse ulang. Clean dan efisien.

Performance Tips

Pool database dengan shared schema punya bottleneck di query performance. Solusinya:

Dari pengalaman saya, pool database shared schema bisa handle ribuan tenant dengan response time under 50ms selama Anda proper index.

Tenant Isolation: Aspek Keamanan yang Kritis

Salah satu tantangan terbesar multi-tenant adalah memastikan data isolation. Satu kesalahan kecil di query bisa leak data antar tenant. Ini nightmare yang harus dicegah.

Di Go, saya selalu pakai row-level security di PostgreSQL sebagai layer pertahanan kedua. Meskipun application layer sudah filter by tenant_id, database tetap enforce isolation di level table:

-- Enable RLS
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;

-- Policy: user hanya bisa akses data tenant-nya
CREATE POLICY tenant_isolation ON projects
    USING (tenant_id = current_setting('app.tenant_id')::int);

Dengan kombinasi application-level filtering dan database-level RLS, kemungkinan data leak menjadi sangat kecil. Defense in depth selalu lebih baik dari single point of failure.

Migration Strategy untuk Multi-Tenant

Menambah kolom atau tabel baru di multi-tenant setup membutuhkan perencanaan ekstra. Jangan asal ALTER TABLE. Pertimbangkan impact ke semua tenant. Saya biasanya pakai expand-contract pattern: tambah kolom baru, migrate data, lalu hapus kolom lama. Proses ini harus di-automate dan bisa di-rollback.

← More articles from Cecep Azhar Central Content Hub Home →