Model of Patroni Active Failure
RTO Timeline
Failure Model
| Item | Best | Worst | Average | Description |
|---|---|---|---|---|
| Crash Found | 0 | loop | loop/2 | Best: PG crashes right before check Worst: PG crashes right after check |
| Restart Timeout | 0 | start | start | Best: PG recovers instantly Worst: Wait full start timeout before releasing lease |
| Replica Detect | 0 | loop | loop/2 | Best: Right at check point Worst: Just missed check point |
| Elect Promote | 0 | 2 | 1 | Best: Acquire lock and promote directly Worst: API timeout + Promote |
| HAProxy Check | (rise-1) × fastinter | (rise-1) × fastinter + inter | (rise-1) × fastinter + inter/2 | Best: State changes before check Worst: State changes right after check |
Key Difference Between Active and Passive Failure:
| Scenario | Patroni Status | Lease Handling | Main Wait Time |
|---|---|---|---|
| Active Failure (PG crash) | Alive, healthy | Actively tries to restart PG, releases lease after timeout | primary_start_timeout |
| Passive Failure (node down) | Dies with node | Cannot actively release, must wait for TTL expiry | ttl |
During active failure, Patroni remains available. It detects a PostgreSQL crash and attempts a restart. If restart succeeds, service recovers locally. If recovery times out, Patroni releases the Leader Key and triggers an election.
Timing Analysis
Phase 1: Failure Detection
Each loop_wait cycle, Patroni checks PostgreSQL through pg_isready or a process check.
- Best case: PG crashes right before Patroni check, detected immediately, wait
0 - Worst case: PG crashes right after check, wait for next cycle, wait
loop - Average case:
loop/2
Phase 2: Restart Timeout
After detecting a crash, Patroni attempts to restart PostgreSQL. There are two possible results:
Path A: Self-healing Success (Best case)
- PostgreSQL restarts and service recovers.
- No failover occurs, so RTO is very short.
- Wait:
0relative to the failover path.
Path B: Failover Required (Average/Worst case)
- PostgreSQL does not recover before
primary_start_timeout. - Patroni releases the Leader Key.
- Wait:
start.
Note: The average assumes failover is necessary. A quick local restart can substantially reduce RTO.
Phase 3: Standby Detection
Standbys check the DCS Leader Key each loop_wait cycle. After the primary releases it, they detect its absence and begin an election.
- Best case: Standby wakes right when lease is released, wait
0 - Worst case: Standby just went to sleep when lease released, wait
loop - Average case:
loop/2
Phase 4: Lock & Promote
When the Leader Key is absent, standbys begin an election. The winner acquires the key and runs pg_ctl promote.
- Query standby replication positions in parallel through REST APIs. Typical response time is 10ms; the hardcoded timeout is 2s.
- Compare WAL positions and select the best candidate. Standbys attempt atomic CAS creation of the Leader Key.
- Run
pg_ctl promote. Its duration is usually negligible.
- Best case: Single standby or direct lock acquisition and promote, constant overhead
0.1s - Worst case: DCS API call timeout:
2s - Average case:
1sconstant overhead
Phase 5: Health Check
HAProxy requires rise consecutive successful checks before it marks the new primary healthy.
- Best case: New primary comes up right at check time,
(rise-1) × fastinter - Worst case: New primary comes up right after check,
(rise-1) × fastinter + inter - Average case:
(rise-1) × fastinter + inter/2
RTO Formula
Add the phase durations to calculate total RTO:
Best Case (PG instant self-healing)
Average Case (Failover required)
Worst Case
Model Calculation
Apply the four RTO presets to these formulas:
Calculation Results for Four Modes (unit: seconds, format: min / avg / max)
| Phase | fast | norm | safe | wide |
|---|---|---|---|---|
| Failure Detection | 0 / 3 / 5 | 0 / 3 / 5 | 0 / 5 / 10 | 0 / 10 / 20 |
| Restart Timeout | 0 / 15 / 15 | 0 / 25 / 25 | 0 / 45 / 45 | 0 / 95 / 95 |
| Standby Detection | 0 / 3 / 5 | 0 / 3 / 5 | 0 / 5 / 10 | 0 / 10 / 20 |
| Lock & Promote | 0 / 1 / 2 | 0 / 1 / 2 | 0 / 1 / 2 | 0 / 1 / 2 |
| Health Check | 1 / 2 / 2 | 2 / 3 / 4 | 3 / 5 / 6 | 4 / 6 / 8 |
| Total | 1 / 24 / 29 | 2 / 35 / 41 | 3 / 61 / 73 | 4 / 122 / 145 |
Comparison with Passive Failure
| Phase | Active Failure (PG crash) | Passive Failure (node down) | Description |
|---|---|---|---|
| Detection Mechanism | Patroni active detection | TTL passive expiry | Active detection discovers failure faster |
| Core Wait | start | ttl | start is usually less than ttl, but requires additional failure detection time |
| Lease Handling | Active release | Passive expiry | Active release is more timely |
| Self-healing Possible | Yes | No | Active detection can attempt local recovery |
RTO Comparison (Average case):
| Mode | Active Failure (PG crash) | Passive Failure (node down) | Difference |
|---|---|---|---|
| fast | 24s | 23s | +1s |
| norm | 35s | 34s | +1s |
| safe | 61s | 66s | -5s |
| wide | 122s | 127s | -5s |
Analysis: In
fastandnorm, active failures wait forprimary_start_timeout(start), making RTO slightly longer than for passive failures. Insafeandwide,start < ttl - loop, so active recovery is faster. A successful local restart can make the best-case active RTO much shorter.
Was this page helpful?
Thanks—your feedback helps us improve this page.
What got in the way? (optional)