📘 System Design - Concepts

Reliability in System Design

Reliability means the ability of a system to consistently perform the correct operation over a period of time.For example, imagine a banking application that is always accessible, but sometimes transfers the same payment twice.

S

Site Administrator

📅 Sep 26, 2026 🕒 12 min read 👁 42 views
☆ Save 𝕏 in f ✆
Reliability in System Design

Reliability means the ability of a system to consistently perform the correct operation and produce the expected result.

A system can be available but still not be reliable.

For example, a banking application may be running and accepting requests, but if a money transfer sometimes deducts money without completing the transfer, the system is not reliable.

Reliability is about correctness, consistency and dependable behavior.

What Is Reliability?

Consider an online payment system.

A customer pays ₹1,000.

The expected result is:

  • ₹1,000 is deducted from the customer.
  • Payment is recorded.
  • The merchant receives the payment status.
  • The customer receives confirmation.

If the system sometimes performs only some of these operations, we have a reliability problem.

flowchart LR
    User --> PaymentAPI
    PaymentAPI --> PaymentService
    PaymentService --> Database
    PaymentService --> Bank

Availability vs Reliability

Availability and reliability are related, but they are not the same.

Availability: Is the system available to receive requests?

Reliability: Does the system correctly process those requests?

For example, an API can return HTTP 200 for every request and still be unreliable if it stores incorrect data.

Availability Reliability
System is accessible System behaves correctly
Focuses on uptime Focuses on correct and dependable operation
Can users reach the system? Can users trust the result?

Real-World Example: Money Transfer

Suppose a customer transfers ₹5,000 from Account A to Account B.

The operation should be:

flowchart TD
    Request --> Debit
    Debit --> Credit
    Credit --> Record
    Record --> Success

But imagine the application deducts ₹5,000 from Account A and then crashes before crediting Account B.

Now the system has produced an incorrect result.

This is a reliability problem.

Database Transaction

SQL Server transactions can help keep related database operations together.

For example:

BEGIN TRANSACTION;
UPDATE Accounts
SET Balance = Balance - 5000
WHERE Id = 1;
UPDATE Accounts
SET Balance = Balance + 5000
WHERE Id = 2;
COMMIT TRANSACTION;

If an error occurs before the transaction is committed, we can roll back the transaction.

BEGIN TRANSACTION;
UPDATE Accounts
SET Balance = Balance - 5000
WHERE Id = 1;
UPDATE Accounts
SET Balance = Balance + 5000
WHERE Id = 2;
IF @@ERROR <> 0
BEGIN
    ROLLBACK TRANSACTION;
END
ELSE
BEGIN
    COMMIT TRANSACTION;
END

This helps ensure that the two database operations are treated as one unit.

ASP.NET Core Example

The same concept can be implemented using Entity Framework Core.

public async Task TransferMoney(
    int fromAccount,
    int toAccount,
    decimal amount)
{
    await using var transaction =
        await _context.Database.BeginTransactionAsync();
    try
    {
        var source = await _context.Accounts
            .FirstAsync(x => x.Id == fromAccount);
        var destination = await _context.Accounts
            .FirstAsync(x => x.Id == toAccount);
        if (source.Balance < amount)
            throw new Exception("Insufficient balance");
        source.Balance -= amount;
        destination.Balance += amount;
        await _context.SaveChangesAsync();
        await transaction.CommitAsync();
    }
    catch
    {
        await transaction.RollbackAsync();
        throw;
    }
}

If the operation fails before the commit, the transaction is rolled back.

What Can Make a System Unreliable?

Several problems can affect reliability.

  • Application crashes
  • Database failures
  • Network failures
  • Timeouts
  • Duplicate requests
  • Race conditions
  • Partial failures
  • Incorrect retry logic
  • Data corruption
  • External service failures

Handling External Service Failures

Consider an order application that calls a payment provider.

flowchart LR
    User --> OrderAPI
    OrderAPI --> PaymentService
    PaymentService --> PaymentProvider

What happens if the payment provider does not respond?

The application should not wait forever.

We can use a timeout.

using var cts =
    new CancellationTokenSource(
        TimeSpan.FromSeconds(5));
var response = await httpClient.PostAsync(
    "payment",
    content,
    cts.Token);

If the external service does not respond within the expected time, the request can fail or move into an appropriate recovery flow.

Retry and Reliability

Some failures are temporary.

For example, a network request may fail once and succeed immediately afterward.

A retry can help in such cases.

flowchart TD
    Request --> Service
    Service --> Success
    Service --> Failure
    Failure --> Retry
    Retry --> Service

But blindly retrying is dangerous.

Imagine a payment request is successfully processed by the payment provider, but the response is lost because of a network failure.

If we simply send the same payment request again, we could potentially create a duplicate payment.

This is why retries often need to be combined with idempotency.

Idempotency

Idempotency means that sending the same operation multiple times should not produce an unintended additional effect.

For example, a payment request could contain a unique idempotency key.

{
    "orderId": 1001,
    "amount": 5000,
    "idempotencyKey": "PAY-1001-ABC123"
}

The system can store the key.

If the same request arrives again, the system can recognize that the operation was already processed.

flowchart TD
    Request --> CheckKey
    CheckKey --> Existing
    CheckKey --> NewRequest
    Existing --> ReturnPreviousResult
    NewRequest --> ProcessPayment
    ProcessPayment --> StoreKey
    StoreKey --> ReturnResult

This is especially important for payment, order creation and other operations where duplicate processing can cause business problems.

Reliability and SQL Server

Reliability also depends on protecting data from incorrect operations.

For example, suppose two users try to purchase the last available product at the same time.

Both requests may read:

Available Quantity = 1

Both may then attempt to reduce the quantity.

This can create incorrect inventory.

Database concurrency control and appropriate transaction strategies are important for such scenarios.

Monitoring Reliability

We cannot improve reliability if we don't know when failures are happening.

Production systems should monitor things such as:

  • Failed requests
  • Database errors
  • Timeouts
  • Exception rates
  • Failed background jobs
  • Payment failures
  • Message processing failures
flowchart LR
    Application --> Logs
    Application --> Metrics
    Application --> Alerts
    Metrics --> Dashboard

For example, if payment failures suddenly increase, monitoring should help the engineering team identify the problem quickly.

Reliability in Distributed Systems

As systems become larger, they contain more components.

flowchart LR
    User --> API
    API --> OrderService
    OrderService --> PaymentService
    OrderService --> InventoryService
    OrderService --> NotificationService
    PaymentService --> Database
    InventoryService --> Database

Each component can fail independently.

This is called a partial failure.

For example, the order service may be working while the notification service is unavailable.

A reliable system should handle such failures gracefully instead of unnecessarily bringing down the entire application.

Key Takeaways

  • Reliability means consistently producing the correct and expected result.
  • Availability means the system is accessible.
  • A system can be available but unreliable.
  • Database transactions help keep related operations consistent.
  • Timeouts prevent the application from waiting indefinitely for external services.
  • Retries can help with temporary failures but must be designed carefully.
  • Idempotency helps prevent duplicate operations.
  • Monitoring and alerting are important for detecting reliability problems.
  • Distributed systems must handle partial failures.

Conclusion

Reliability is about making users confident that the system will do what it is supposed to do.

A reliable system should handle failures without producing incorrect results, duplicate operations or corrupted data.

Transactions, idempotency, timeouts, controlled retries, monitoring and proper failure handling are some of the important techniques used to improve reliability.

Once a system is reliable, we also need to ask another important question:

How quickly can the system process requests?

That brings us to the next concept: Performance.

Reliability means the ability of a system to consistently perform the correct operation and produce the expected result.

A system can be available but still not be reliable.

For example, a banking application may be running and accepting requests, but if a money transfer sometimes deducts money without completing the transfer, the system is not reliable.

Reliability is about correctness, consistency and dependable behavior.

What Is Reliability?

Consider an online payment system.

A customer pays ₹1,000.

The expected result is:

  • ₹1,000 is deducted from the customer.
  • Payment is recorded.
  • The merchant receives the payment status.
  • The customer receives confirmation.

If the system sometimes performs only some of these operations, we have a reliability problem.

flowchart LR
    User --> PaymentAPI
    PaymentAPI --> PaymentService
    PaymentService --> Database
    PaymentService --> Bank

Availability vs Reliability

Availability and reliability are related, but they are not the same.

Availability: Is the system available to receive requests?

Reliability: Does the system correctly process those requests?

For example, an API can return HTTP 200 for every request and still be unreliable if it stores incorrect data.

Availability Reliability
System is accessible System behaves correctly
Focuses on uptime Focuses on correct and dependable operation
Can users reach the system? Can users trust the result?

Real-World Example: Money Transfer

Suppose a customer transfers ₹5,000 from Account A to Account B.

The operation should be:

flowchart TD
    Request --> Debit
    Debit --> Credit
    Credit --> Record
    Record --> Success

But imagine the application deducts ₹5,000 from Account A and then crashes before crediting Account B.

Now the system has produced an incorrect result.

This is a reliability problem.

Database Transaction

SQL Server transactions can help keep related database operations together.

For example:

BEGIN TRANSACTION;
UPDATE Accounts
SET Balance = Balance - 5000
WHERE Id = 1;
UPDATE Accounts
SET Balance = Balance + 5000
WHERE Id = 2;
COMMIT TRANSACTION;

If an error occurs before the transaction is committed, we can roll back the transaction.

BEGIN TRANSACTION;
UPDATE Accounts
SET Balance = Balance - 5000
WHERE Id = 1;
UPDATE Accounts
SET Balance = Balance + 5000
WHERE Id = 2;
IF @@ERROR <> 0
BEGIN
    ROLLBACK TRANSACTION;
END
ELSE
BEGIN
    COMMIT TRANSACTION;
END

This helps ensure that the two database operations are treated as one unit.

ASP.NET Core Example

The same concept can be implemented using Entity Framework Core.

public async Task TransferMoney(
    int fromAccount,
    int toAccount,
    decimal amount)
{
    await using var transaction =
        await _context.Database.BeginTransactionAsync();
    try
    {
        var source = await _context.Accounts
            .FirstAsync(x => x.Id == fromAccount);
        var destination = await _context.Accounts
            .FirstAsync(x => x.Id == toAccount);
        if (source.Balance < amount)
            throw new Exception("Insufficient balance");
        source.Balance -= amount;
        destination.Balance += amount;
        await _context.SaveChangesAsync();
        await transaction.CommitAsync();
    }
    catch
    {
        await transaction.RollbackAsync();
        throw;
    }
}

If the operation fails before the commit, the transaction is rolled back.

What Can Make a System Unreliable?

Several problems can affect reliability.

  • Application crashes
  • Database failures
  • Network failures
  • Timeouts
  • Duplicate requests
  • Race conditions
  • Partial failures
  • Incorrect retry logic
  • Data corruption
  • External service failures

Handling External Service Failures

Consider an order application that calls a payment provider.

flowchart LR
    User --> OrderAPI
    OrderAPI --> PaymentService
    PaymentService --> PaymentProvider

What happens if the payment provider does not respond?

The application should not wait forever.

We can use a timeout.

using var cts =
    new CancellationTokenSource(
        TimeSpan.FromSeconds(5));
var response = await httpClient.PostAsync(
    "payment",
    content,
    cts.Token);

If the external service does not respond within the expected time, the request can fail or move into an appropriate recovery flow.

Retry and Reliability

Some failures are temporary.

For example, a network request may fail once and succeed immediately afterward.

A retry can help in such cases.

flowchart TD
    Request --> Service
    Service --> Success
    Service --> Failure
    Failure --> Retry
    Retry --> Service

But blindly retrying is dangerous.

Imagine a payment request is successfully processed by the payment provider, but the response is lost because of a network failure.

If we simply send the same payment request again, we could potentially create a duplicate payment.

This is why retries often need to be combined with idempotency.

Idempotency

Idempotency means that sending the same operation multiple times should not produce an unintended additional effect.

For example, a payment request could contain a unique idempotency key.

{
    "orderId": 1001,
    "amount": 5000,
    "idempotencyKey": "PAY-1001-ABC123"
}

The system can store the key.

If the same request arrives again, the system can recognize that the operation was already processed.

flowchart TD
    Request --> CheckKey
    CheckKey --> Existing
    CheckKey --> NewRequest
    Existing --> ReturnPreviousResult
    NewRequest --> ProcessPayment
    ProcessPayment --> StoreKey
    StoreKey --> ReturnResult

This is especially important for payment, order creation and other operations where duplicate processing can cause business problems.

Reliability and SQL Server

Reliability also depends on protecting data from incorrect operations.

For example, suppose two users try to purchase the last available product at the same time.

Both requests may read:

Available Quantity = 1

Both may then attempt to reduce the quantity.

This can create incorrect inventory.

Database concurrency control and appropriate transaction strategies are important for such scenarios.

Monitoring Reliability

We cannot improve reliability if we don't know when failures are happening.

Production systems should monitor things such as:

  • Failed requests
  • Database errors
  • Timeouts
  • Exception rates
  • Failed background jobs
  • Payment failures
  • Message processing failures
flowchart LR
    Application --> Logs
    Application --> Metrics
    Application --> Alerts
    Metrics --> Dashboard

For example, if payment failures suddenly increase, monitoring should help the engineering team identify the problem quickly.

Reliability in Distributed Systems

As systems become larger, they contain more components.

flowchart LR
    User --> API
    API --> OrderService
    OrderService --> PaymentService
    OrderService --> InventoryService
    OrderService --> NotificationService
    PaymentService --> Database
    InventoryService --> Database

Each component can fail independently.

This is called a partial failure.

For example, the order service may be working while the notification service is unavailable.

A reliable system should handle such failures gracefully instead of unnecessarily bringing down the entire application.

Key Takeaways

  • Reliability means consistently producing the correct and expected result.
  • Availability means the system is accessible.
  • A system can be available but unreliable.
  • Database transactions help keep related operations consistent.
  • Timeouts prevent the application from waiting indefinitely for external services.
  • Retries can help with temporary failures but must be designed carefully.
  • Idempotency helps prevent duplicate operations.
  • Monitoring and alerting are important for detecting reliability problems.
  • Distributed systems must handle partial failures.

Conclusion

Reliability is about making users confident that the system will do what it is supposed to do.

A reliable system should handle failures without producing incorrect results, duplicate operations or corrupted data.

Transactions, idempotency, timeouts, controlled retries, monitoring and proper failure handling are some of the important techniques used to improve reliability.

Once a system is reliable, we also need to ask another important question:

How quickly can the system process requests?

That brings us to the next concept: Performance.

Comments & Ratings (0)

Log in or create a student account to comment and rate this article.

Be the first to comment on this article.

Never miss a new post 📬

Get an email whenever a new article, project, cheatsheet or video drops.

✅

ℹ️