.NET Resiliency
Goal
Apply resilience patterns carefully and pragmatically in distributed .NET systems.
Use this skill for
- Retry
- Timeout
- Circuit breaker
- Fallback
- Idempotency
- External dependency failures
- Fault handling in distributed flows
- Transactional consistency trade-offs
Core rules
- Use
Microsoft.Extensions.Http.Resiliencepackage - Retry only transient failures.
- Never retry validation or business rule failures.
- Always pair retries with bounded attempts and backoff.
- Use timeout to prevent resource exhaustion.
- Use circuit breaker to fail fast when a dependency is unhealthy.
- Explain trade-offs before adding fallback behavior.
- Design side-effecting operations to be idempotent when retried.
- Consider Workflow Core for long-running orchestration that needs explicit retries, compensation, or recoverable workflow state.
Circuit breaker guidance
When the circuit is open:
- fail fast
- avoid hammering the dependency
- preserve observability
- decide explicitly what happens to the request or message
Possible strategies:
- return a controlled failure for synchronous calls
- reschedule or retry later for async flows
- send terminal failures to dead-letter or manual handling paths when appropriate
Idempotency
Prefer:
- idempotency keys
- unique constraints where valid
- processing ledgers / integration registers
- safe re-entry in handlers
Check:
- every retryable operation has a stable unique identifier, such as
requestId,eventId, message id, or idempotency key - deduplication logic records processing outcomes before acknowledging externally retried work when appropriate
- database constraints enforce uniqueness for operations that must only happen once
- side effects such as payments, emails, external API calls, publishes, and state transitions cannot be duplicated by retry or replay
- concurrent attempts cannot bypass idempotency through race conditions
- check potential issues when race conditions or concurrent processing can cause multiple attempts to succeed when only one should, such as:
- two messages with the same id being processed at the same time
- a retry attempt starting before the original attempt has recorded its outcome
- retry behavior is coordinated with transactions, outbox/inbox records, message commits, and external dependency semantics
- failure recovery, what happens when any dependency is unavailable, and how retries interact with these failure modes
Output style
When suggesting resilience changes, always include:
- failure mode being addressed
- why the pattern fits
- trade-offs
- operational side effects
- idempotency risks and concrete fix suggestions when retry, replay, or redelivery can duplicate side effects