Course contentsShow
← C#
Lesson 1577 of 1,90814. Background Work and MessagingFree lesson

Container Orchestration Best Practices

Configure resource limits and probes for background workers in Kubernetes environments.

In this lesson, you will learn how to stabilize your background workers by configuring precise resource constraints and health probes within your Kubernetes manifests.

When deploying C# background workers—especially those performing intensive tasks like stream processing or heavy serialization—relying on default settings is a recipe for instability. If a worker consumes more memory than the host expects, the OOM (Out of Memory) Killer will terminate it; if it consumes more CPU than it is granted, it will experience significant latency spikes.

Defining Resource Constraints

For .NET background services, you should explicitly define requests and limits. The request is what the scheduler guarantees, while the limit is the hard ceiling. For memory, set these close together to prevent the garbage collector from being surprised by sudden memory pressure, which often triggers premature process restarts.

resources:
  requests:
    cpu: "250m"
    memory: "512Mi"
  limits:
    cpu: "500m"
    memory: "768Mi"

Implementing Probes

A background worker that is "running" is not necessarily "healthy." If a worker loses its connection to the message broker or hits a deadlock, it might look operational to the orchestrator while failing to process work. You should implement a livenessProbe to restart a crashed process and a readinessProbe to ensure the worker is only handed traffic once it has established its connection to your event mesh.

In C#, expose a simple health endpoint using Microsoft.Extensions.Diagnostics.HealthChecks. You can then map this to your YAML:

livenessProbe:
  httpGet:
    path: /health/live
    port: 8080
  initialDelaySeconds: 15
  periodSeconds: 20
readinessProbe:
  httpGet:
    path: /health/ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 10

By keeping these probes separate, you prevent the orchestrator from killing a worker simply because it’s temporarily busy (liveness) while ensuring it isn’t assigned new tasks until its internal state is fully initialized (readiness). This keeps your background pipeline resilient even under fluctuating load.

Key Takeaway: Always define strict resource limits and distinct liveness/readiness probes to ensure your background workers remain stable, predictable, and fully initialized before participating in the event-driven ecosystem.