Building a reliable application isn't just about writing correct code—it's also about knowing when something goes wrong. A web application may appear to be running while its database is unavailable, Redis is disconnected, or a third-party API is failing. Without proper health monitoring, these issues often remain undetected until users begin reporting failures.
ASP.NET Core includes a built-in Health Checks framework that allows applications to expose endpoints for monitoring their dependencies. These endpoints integrate seamlessly with Kubernetes, Docker, Azure App Service, load balancers, and monitoring platforms, making it easier to detect failures before they impact users.
Rather than checking only whether an application process is running, this article explains how to build comprehensive health checks for production-ready ASP.NET Core applications.
Note: A healthy application is one whose critical dependencies are available. Simply returning HTTP 200 from an endpoint is not enough for production monitoring.
Why Health Checks Matter
Without health checks, organizations often experience:
Traffic routed to unhealthy servers
Failed deployments
Undetected database outages
Slow incident response
Poor auto-scaling decisions
Increased downtime
Health checks provide real-time visibility into application availability.
Common Health Check Targets
Production applications typically monitor:
SQL Server
PostgreSQL
Redis
External REST APIs
Azure Storage
RabbitMQ
Kafka
Disk space
Memory usage
Every critical dependency should be monitored continuously.
Health Check Architecture
flowchart LR
A[Load Balancer]
B[Kubernetes]
C[Monitoring System]
D[ASP.NET Core API]
E[(SQL Server)]
F[(Redis)]
G[External API]
A --> D
B --> D
C --> D
D --> E
D --> F
D --> G
The application verifies the health of its dependencies before reporting its own health status.
Installing Health Checks
Register Health Checks during application startup.
builder.Services.AddHealthChecks();
This enables the built-in Health Checks framework.
Exposing a Health Endpoint
Map a health endpoint.
var app = builder.Build();
app.MapHealthChecks("/health");
app.Run();
A request to /health returns the current application health status.
Checking SQL Server
Monitor database connectivity.
builder.Services
.AddHealthChecks()
.AddSqlServer(
builder.Configuration
.GetConnectionString("Default"));
The health check verifies that SQL Server is reachable.
Monitoring Redis
Register a Redis health check.
builder.Services
.AddHealthChecks()
.AddRedis(
builder.Configuration
.GetConnectionString("Redis"));
Redis connectivity failures are immediately reflected in the health endpoint.
Monitoring External APIs
Create a custom health check.
public class WeatherApiHealthCheck
: IHealthCheck
{
public async Task<HealthCheckResult>
CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken)
{
return HealthCheckResult.Healthy();
}
}
Custom checks allow monitoring of any external dependency.
Register the custom check.
builder.Services
.AddHealthChecks()
.AddCheck<WeatherApiHealthCheck>(
"Weather API");
Liveness vs Readiness
Liveness and readiness serve different purposes.
| Check | Purpose |
|---|
| Liveness | Determines whether the application process is running |
| Readiness | Determines whether the application is ready to receive traffic |
Separating these checks improves deployment reliability.
Health Check Workflow
flowchart LR
A[Health Request]
B[ASP.NET Core]
C[(Database)]
D[(Redis)]
E[(External API)]
F{All Healthy?}
A --> B
B --> C
B --> D
B --> E
C --> F
D --> F
E --> F
F -->|Yes| G[HTTP 200]
F -->|No| H[HTTP 503]
The application evaluates all registered checks before returning its overall health status.
Custom Response Format
Return detailed health information.
app.MapHealthChecks("/health", new HealthCheckOptions
{
ResponseWriter =
UIResponseWriter.WriteHealthCheckUIResponse
});
Structured responses integrate easily with dashboards and monitoring tools.
Health Status Values
ASP.NET Core defines three health states.
| Status | Meaning |
|---|
| Healthy | Dependency is functioning normally |
| Degraded | Dependency is available but experiencing issues |
| Unhealthy | Dependency is unavailable or failing |
A degraded state allows operators to investigate problems before complete failures occur.
Kubernetes Readiness Probe
Example readiness probe.
readinessProbe:
httpGet:
path: /health
port: 80
Kubernetes removes unhealthy pods from service automatically until they recover.
Common Production Mistakes
| Problem | Root Cause |
|---|
| Health endpoint always returns success | No dependency checks configured |
| Database outage undetected | SQL Server health check missing |
| Slow deployments | Readiness probe misconfigured |
| Excessive monitoring traffic | Health endpoint performs expensive operations |
| False positives | Health checks depend on non-critical services |
| Traffic sent to unhealthy instances | Load balancer not using health endpoints |
Most monitoring issues occur because health checks are too simplistic or poorly configured.
Best Practices
Monitor every critical dependency.
Separate liveness and readiness endpoints.
Keep health checks lightweight.
Return HTTP 503 for unhealthy services.
Log health transitions.
Integrate health endpoints with Kubernetes and load balancers.
Regularly test failure scenarios.
Common Anti-Patterns
Avoid these common mistakes:
Performing expensive database queries inside health checks.
Including non-essential services in readiness checks.
Returning HTTP 200 regardless of dependency status.
Exposing sensitive diagnostic information publicly.
Running health checks too frequently.
Ignoring degraded health states.
FAQ
What is the difference between liveness and readiness?
Liveness checks determine whether the application process is running, while readiness checks determine whether the application can safely receive incoming traffic.
Should every dependency have its own health check?
Critical dependencies such as databases, caches, message brokers, and external APIs should typically have individual health checks so failures can be identified quickly.
Can health checks monitor external services?
Yes. Custom implementations of IHealthCheck allow applications to verify REST APIs, message queues, cloud services, or any other dependency.
Should health endpoints require authentication?
Generally, health endpoints used by infrastructure should remain accessible to trusted monitoring systems, but they should be protected from public exposure using network restrictions, reverse proxies, or appropriate authorization policies.
Conclusion
Health checks are an essential component of production-ready ASP.NET Core applications. By monitoring databases, caches, external services, and other critical dependencies, applications can detect failures early, support automated recovery, and provide accurate status information to orchestration platforms.
When combined with Kubernetes probes, load balancers, and monitoring tools, ASP.NET Core Health Checks help build resilient systems that remain available even as infrastructure and application complexity continue to grow.