# Add a startup probe for a slow-starting app

> A Java service needs a minute to start and its liveness probe kills it first. Give it a startup probe without weakening the liveness check.

Level: Intermediate · Topic: Workloads · About 10 minutes
Try it in the browser: https://k8wiz.com/playground/add-a-startup-probe-for-a-slow-app

The playground is a simulated Kubernetes cluster that runs in the browser. kubectl output and errors follow the real ones.

## The situation

`billing` loads a large cache before it listens on port 8080, which takes about a minute. Its Pods restart again and again and never become Ready.

The liveness probe is right for a running app: if billing hangs, it should be restarted within 30 seconds. It just shouldn't apply while billing is starting.

## Objectives

1. See what restarts billing (`kubectl describe pod -l app=billing` and `kubectl logs`)
2. billing has a startup probe that allows its warm-up (The probe may fail for longer than the minute billing needs)
3. Both billing Pods are Ready, with no restarts
4. Liveness still restarts a hung billing within 30 seconds (No long `initialDelaySeconds` on the liveness probe)

## Hints

1. `kubectl describe pod -l app=billing` shows `Liveness probe failed: ... connection refused` and `Container billing failed liveness probe, will be restarted`. `kubectl logs` shows the cache loading.
2. A `startupProbe` runs first. Until it succeeds, the kubelet runs no liveness or readiness probe. It may fail `failureThreshold` times, `periodSeconds` apart, before the container is restarted.
3. `failureThreshold: 12` with `periodSeconds: 10` gives billing up to 2 minutes to start.
4. kubectl patch deployment billing -p '{"spec":{"template":{"spec":{"containers":[{"name":"billing","startupProbe":{"httpGet":{"path":"/healthz","port":"http"},"periodSeconds":10,"failureThreshold":12}}]}}}}'

## Solution

```bash
kubectl describe pod -l app=billing
```
```bash
kubectl patch deployment billing -p '{"spec":{"template":{"spec":{"containers":[{"name":"billing","startupProbe":{"httpGet":{"path":"/healthz","port":"http"},"periodSeconds":10,"failureThreshold":12}}]}}}}'
```
```bash
kubectl rollout status deployment billing --timeout=170s
```

## What it teaches

- A liveness probe that fails while the app starts turns a slow start into a crash loop.
- A startup probe covers the start only. Once it passes, the liveness and readiness probes take over with their own short timings.
- Raising the liveness probe's `initialDelaySeconds` also stops the restarts, but then a hung app goes unnoticed for as long after every restart.
- Size the startup budget, `failureThreshold` × `periodSeconds`, for the slowest start you expect, with some room.
