Two load balancers
| Load Balancer (flexible) | Network Load Balancer | |
|---|---|---|
| Layer | 7 (HTTP/HTTPS) and 4 (TCP) | 4 (TCP/UDP/ICMP) |
| Features | TLS termination, hostnames, path routing, rule sets, WAF attachment, session persistence | Pass-through, source IP preservation, very high throughput |
| Pricing | Per hour + bandwidth (flexible shape) | No charge for the NLB itself (check current pricing) |
If an app only needs TCP balancing (databases, custom protocols, backends that terminate TLS themselves), the NLB is usually the simpler and cheaper choice.
1. Measure
OCI Monitoring, namespace oci_lbaas, 30 days per load balancer:
BytesReceived/BytesSent→ peak MbpsActiveConnections,HttpRequestsBackendTimeouts,HttpResponses5xx
BytesSent[1m]{resourceId = "<lb-ocid>"}.rate().max()
Convert bytes/s to Mbps (× 8 / 1,000,000) and compare with the configured minimum/maximum.
2. Set flexible bandwidth
oci lb load-balancer update-load-balancer-shape --load-balancer-id $LB \
--shape-name flexible --shape-details '{"minimumBandwidthInMbps": 10, "maximumBandwidthInMbps": 400}'
- Minimum: billed always. Set it to your steady baseline (often the smallest value for internal apps).
- Maximum: the ceiling for bursts. Set it above measured peak so traffic isn't capped.
Converting old fixed shapes (e.g. 100 Mbps, 400 Mbps) to flexible is supported. Check the current procedure.
3. Consolidate small apps
One flexible load balancer can host several apps with hostnames on a listener and routing policies:
lb-internal-shared
listener https-443 (SNI certificates)
hostname hr.internal.example → backend set hr
hostname wiki.internal.example → backend set wiki
path /api/* → backend set api
Group by environment and exposure (public vs private); don't mix prod with dev. Watch the per-load-balancer limits on listeners, backend sets and certificates.
4. Backend set tuning
| Setting | Recommendation |
|---|---|
| Health check | Dedicated lightweight URL; interval and retries that detect failure quickly without flapping |
| Policy | Least connections for uneven request duration; round robin otherwise |
| Connection draining | Enable with a timeout matching request duration, so deployments don't drop requests |
| Idle timeout (listener) | Lower than backend keep-alive to avoid random 502s |
| Session persistence | Only when the app needs it |
oci lb backend-set update --load-balancer-id $LB --backend-set-name web \
--policy LEAST_CONNECTIONS --health-checker-protocol HTTP --health-checker-url-path /healthz \
--health-checker-port 8080 --health-checker-interval-in-ms 10000 --health-checker-retries 3 \
--backends file://backends.json --force
update replaces the backends list. Pass the current backends file, or use oci lb backend commands to change backends individually.
5. Clean up
- Load balancers with no traffic for 90 days (and confirm they aren't DR standbys).
- Load balancers created by deleted OKE services (
oci lb load-balancer list+ tags from OKE). - Unused reserved public IPs left after deleting load balancers.
Tip
In OKE, use one shared ingress controller (or a few) behind a load balancer instead of a
LoadBalancerService per app. It cuts the number of load balancers and centralises TLS.
Checklist
- Bandwidth and connections measured per LB
- Flexible min/max set to baseline and peak
- NLB used where layer 7 isn't needed
- Small apps consolidated by environment/exposure
- Backend sets tuned (health, policy, draining, timeouts)
- Idle and orphaned LBs removed