Bundle Enterprise: Spring + Postgres + K8s
Stack enterprise default yang saya jalankan 26 bulan di fintech series-B + BUMN energy Jakarta. Spring Boot 3 + Postgres + K8s + Kafka + Redis. Total cost Rp 45-65 juta/bulan untuk 18 service. Verdict Recommended sebagai baseline 2026.
TL;DR
- Bundle Components: Spring Boot 3 (Java 21 LTS) + PostgreSQL (Cloud SQL atau self-host) + Kubernetes (GKE) + Kafka self-host + Redis + Cloudflare edge.
- Cost run-rate: Rp 45-65 juta/bulan untuk 18 service enterprise fintech.
- Performance baseline: p99 latency < 250ms, throughput 1k-2k RPS per service, availability 99,94%.
- Verdict: Recommended sebagai baseline enterprise Indonesia 2026. Default untuk fintech series-B, BUMN, enterprise mid-size.
Konteks
Saya jalankan bundle ini paralel 26 bulan (Maret 2024 - Mei 2026) di:
- Fintech series-B Jakarta: 18 microservice, full bundle, run-rate Rp 52 juta/bulan
- BUMN energy Jakarta: 22 microservice, hybrid bundle (Rancher on-prem K8s instead of GKE, Postgres on-prem instead of Cloud SQL), run-rate equivalent Rp 78 juta/bulan (lebih mahal karena on-prem amortization + ops time)
Sebelumnya 8+ tahun pengalaman stack Spring + Postgres (sejak Spring 3.x era, Postgres 9.x).
Pricing breakdown (Juni 2026)
Compute K8s (GKE Autopilot Jakarta)
- Control plane: USD 73/bulan/cluster × 2 (prod + staging) = USD 146/bulan
- Workload pod compute: ~18 service × 3 replica × resource request average
- Untuk fintech: ~Rp 16-20 juta/bulan
- Total compute: ~Rp 18 juta/bulan
Database PostgreSQL (Cloud SQL Postgres regional HA)
- Tier db-custom-4-15360 (4 vCPU, 15GB RAM, 500GB SSD), regional HA + read replica:
- Primary: Rp 4,2 juta/bulan
- Replica: Rp 2,1 juta/bulan
- Backup automated PITR: Rp 1,8 juta/bulan
- Total DB: Rp 8,1 juta/bulan
Message Broker (Kafka self-host)
- 3-broker cluster di GKE Jakarta n2-standard-4: Rp 5,8 juta/bulan
- Schema Registry + Connect: Rp 1,8 juta/bulan
- MirrorMaker 2 ke DR Singapore: Rp 1,2 juta/bulan
- Total Kafka: Rp 8,8 juta/bulan
Cache (Redis Memorystore basic-HA)
- Tier basic-1, 4GB: Rp 1,6 juta/bulan
- Snapshot ke R2: Rp 200 ribu/bulan
- Total Redis: Rp 1,8 juta/bulan
Storage (Cloudflare R2)
- 500GB object storage (asset, backup, log archive): Rp 1,2 juta/bulan
Observability (LGTM stack self-host)
- Grafana + Loki + Tempo + Mimir cluster: Rp 12,4 juta/bulan (lihat artikel observability detail)
Secret management (HashiCorp Vault)
- 3 Vault pod di GKE + KV backend: Rp 800 ribu/bulan
Networking + Load Balancer
- Cloudflare Pro + WAF: USD 25/bulan
- Cloud Load Balancer GCP: Rp 1,6 juta/bulan
- Egress bandwidth: Rp 400 ribu/bulan
- Total networking: Rp 2,4 juta/bulan
Total run-rate
| Komponen | Cost/bulan |
|---|---|
| Compute K8s | Rp 18 juta |
| Postgres regional HA | Rp 8,1 juta |
| Kafka self-host | Rp 8,8 juta |
| Redis | Rp 1,8 juta |
| Storage R2 | Rp 1,2 juta |
| Observability LGTM | Rp 12,4 juta |
| Vault secret | Rp 800 ribu |
| Networking + LB | Rp 2,4 juta |
| Total | Rp 53,5 juta/bulan |
Cost per service: Rp 53,5 juta / 18 = ~Rp 3 juta/service/bulan all-in. Untuk B2B SaaS dengan target Rp 5-15 juta/customer/bulan, infra cost ~20-60% revenue/customer = healthy.
SLO + performance (26 bulan)
Service-level (per microservice average)
| Metrik | Target | Realisasi |
|---|---|---|
| Availability per service | 99,95% | 99,94% |
| p50 latency HTTP | < 30ms | 22ms |
| p99 latency HTTP | < 250ms | 185ms |
| Throughput sustained per pod | > 1.000 RPS | 1.380 RPS |
| Cold start (Spring Boot 3 + Java 21) | < 8 detik | 4-6 detik |
| GC pause p99 (ZGC) | < 15ms | 8ms |
System-level
| Metrik | Target | Realisasi |
|---|---|---|
| End-to-end availability (compound) | 99,9% | 99,87% |
| RTO regional failover | < 30 menit | 18-25 menit |
| RPO data | < 5 menit | 30 detik - 2 menit |
| Deploy lead time p99 | < 20 menit | 14 menit |
| MTTR P1 incident | < 60 menit | 45 menit |
Architecture pattern
Stack arsitektural
Cloudflare WAF + DDoS
│
Cloudflare PoP Jakarta
│
├─→ Cloudflare Pages (frontend SPA)
│
└─→ GKE Jakarta Ingress
│
┌──────┴───────┐
│ │
Spring Boot 3 Spring Boot 3
(Java 21) (Java 21)
Service A Service B
│ │
┌──────┴──────────────┴───┐
│ │
Postgres HA Redis cache
(Cloud SQL) (Memorystore)
│
└─→ Replica Singapore (DR)
Kafka cluster
(3-broker self-host)
│
├─→ Audit log
├─→ Event streaming
└─→ MirrorMaker → Singapore DR
LGTM Observability
(Grafana + Loki + Tempo + Mimir)
│
├─→ Metric, log, trace
├─→ Alert ke Slack + PagerDuty
└─→ Audit log retention 7 tahun ke S3 Glacier
Vault (HashiCorp)
│
└─→ Secret KV + dynamic credential Postgres
Per-service template
Spring Boot 3 service standard saya:
service-payment/
├── src/main/java/com/company/payment/
│ ├── PaymentApplication.java
│ ├── api/ # REST controller
│ ├── domain/ # Business logic
│ ├── infrastructure/ # Repository, external client
│ ├── config/ # Spring config
│ └── observability/ # OpenTelemetry init
├── src/main/resources/
│ ├── application.yml # Profile prod/staging/dev
│ └── db/migration/ # Flyway script
├── src/test/ # JUnit 5 + Testcontainers
├── Dockerfile # Multi-stage build, distroless base
├── kustomization.yaml # K8s manifest
└── pom.xml
application.yml baseline:
spring:
application:
name: payment
datasource:
url: jdbc:postgresql://postgres-primary:5432/payment
hikari:
maximum-pool-size: 20
minimum-idle: 5
jpa:
hibernate:
ddl-auto: validate
flyway:
enabled: true
kafka:
bootstrap-servers: kafka-1:9092,kafka-2:9092,kafka-3:9092
producer:
acks: all
enable-idempotence: true
data:
redis:
host: redis-master
port: 6379
server:
port: 8080
tomcat:
threads:
max-threads: 10000 # virtual threads enabled
shutdown: graceful
management:
endpoints:
web:
exposure:
include: health,info,prometheus,metrics
endpoint:
health:
probes:
enabled: true
Database migration pattern
Flyway script di db/migration/:
V1__create_payment_table.sql
V2__add_payment_status_index.sql
V3__add_refund_table.sql
Schema versioning di Git. Migration run otomatis di startup, atau via job pre-deploy untuk control.
Observability instrumentation
Auto-instrumentation via OpenTelemetry Java agent:
java -javaagent:/opt/otel-agent.jar \
-Dotel.service.name=payment \
-Dotel.exporter.otlp.endpoint=http://otel-collector:4318 \
-Dotel.traces.sampler=parentbased_traceidratio \
-Dotel.traces.sampler.arg=0.1 \
-jar payment.jar
10% trace sampling untuk service biasa, 100% untuk service kritis (payment).
High availability + DR
Multi-region active-passive
Primary: GKE asia-southeast2 (Jakarta)
├── 3 zone HA
├── Postgres Cloud SQL regional HA (synchronous replication)
├── Kafka 3-broker (acks=all)
└── Redis basic-HA
DR: GKE asia-southeast1 (Singapore)
├── 30% capacity standby
├── Postgres replica (async, RPO 30 detik)
├── Kafka mirror via MirrorMaker 2
└── Redis snapshot restore
Failover trigger:
- Manual via runbook (BUMN compliance)
- Auto-detect health check fail > 5 menit (fintech)
- DNS swap via Cloudflare API
RPO/RTO realisasi
| Komponen | RPO target | RTO target | Realisasi |
|---|---|---|---|
| Compute K8s | 0 | 5 menit | 3-4 menit |
| Postgres | 5 menit | 30 menit | 30-90 detik / 12-18 menit |
| Kafka | 5 menit | 15 menit | 1-3 menit / 8-12 menit |
| Redis | 60 menit | 10 menit | snapshot last + restore 6-10 menit |
| Total system | 5 menit | 30 menit | 2-3 menit / 18-25 menit |
Failover test quarterly via chaos engineering drill.
Decision matrix
Kapan adopt bundle full ini?
- Tim engineering 8+ dev dengan dedicated SRE 1+ FTE
- 8+ microservice production
- Customer-facing dengan SLO 99,95%+
- Budget infra Rp 30+ juta/bulan
- Compliance audit requirement (OJK, BSP, atau internal)
Kapan sederhanakan bundle?
Untuk SMB < 10 service:
- Skip K8s: pakai Cloud Run / Fly.io / Railway
- Postgres managed (Neon, Supabase) instead of Cloud SQL HA
- Skip Kafka self-host: pakai Confluent Cloud free tier atau hilangkan event streaming kalau tidak butuh
- Observability: Grafana Cloud free tier (50GB log gratis)
- Cost target: Rp 5-15 juta/bulan
Kapan upgrade ke beyond bundle?
Untuk enterprise large (50+ microservice, 100+ engineer):
- Service mesh (Istio, Linkerd) untuk traffic management + mTLS
- Multi-cluster federation
- Distributed cache (Hazelcast, Apache Ignite)
- Premium observability (Datadog APM AI insight)
- Cost: Rp 200+ juta/bulan
Trade-off
Pro bundle ini
- Maturity: setiap komponen battle-tested 10+ tahun production
- Hiring: pool Indonesia paling besar untuk semua komponen
- Documentation: knowledge base luas + community Indonesia aktif
- Scalability: scale dari 3 pod ke 300 pod tanpa rewrite arsitektural
- Compliance: pattern audit-friendly + data residency Indonesia controllable
- Cost predictable: scale predictable, no surprise pricing
Con bundle ini
- Operational overhead: butuh dedicated SRE (LGTM, K8s, Kafka semua ops-heavy)
- Cold start Spring Boot: 4-6 detik (vs Quarkus native 60-200ms) — bukan ideal untuk serverless scale-to-zero
- Java verbosity: lebih banyak boilerplate dibanding Kotlin / Go
- Kafka complexity: ops 25-35 jam/bulan kalau self-host
Variasi bundle
Bundle BUMN dengan on-prem mandate
- K8s on-prem (Rancher / Talos) instead of GKE
- Postgres self-host on-prem instead of Cloud SQL
- Object storage MinIO instead of R2 (kalau on-prem-only)
- Cost lebih tinggi karena ops overhead, tapi compliance sektoral satisfied
Bundle fintech series-B agile
- Full managed cloud (GKE Autopilot, Cloud SQL managed, Memorystore)
- Konsolidasi ke 1 cloud (saya pilih GCP karena Jakarta region)
- Cloudflare di depan untuk WAF + DDoS
- Cost optimized untuk speed-to-market
Bundle SaaS B2B Indonesia mid-market
- Sama dengan fintech series-B tapi tambah:
- Multi-tenant pattern (1 deployment, isolation via DB schema atau row-level security)
- Feature flag (GrowthBook self-host atau LaunchDarkly)
- Auth bundle (Clerk + WorkOS)
Migration pattern
Dari legacy on-prem ke bundle ini
12-18 bulan total kalau ada legacy investment besar. Pattern bertahap:
- Bulan 1-3: Setup K8s + observability paralel dengan legacy
- Bulan 4-9: Migrate service per-domain (strangler fig pattern)
- Bulan 10-12: Database migration (legacy DB → Postgres)
- Bulan 13-15: Decommission legacy
- Bulan 16-18: Optimization + hardening
Pengalaman saya di BUMN energy: 14 bulan total untuk full migrate 22 service legacy ke bundle ini.
Dari MVP cloud SaaS ke bundle ini
3-6 bulan kalau scale outgrow Cloud Run / Fly.io. Pattern:
- Bulan 1: Setup K8s + observability
- Bulan 2-3: Migrate service ke K8s
- Bulan 4: Setup Kafka + Redis
- Bulan 5: Hardening + compliance
- Bulan 6: Performance tuning
Common pitfall
- Premature adoption full bundle. Untuk < 8 service: K8s + Kafka + LGTM = over-engineering. Wait until pain point real.
- Multi-region tanpa test failover. Failover yang tidak pernah di-test = failover yang tidak akan work saat butuh. Chaos engineering quarterly drill.
- Skip observability di awal. “Add later” = tidak pernah. Setup LGTM bersamaan dengan service pertama.
- No infrastructure-as-code. Manual click di console = drift, no audit trail. Pakai OpenTofu / Terraform dari hari pertama.
- Cost monitoring tidak setup. Cloud cost bisa balloon. Setup billing alert + monthly review.
Cost of ownership 36 bulan
| Item | Cost 3 tahun |
|---|---|
| Infrastructure (Rp 53,5 juta × 36) | Rp 1,93 miliar |
| Ops engineer (2 SRE × Rp 35 juta × 36) | Rp 2,52 miliar |
| Migration / build out one-time | Rp 1,2 miliar |
| Insiden (rata-rata Rp 30 juta/quarter) | Rp 360 juta |
| Training tim + tooling upgrade | Rp 240 juta |
| Total 3 tahun | Rp 6,25 miliar |
Untuk fintech series-B Series B funded (USD 30-60 juta typical): 6,25 miliar = ~0,3-0,5% total funding. Acceptable.
Untuk BUMN dengan IT budget Rp 25-40 miliar/tahun: 6,25 miliar 3 tahun = ~6-8% IT budget. Acceptable.
Untuk SMB Indonesia Rp 1-3 miliar/tahun IT: 6,25 miliar 3 tahun = 100-200% budget. NOT acceptable — pakai bundle simplified.
Yang surprising
Setelah 26 bulan: ops cost engineer ternyata lebih dari infrastructure cost (47% vs 31%). Untuk justify bundle full, butuh SRE skill + dedication. Tanpa SRE: ops cost balloon karena engineer biasa firefighting + tooling drift.
Surprise lain: Postgres regional HA + read replica setup ternyata cover hampir semua use case enterprise saya. Tidak butuh upgrade ke distributed (Citus, CockroachDB) dalam 26 bulan. Threshold dari single Postgres ke distributed lebih jauh dari ekspektasi awal (saya kira hit di 5k RPS, realita comfortable di 15k+ RPS dengan Postgres tuning + connection pooling agresif).
Verdict
Recommended sebagai bundle baseline enterprise Indonesia 2026.
- Default fintech series-B / BUMN mid-size / enterprise: Bundle full ini. ROI clear, scalability runway 5-10 tahun.
- SMB < 10 service: Bundle simplified (skip K8s + self-host Kafka). Cost target Rp 5-15 juta/bulan.
- Enterprise large 50+ service: Bundle ini sebagai foundation + add service mesh + advanced observability.
- Skip bundle full kalau Anda < 5 dev atau pre-PMF — over-engineering tidak justify.
Threshold konkret untuk adopt: 8+ microservice + dedicated SRE 0,5+ FTE + budget Rp 30+ juta/bulan infra. Di bawah ini, bundle simplified atau platform abstraksi (Cloud Run, Fly.io) lebih ROI-friendly.
Ditulis oleh Asti Larasati