Redis  

ASP.NET Core Health Checks: Monitoring Databases, Redis, and External Services

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.

CheckPurpose
LivenessDetermines whether the application process is running
ReadinessDetermines 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.

StatusMeaning
HealthyDependency is functioning normally
DegradedDependency is available but experiencing issues
UnhealthyDependency 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

ProblemRoot Cause
Health endpoint always returns successNo dependency checks configured
Database outage undetectedSQL Server health check missing
Slow deploymentsReadiness probe misconfigured
Excessive monitoring trafficHealth endpoint performs expensive operations
False positivesHealth checks depend on non-critical services
Traffic sent to unhealthy instancesLoad 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.