
Table of Contents
By Khimananda Oli | Last reviewed: August 2026
You want to run Fiber on Kubernetes because your Go API needs raw throughput and low latency that traditional frameworks cannot match at scale. While Fiber’s performance is exceptional, deploying it requires specific containerization and orchestration patterns to avoid common pitfalls like improper signal handling or resource starvation. This guide covers the exact configuration I use in production to bridge the gap between local development and a resilient, autoscaling cluster.
How do you containerize Go Fiber for Kubernetes?
The foundation of any reliable deployment is the container image. When you run Fiber on Kubernetes, you must avoid shipping source code or heavy base images. A proper multi-stage build reduces your attack surface and ensures consistent startup times across environments. In my experience auditing SOC 2 compliance for fintech clients, minimizing the final image size is often the first control verified during security reviews.
Your Dockerfile should explicitly disable CGO unless you have a specific dependency requiring it. Static binaries eliminate libc version mismatches between build and runtime environments. Here is a production-tested Dockerfile pattern:
# Build stage
FROM golang:1.23-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo \
-ldflags="-w -s -extldflags '-static'" \
-o server .
# Runtime stage
FROM alpine:3.19
RUN apk --no-cache add ca-certificates tzdata curl
WORKDIR /root/
COPY --from=builder /app/server .
RUN adduser -D -H -u 1000 appuser
USER appuser
EXPOSE 3000
CMD ["./server"] Note the inclusion of curl in the runtime stage. While some purists prefer scratch, Alpine with curl enables native HTTP-based liveness probes without installing additional binaries. For teams managing Kubernetes secrets management, this base also provides necessary tools for debugging authentication issues during incident response.
What are the correct health check configurations for Fiber?
Fiber uses fasthttp under the hood, which behaves differently than net/http. A common mistake when engineers first run Fiber on Kubernetes is configuring TCP probes instead of HTTP probes. TCP probes only verify that the socket is open, not that the application can actually process requests. You must implement dedicated health endpoints that validate downstream dependencies.
Implementing Native Health Endpoints
Add explicit routes for liveness and readiness. Liveness should be lightweight—just confirming the event loop isn't blocked. Readiness should check database connections, cache availability, and external service dependencies.
app.Get("/healthz/live", func(c *fiber.Ctx) error {
return c.JSON(fiber.Map{"status": "ok"})
})
app.Get("/healthz/ready", func(c *fiber.Ctx) error {
if err := db.Ping(); err != nil {
return c.Status(503).JSON(fiber.Map{
"status": "unavailable",
"reason": err.Error()
})
}
return c.JSON(fiber.Map{"status": "ready"})
}) Kubernetes Probe Configuration
Configure your Deployment manifest to use these endpoints. Set appropriate timeouts and thresholds based on your application's actual startup behavior. I typically see Fiber apps start in under 2 seconds, but always measure before setting values.
- livenessProbe: HTTP GET /healthz/live, initialDelaySeconds: 5, periodSeconds: 10, failureThreshold: 3
- readinessProbe: HTTP GET /healthz/ready, initialDelaySeconds: 2, periodSeconds: 5, failureThreshold: 2
- startupProbe: HTTP GET /healthz/live, initialDelaySeconds: 0, periodSeconds: 1, failureThreshold: 30 (protects slow starts)
For deeper observability integration, consider pairing these probes with the patterns described in instrumenting an app with OpenTelemetry to correlate probe failures with trace data.
How do you configure resource limits and autoscaling?
Fiber’s efficiency means you can handle more requests per CPU core than most frameworks, but this creates a counterintuitive scaling challenge. If you set requests too low, the scheduler may pack too many pods onto a node, causing noisy-neighbor issues during traffic spikes. If you set them too high, you waste resources and delay scaling decisions.
Setting Requests vs Limits
For CPU-bound Go applications like Fiber, set requests equal to limits. This guarantees predictable scheduling and prevents throttling during peak loads. Memory should have a small buffer between request and limit to accommodate GC spikes.
| Configuration | Development | Production (Recommended) | Rationale |
|---|---|---|---|
| CPU Request | 100m | 250m–500m | Matches typical single-goroutine baseline |
| CPU Limit | 500m | = Request | Prevents CFS throttling on shared cores |
| Memory Request | 128Mi | 256Mi–512Mi | Based on p99 heap usage + GC headroom |
| Memory Limit | 256Mi | Request × 1.2 | Avoids OOMKill during transient allocations |
| GOMAXPROCS | Auto | Match CPU Limit | Prevents excessive context switching |
Always set GOMAXPROCS explicitly to match your CPU limit. The Go runtime defaults to host CPU count, which causes severe performance degradation in containers. Use uber-go/automaxprocs or set it manually in your entrypoint.
Horizontal Pod Autoscaler Tuning
Start with CPU-based scaling at 70% target utilization. Fiber handles concurrency efficiently, so CPU correlates well with actual load. Avoid memory-based HPA for Go apps unless you have known leak patterns. Configure stabilization windows to prevent flapping:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: fiber-api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: fiber-api
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleUp:
stabilizationWindowSeconds: 30
policies:
- type: Pods
value: 2
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 120 How do you handle graceful shutdowns and zero-downtime deploys?
Fiber supports graceful shutdown natively, but Kubernetes doesn’t wait indefinitely. Your pod’s terminationGracePeriodSeconds must exceed your longest expected request duration plus shutdown cleanup time. I recommend 30 seconds as a starting point for most APIs, extending to 60+ for endpoints processing large uploads or complex transactions.
Signal Handling Implementation
Ensure your main function properly catches SIGTERM and initiates shutdown. Fiber’s Shutdown() method stops accepting new connections while completing in-flight requests.
go func() {
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
<-sigChan
log.Info("Received shutdown signal, draining connections...")
if err := app.ShutdownWithTimeout(25 * time.Second); err != nil {
log.Errorf("Shutdown error: %v", err)
}
}()
if err := app.Listen(":3000"); err != nil {
log.Fatalf("Server failed: %v", err)
} Pair this with a preStop hook that sleeps for 5 seconds. This allows the kube-proxy and ingress controller to update endpoints before your app stops serving, preventing connection resets during rolling updates. For teams implementing blue-green and canary deploys on Kubernetes, this hook is non-negotiable.
What networking and ingress patterns work best for Fiber?
Fiber’s performance can be bottlenecked by misconfigured ingress controllers. Since Fiber speaks HTTP/1.1 and HTTP/2 natively, ensure your ingress terminates TLS correctly and forwards real client IPs. Most ingress controllers require specific annotations to preserve headers that Fiber expects for rate limiting and logging.
Enable proxy protocol support if your load balancer requires it. Configure Fiber’s EnableTrustedProxyCheck and TrustedProxies settings to match your cluster’s CIDR ranges. Without this, rate limiters and audit logs will record internal IPs instead of real client addresses—a frequent issue I encounter during structured logging audits.
Run Fiber on Kubernetes With Confidence
Successfully deploying high-performance Go services requires attention to containerization details, probe semantics, and resource tuning that generic tutorials often skip. When you run Fiber on Kubernetes using the patterns above—multi-stage builds, proper health checks, matched CPU requests/limits, and graceful shutdown handling—you get a platform that scales predictably under real production load. Start with the Dockerfile and probe configuration, validate locally with kind or minikube, then apply the HPA and networking settings incrementally. If your team needs help designing a compliant, observable deployment pipeline for Go microservices, reach out to discuss your infrastructure requirements.