Overview
Health checks verify the operational status of:- PostgreSQL Database: Connection and query capability
- Redis Cache: Connection and storage capability
- Keycloak Identity Provider: HTTP endpoint availability
Health Check Endpoint
The health check endpoint is configured in src/Bookify.Api/Program.cs:47:Accessing Health Checks
Send a GET request to the/health endpoint:
Response Format
The endpoint returns a JSON response with overall status and individual dependency statuses:Status Codes
| Status | HTTP Code | Description |
|---|---|---|
Healthy | 200 | All dependencies are operational |
Degraded | 200 | Some non-critical dependencies are unhealthy |
Unhealthy | 503 | Critical dependencies are unavailable |
Health Check Configuration
Health checks are registered in src/Bookify.Infrastructure/DependencyInjection.cs:139:Dependencies
Bookify uses theAspNetCore.HealthChecks NuGet packages:
AspNetCore.HealthChecks.NpgSql: PostgreSQL health checksAspNetCore.HealthChecks.Redis: Redis health checksAspNetCore.HealthChecks.Uris: HTTP endpoint health checksAspNetCore.HealthChecks.UI.Client: JSON response formatter
Individual Health Checks
PostgreSQL Health Check
What it checks:- Database connection can be established
- Database server is responsive
- Connection string is valid
- PostgreSQL container is down
- Invalid connection string
- Network connectivity issues
- Database authentication failure
Redis Health Check
What it checks:- Redis connection can be established
- Redis server is responsive
- Cache operations work
- Redis container is down
- Invalid connection string
- Redis server out of memory
- Network connectivity issues
Keycloak Health Check
What it checks:- Keycloak endpoint is reachable
- HTTP GET request succeeds
- Identity provider is operational
- Keycloak container is down
- Invalid base URL configuration
- Network connectivity issues
- Keycloak server error
Adding Custom Health Checks
Simple Health Check
Create a custom health check by implementingIHealthCheck:
Register Custom Health Check
Add it to the health checks configuration:- Name: Identifier in health check response (“email”)
- FailureStatus: Status when check fails (Degraded or Unhealthy)
Use
HealthStatus.Degraded for non-critical dependencies to avoid marking the entire application as unhealthy.Health Check with Data
Include additional diagnostic information:Health Check Strategies
Liveness vs. Readiness
Liveness vs. Readiness
Liveness: Is the application running?
- Used by orchestrators (Kubernetes) to restart unhealthy containers
- Should check minimal critical components
- Fast execution (less than 1 second)
- Used by load balancers to route traffic
- Can check all dependencies
- May take longer to execute
Tagging Health Checks
Tagging Health Checks
Organize health checks with tags:
Timeout Configuration
Timeout Configuration
Prevent health checks from hanging:
Monitoring Integration
Kubernetes Probes
Configure Kubernetes liveness and readiness probes:Prometheus Metrics
Expose health check results as Prometheus metrics:Application Insights
Log health check results to Application Insights:Best Practices
Keep Checks Fast
- Aim for less than 100ms execution time
- Use timeouts to prevent hanging
- Cache results for frequently checked dependencies
- Run expensive checks less frequently
Check What Matters
- Focus on critical dependencies
- Don’t check every internal component
- Prioritize user-facing functionality
- Use degraded status for nice-to-have features
Provide Context
- Include error messages
- Add diagnostic data
- Log health check failures
- Make troubleshooting easier
Test Health Checks
- Verify checks fail when dependencies are down
- Test timeout behavior
- Validate response format
- Ensure checks don’t throw unhandled exceptions
Troubleshooting
Health Check Always Returns Unhealthy
Causes:- Configuration values are incorrect
- Dependency services are not running
- Network connectivity issues
- Health check timeout too short
- Check service status:
docker-compose ps - Verify configuration in appsettings
- Test connections manually
- Review health check logs
- Increase timeout values
Health Check Endpoint Not Found
- Endpoint not mapped in Program.cs
- Route middleware order incorrect
Slow Health Check Response
Causes:- Too many checks running sequentially
- No timeouts configured
- Network latency to dependencies
- Add timeouts to individual checks
- Run checks in parallel (default behavior)
- Cache health status for a few seconds
- Move expensive checks to background tasks
Next Steps
Docker Deployment
Deploy with health check monitoring
Architecture
Learn about system architecture