Spring Boot
Server Startup
Database Connection
Application Resilience
Java Configuration

How to make Spring server to start even if database is down?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

By default, many Spring Boot applications fail startup when the database is unavailable. That behavior is reasonable for strict systems, but some architectures need the process to start and report not ready while dependencies recover. The safe pattern is startup tolerance plus explicit readiness gating and strong observability.

Configure DataSource for Non Fail Fast Startup

With HikariCP, set initialization behavior so startup does not fail immediately on first connection attempt.

yaml
1spring:
2  datasource:
3    url: jdbc:postgresql://db:5432/app
4    username: app
5    password: secret
6    hikari:
7      initializationFailTimeout: 0
8      connectionTimeout: 3000

initializationFailTimeout: 0 allows app boot even if the first connection attempt fails.

Keep connection timeout bounded so blocked calls do not hang worker threads.

Separate Startup from Readiness

Starting process and serving traffic are different concerns. Use health probes so orchestrators hold traffic until dependencies are available.

yaml
1management:
2  endpoint:
3    health:
4      probes:
5        enabled: true
6  endpoints:
7    web:
8      exposure:
9        include: health,info

Readiness endpoint check:

bash
curl -s http://localhost:8080/actuator/health/readiness

Liveness can remain up while readiness stays down during database outage.

Avoid Early Database Access During Boot

Even with tolerant datasource settings, startup can fail if code touches repositories in boot hooks such as @PostConstruct, ApplicationRunner, or eager cache loaders.

Move database work to request time or scheduled background workers with retry logic.

java
1import org.springframework.web.bind.annotation.GetMapping;
2import org.springframework.web.bind.annotation.RestController;
3import javax.sql.DataSource;
4import java.sql.Connection;
5
6@RestController
7class DbStatusController {
8    private final DataSource dataSource;
9
10    DbStatusController(DataSource dataSource) {
11        this.dataSource = dataSource;
12    }
13
14    @GetMapping("/db-status")
15    String status() {
16        try (Connection c = dataSource.getConnection()) {
17            return c.isValid(2) ? "db-up" : "db-down";
18        } catch (Exception ex) {
19            return "db-down";
20        }
21    }
22}

This keeps startup lightweight while still exposing dependency state.

Handle Flyway or Liquibase Behavior

Migration tools can force startup failure when DB is down. Decide policy explicitly:

  • strict mode for production critical consistency.
  • tolerant mode where migrations run separately.

Example tolerant profile:

yaml
spring:
  flyway:
    enabled: false

If migrations are disabled at startup, ensure a separate controlled migration pipeline exists before enabling traffic.

Use Profiles for Environment Specific Strategy

Different environments may need different startup rules.

yaml
1# application-resilient.yml
2spring:
3  datasource:
4    hikari:
5      initializationFailTimeout: 0

Run with profile:

bash
java -jar app.jar --spring.profiles.active=resilient

This keeps strict and tolerant behavior explicit and avoids accidental drift.

Add Retry and Alerting

Startup tolerance should not hide prolonged outages. Add operational controls:

  • alert when readiness remains down beyond threshold.
  • monitor pool exhaustion and connection failure rates.
  • expose dependency health in dashboards.

Application startup success should not be treated as dependency success.

Controller and Job Design Considerations

When database may be unavailable during startup, controllers and scheduled jobs should fail gracefully rather than throwing unhandled exceptions. Return clear temporary dependency error responses and backoff in background tasks.

Practical guidance:

  1. Wrap repository calls in resilience patterns where appropriate.
  2. Keep retry intervals bounded.
  3. Emit structured logs with dependency state context.

This keeps runtime behavior predictable while infrastructure recovers. It also gives operations teams clearer evidence when deciding whether to scale, restart, or fail over components.

Common Pitfalls

  • Allowing startup without readiness gating and serving immediate failing requests.
  • Leaving repository calls in startup hooks that still force DB dependency.
  • Disabling migration tools without a replacement schema workflow.
  • Confusing liveness success with full application readiness.
  • Adding long synchronous retries in request threads and exhausting pools.

Summary

  • Configure datasource startup to avoid fail fast when outage tolerance is required.
  • Separate process startup from readiness driven traffic acceptance.
  • Remove early repository calls from boot lifecycle hooks.
  • Define clear migration strategy for tolerant startup modes.
  • Add alerting so tolerated startup does not mask persistent dependency failure.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.