In modern web applications, ensuring that your system is running correctly is crucial. A sudden service failure or database outage can impact users, lead to downtime, or cause data loss. Health checks in ASP.NET Core provide a simple, structured way to monitor the health of your application and its dependencies like databases, APIs, or external services.
This article explains how to implement health checks in ASP.NET Core, step by step, with practical examples and best practices for full-stack applications.
What You Will Learn
What health checks are and why they are important
How to implement built-in health checks in ASP.NET Core
How to monitor dependencies like SQL Server, Redis, or APIs
How to create custom health checks
How to expose a health check endpoint
Integration with monitoring tools
Why Health Checks Are Important
Detect failures early: Automatically detect when a service or database is down.
Improve reliability: Prevent user-facing downtime by monitoring dependencies.
Support DevOps practices: Integrate with Kubernetes, Docker, or load balancers.
Enable proactive maintenance: Send alerts to developers or administrators when services are unhealthy.
In production, health check endpoints are often polled by monitoring tools like Prometheus, Grafana, or Azure Monitor.
Part 1: Adding Health Checks in ASP.NET Core
Step 1: Install Required Packages
ASP.NET Core has built-in support for health checks. You may install additional packages for database or external service checks:
dotnet add package Microsoft.AspNetCore.Diagnostics.HealthChecks
dotnet add package AspNetCore.HealthChecks.SqlServer
Step 2: Register Health Checks
In Program.cs (ASP.NET Core 6/7+):
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
var builder = WebApplication.CreateBuilder(args);
// Register health checks
builder.Services.AddHealthChecks()
.AddSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"),
name: "SQL Server",
failureStatus: Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus.Unhealthy)
.AddCheck("Custom", () =>
{
bool isHealthy = true; // Replace with custom logic
if (isHealthy)
return Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult.Healthy("Everything is fine");
else
return Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult.Unhealthy("Something is wrong");
});
var app = builder.Build();
Step 3: Configure Health Check Endpoint
app.MapHealthChecks("/health", new HealthCheckOptions
{
Predicate = _ => true, // Include all health checks
ResponseWriter = async (context, report) =>
{
context.Response.ContentType = "application/json";
var result = new
{
status = report.Status.ToString(),
checks = report.Entries.Select(e => new {
name = e.Key,
status = e.Value.Status.ToString(),
description = e.Value.Description
})
};
await context.Response.WriteAsJsonAsync(result);
}
});
Now, when you visit https://localhost:5001/health, you get a JSON response like:
{
"status": "Healthy",
"checks": [
{
"name": "SQL Server",
"status": "Healthy",
"description": "Healthy"
},
{
"name": "Custom",
"status": "Healthy",
"description": "Everything is fine"
}
]
}
Part 2: Adding Database Health Checks
If your application depends on SQL Server:
builder.Services.AddHealthChecks()
.AddSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"),
name: "SQL Server",
failureStatus: Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus.Unhealthy);
For PostgreSQL, MySQL, Redis, or MongoDB, you can install respective NuGet packages and use a similar pattern.
Part 3: Creating Custom Health Checks
Sometimes you need to monitor external APIs, disk space, or business rules.
Create a class implementing IHealthCheck:
using Microsoft.Extensions.Diagnostics.HealthChecks;
public class ExternalApiHealthCheck : IHealthCheck
{
private readonly HttpClient _httpClient;
public ExternalApiHealthCheck(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
var response = await _httpClient.GetAsync("https://api.example.com/health");
if (response.IsSuccessStatusCode)
return HealthCheckResult.Healthy("API is available");
else
return HealthCheckResult.Unhealthy("API is down");
}
}
Register the custom health check:
builder.Services.AddHttpClient();
builder.Services.AddHealthChecks()
.AddCheck<ExternalApiHealthCheck>("External API");
Part 4: Integrating Health Checks With Angular
Angular can use HTTP requests to check application health, useful for admin dashboards.
import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-health',
template: `
<h2>Application Health</h2>
<pre>{{ healthStatus | json }}</pre>
`
})
export class HealthComponent implements OnInit {
healthStatus: any;
constructor(private http: HttpClient) {}
ngOnInit() {
this.http.get('https://localhost:5001/health').subscribe({
next: data => this.healthStatus = data,
error: err => this.healthStatus = { status: 'Unhealthy', error: err }
});
}
}
This component fetches the health endpoint and displays a structured report in JSON format.
Part 5: Best Practices
Separate critical and non-critical checks
Database failures should mark the service unhealthy
Optional services (e.g., cache) can be warning only
Use short response times
Health checks should not block the application. Keep them lightweight.
Integrate with monitoring systems
Use Prometheus, Grafana, or Azure Monitor to poll health endpoints.
Secure sensitive endpoints
Consider restricting /health to internal networks or authenticated users.
Use tags
Tag health checks to differentiate between liveness and readiness checks:
.AddSqlServer(..., tags: new[] { "ready" })
Then filter in the endpoint:
app.MapHealthChecks("/ready", new HealthCheckOptions { Predicate = check => check.Tags.Contains("ready") });
Part 6: Liveness VS Readiness
Separate endpoints
app.MapHealthChecks("/health/live", new HealthCheckOptions { Predicate = _ => false }); // Basic
app.MapHealthChecks("/health/ready", new HealthCheckOptions { Predicate = check => check.Tags.Contains("ready") });
Conclusion
Health checks in ASP.NET Core provide a simple and powerful way to monitor application health. With health checks, you can:
Detect failures early
Improve system reliability
Integrate with DevOps pipelines and monitoring tools
Build robust full-stack applications with Angular dashboards
By combining built-in checks, database checks, and custom checks, you can ensure your application is always monitored and reliable in production.