I'm always excited to take on new projects and collaborate with innovative minds.

Social Links

Extending ASP.NET Core Health Checks with Custom Database and API Probes

Learn how to enhance ASP.NET Core Health Checks with custom probes for databases and external APIs. This guide includes full code, setup instructions, and a Health Check UI dashboard. Ideal for improving observability and ensuring services are truly ready before deployment.

Extending ASP.NET Core Health Checks with Custom Database and API Probes

Modern applications are expected to be not just functional but also resilient and observable. ASP.NET Core’s built-in health checks provide a solid foundation for monitoring the health of services. However, real-world systems often demand more than just “is the application running?”. We need visibility into the health of dependencies like databases, external APIs, and internal microservices.

In this post, we’ll go beyond the basics and explore how to extend ASP.NET Core Health Checks to include custom probes—specifically for databases and third-party APIs. This ensures your deployments are more reliable and your monitoring systems can detect issues before they cause downtime.

Why Go Beyond the Defaults?

The default health check in ASP.NET Core typically just confirms that the app is up. In microservice or cloud-based environments, that's not enough. We also need answers to questions like:

  • Is the database reachable and performing?
  • Are external dependencies (APIs, queues, etc.) responding correctly?
  • Are internal services in a healthy state?

Failing to check these before deployment can lead to production outages due to misconfigured connections, expired tokens, or dependent services being down.


Setting Up Health Checks in ASP.NET Core

To get started, install the required NuGet package:

dotnet add package AspNetCore.HealthChecks.UI

Register basic health checks in your Program.cs:

builder.Services.AddHealthChecks()
    .AddSqlServer("Your-Connection-String", name: "SQL Server");

This works great for SQL Server or other out-of-the-box integrations, but what if you need something custom—say, checking an internal REST API or a Redis instance that’s not supported by default?


Writing a Custom Health Check

To illustrate, let's create two custom probes:

  1. Database Probe (PostgreSQL in this case)
  2. API Probe (a third-party payment gateway health check)

Custom PostgreSQL Health Check

public class PostgresHealthCheck : IHealthCheck
{
    private readonly IConfiguration _configuration;

    public PostgresHealthCheck(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    public async Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default)
    {
        var connectionString = _configuration.GetConnectionString("PostgresDb");

        try
        {
            await using var conn = new NpgsqlConnection(connectionString);
            await conn.OpenAsync(cancellationToken);
            return HealthCheckResult.Healthy("Postgres is available");
        }
        catch (Exception ex)
        {
            return HealthCheckResult.Unhealthy("Postgres is unavailable", ex);
        }
    }
}

Custom API Health Check

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.thirdparty.com/health", cancellationToken);

        if (response.IsSuccessStatusCode)
            return HealthCheckResult.Healthy("Third-party API is healthy");

        return HealthCheckResult.Unhealthy("Third-party API is down");
    }
}

Registering Custom Health Checks

Now register them during app startup:

builder.Services.AddHttpClient<ExternalApiHealthCheck>();

builder.Services.AddHealthChecks()
    .AddCheck<PostgresHealthCheck>("PostgreSQL")
    .AddCheck<ExternalApiHealthCheck>("ThirdPartyAPI");

Visualizing Health Status with HealthChecks.UI

For better monitoring, integrate with HealthChecks.UI:

dotnet add package AspNetCore.HealthChecks.UI.Client

In Program.cs:

builder.Services.AddHealthChecksUI().AddInMemoryStorage();
app.MapHealthChecksUI(options =>
{
    options.UIPath = "/health-ui";
});

Configure the UI in appsettings.json:

"HealthChecksUI": {
  "HealthChecks": [
    {
      "Name": "Self",
      "Uri": "https://localhost:5001/health"
    }
  ],
  "EvaluationTimeOnSeconds": 10,
  "MinimumSecondsBetweenFailureNotifications": 60
}

Real-World Use Case: Deployment Readiness Checks

In CI/CD pipelines, especially with Kubernetes or Azure DevOps, it's common to validate service health post-deployment. But if your readiness probe only checks for HTTP 200 from the root endpoint, you're missing failure points.

By including database and API health checks in /health/ready, you ensure that your application and its dependencies are up before it receives real traffic.

app.MapHealthChecks("/health/ready", new HealthCheckOptions
{
    Predicate = check => check.Tags.Contains("ready"),
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});

Add tags to your checks:

.AddCheck<PostgresHealthCheck>("PostgreSQL", tags: new[] { "ready" })
.AddCheck<ExternalApiHealthCheck>("ThirdPartyAPI", tags: new[] { "ready" });

Summary

Extending health checks in ASP.NET Core is a crucial step towards production-readiness and system reliability. Whether it's a database, cache, queue, or an external service—your application’s health should reflect the entire system’s condition, not just the app’s uptime.

With custom probes and proper tagging, you can make your monitoring more meaningful and your deployments safer.


GitHub Repository

For a full working sample, visit this GitHub repository:
👉 https://github.com/DheerGupta35959/aspnetcore-health-checks-custom


If you're building microservices or planning automated deployments, integrating custom health checks isn't just nice to have—it's essential.

Let your app tell you when something is wrong—before your users do.

ASP.NET Core, health checks, api monitoring, database health check, readiness probe, liveness probe, deployment, observability, dotnet, dotnet healthcheck, microservices, health check ui, .NET 8, httpclient, npgsql
4 min read
Jul 15, 2025
By Dheer Gupta
Share

Leave a comment

Your email address will not be published. Required fields are marked *