Definition
- Availability – measures whether the system responds when requested; it is about reachability and responsiveness (HTTP status codes, latency).
- Reliability – measures whether the system continues to produce correct behavior over time; it is about correctness and consistency of state.
- Silent Incorrectness – a service returning success while the underlying state is wrong; accumulates undetected and requires painful remediation.
- Correctness SLI – a service level indicator that measures business outcomes (fraction of transfers settled correctly), not just endpoint reachability.
- Reconciliation – comparing intended versus actual state to detect correctness failures independent of HTTP status codes.
Availability at National Bank of India means the counter is open and the clerk stamps "done" on every form. Reliability means the stamp is actually true: the money really moved and the balance is really correct. A clerk who always stamps "done" but quietly drops half the forms in the bin has perfect availability and disastrous reliability.
Understanding the Concepts
What is the difference between availability and reliability?
Availability asks: when a request arrives, does the system accept it and return a response in acceptable time? Reliability asks: over time, does the system keep producing correct outcomes?
package com.bank.observability;
public class AvailabilityVsReliability {
public static void main(String[] args) {
System.out.println("Availability: Did the system respond? (reachability)");
System.out.println(" Measured by: HTTP status codes, latency");
System.out.println();
System.out.println("Reliability: Was the response correct? (correctness)");
System.out.println(" Measured by: actual business outcomes, reconciliation");
System.out.println();
System.out.println("These are INDEPENDENT. A system can be:");
System.out.println(" Available + Reliable: responds AND correct ← GOAL");
System.out.println(" Available + Unreliable: responds but WRONG ← DANGEROUS");
System.out.println(" Unavailable + Reliable: down, but when up it's correct");
}
}
Availability: Did the system respond? (reachability) Measured by: HTTP status codes, latency Reliability: Was the response correct? (correctness) Measured by: actual business outcomes, reconciliation These are INDEPENDENT. A system can be: Available + Reliable: responds AND correct ← GOAL Available + Unreliable: responds but WRONG ← DANGEROUS Unavailable + Reliable: down, but when up it's correct
How can a service score 99.99% availability while being disastrous?
A payment service can accept a transfer, return 200, and the actual money movement can silently fail downstream. Every one of those counts as a success by an availability metric that only checks status codes.
package com.bank.observability;
import java.math.BigDecimal;
public class SilentCorruption {
public static void main(String[] args) {
int totalTransfers = 10000;
int httpSuccess = 9999;
int actuallySettledCorrectly = 9500;
double availability = (double) httpSuccess / totalTransfers * 100;
double reliability = (double) actuallySettledCorrectly / totalTransfers * 100;
System.out.printf("Availability (HTTP 200 rate): %.2f%%%n", availability);
System.out.printf("Reliability (actually settled correctly): %.2f%%%n", reliability);
System.out.println();
System.out.println("500 transfers returned 200 but money did not move correctly");
System.out.println("Dashboard: green. Reality: disaster.");
}
}
Availability (HTTP 200 rate): 99.99%
Reliability (actually settled correctly): 95.00%
500 transfers returned 200 but money did not move correctly
Dashboard: green. Reality: disaster.
Why is silent incorrectness worse than an outage?
An outage is visible and self-correcting once fixed. Silent incorrectness accumulates undetected and surfaces later as a painful reconciliation exercise.
package com.bank.observability;
public class SilentVsVisible {
public static void main(String[] args) {
System.out.println("Outage (visible failure):");
System.out.println(" - Detected immediately by monitoring");
System.out.println(" - Fix the bug → system recovers");
System.out.println(" - No wrong state to clean up");
System.out.println();
System.out.println("Silent incorrectness:");
System.out.println(" - NOT detected by availability monitoring");
System.out.println(" - Accumulates for days or weeks");
System.out.println(" - Discovered by customer complaints or auditors");
System.out.println(" - Requires manual reconciliation of thousands of accounts");
System.out.println(" - Possible regulatory consequences");
}
}
Outage (visible failure): - Detected immediately by monitoring - Fix the bug → system recovers - No wrong state to clean up Silent incorrectness: - NOT detected by availability monitoring - Accumulates for days or weeks - Discovered by customer complaints or auditors - Requires manual reconciliation of thousands of accounts - Possible regulatory consequences
How do you measure correctness SLIs?
Instrument the actual outcome. Compare intended versus actual state through reconciliation.
package com.bank.observability;
public class CorrectnessSli {
public static void main(String[] args) {
// BAD SLI: just HTTP status
int httpSuccess = 9999;
int httpTotal = 10000;
System.out.printf("Availability SLI: %.2f%% (BLIND to correctness)%n",
(double) httpSuccess / httpTotal * 100);
// GOOD SLI: reconciliation-based
long initiated = 10000;
long settledCorrectly = 9500;
System.out.printf("Reliability SLI: %.2f%% (measures actual outcomes)%n",
(double) settledCorrectly / initiated * 100);
System.out.println();
System.out.println("The reliability SLI catches the 500 silent failures");
System.out.println("that the availability SLI misses entirely.");
}
}
Availability SLI: 99.99% (BLIND to correctness)
Reliability SLI: 95.00% (measures actual outcomes)
The reliability SLI catches the 500 silent failures
that the availability SLI misses entirely.
Why does reliability dominate availability for financial systems?
If forced to choose, a bank would rather fail a transfer honestly (hurting availability) than complete it incorrectly (hurting reliability).
package com.bank.observability;
public class ReliabilityDominates {
public static void main(String[] args) {
System.out.println("Scenario A: Transfer fails with HTTP 500 (visible error)");
System.out.println(" Customer retries. Money is correct. Routine.");
System.out.println();
System.out.println("Scenario B: Transfer returns HTTP 200 but wrong amount posted");
System.out.println(" Customer's balance is wrong. Trust destroyed.");
System.out.println(" Regulatory investigation. Manual remediation.");
System.out.println();
System.out.println("For a bank, Scenario B is FAR worse than Scenario A.");
System.out.println("Reliability > Availability.");
}
}
Scenario A: Transfer fails with HTTP 500 (visible error)
Customer retries. Money is correct. Routine.
Scenario B: Transfer returns HTTP 200 but wrong amount posted
Customer's balance is wrong. Trust destroyed.
Regulatory investigation. Manual remediation.
For a bank, Scenario B is FAR worse than Scenario A.
Reliability > Availability.
What design patterns protect reliability?
Idempotency, transactional boundaries, outbox patterns, and reconciliation jobs exist to ensure that what the system reports as done actually happened correctly.
package com.bank.observability;
public class ReliabilityPatterns {
public static void main(String[] args) {
System.out.println("Patterns that protect reliability:");
System.out.println(" 1. Idempotency keys → exactly-once semantics");
System.out.println(" 2. Transactional outbox → atomic write + event publish");
System.out.println(" 3. Reconciliation jobs → detect intended vs actual mismatch");
System.out.println(" 4. Synthetic transactions → end-to-end verification");
System.out.println(" 5. Alert on correctness SLI, not just error rate");
}
}
Patterns that protect reliability: 1. Idempotency keys → exactly-once semantics 2. Transactional outbox → atomic write + event publish 3. Reconciliation jobs → detect intended vs actual mismatch 4. Synthetic transactions → end-to-end verification 5. Alert on correctness SLI, not just error rate
What are common mistakes?
Optimizing the availability number by swallowing errors and returning 200 is optimizing the wrong metric.
package com.bank.observability;
// WRONG: catch all exceptions, return 200
// "Our error rate is 0%!" → actually, errors are hidden, state is wrong
// CORRECT: fail honestly with 500, measure correctness via reconciliation
// Error rate is higher, but every success is REAL
What are common interview follow-up questions?
- How do you implement a reconciliation job for transfer correctness?
- What is the difference between an SLI, SLO, and SLA in this context?
- How do synthetic transactions help measure end-to-end reliability?
- When can availability and reliability be in tension?
Visual Overview
Availability vs Reliability
───────────────────────────
Availability (reachability):
Request ──► Service ──► HTTP 200
Metric: 200 count / total count = 99.99%
Blindness: does NOT check if money actually moved
Reliability (correctness):
Request ──► Service ──► HTTP 200
│
▼
Reconciliation: intended vs actual
┌──────────────────────────────┐
│ Transfer TRF-001: │
│ Intended: 50,000 to Priya │
│ Actual: 0 to Priya │
│ Status: MISMATCH │
└──────────────────────────────┘
Metric: correct count / initiated = 95.00%
The 4.99% gap is INVISIBLE to availability monitoring.
Key Takeaway
Availability and reliability answer two different questions. Availability measures whether the system responds. Reliability measures whether the response is correct. A service can score flawless availability while silently producing wrong financial state, which is far worse than an outage because silent incorrectness accumulates undetected and surfaces as a painful reconciliation exercise.
SLIs for financial systems must measure business correctness: the fraction of transfers that actually settled with correct balances, not just the fraction returning HTTP 200. Correctness SLIs require reconciliation, synthetic end-to-end transactions, and intended-versus-actual comparison.
For a bank, reliability dominates availability. A visible failure is routine and recoverable. Wrong money movement is a trust and regulatory catastrophe. A system that optimizes its availability number by swallowing errors is optimizing the wrong metric.
Remember one sentence: measure whether the transfer actually settled correctly, not just whether the endpoint returned 200, because a cheerful success over wrong financial state is worse than an honest error.
---