Architecture & Resilience Best Practices
These are the habits that keep an AWS-backed service resilient as it grows, without requiring a rewrite every time traffic or scope changes.
Busca en todas las páginas de la documentación
These are the habits that keep an AWS-backed service resilient as it grows, without requiring a rewrite every time traffic or scope changes.
Walk the list once now, then treat it as a review checklist whenever you design a new integration or revisit an existing one.
BatchWriteItem, SendMessageBatch, and similar can return partial success in an otherwise-successful response.Check the response's per-item results, not just the overall status.
# --- Python (boto3) ---
resp = sqs.send_message_batch(QueueUrl=queue_url, Entries=entries)
for failed in resp.get("Failed", []):
print("failed:", failed["Id"], failed["Code"]) # re-drive these// --- TypeScript (AWS SDK v3) ---
const resp = await sqs.send(new SendMessageBatchCommand({ QueueUrl: queueUrl, Entries: entries }));
for (const failed of resp.Failed ?? []) {
console.log("failed:", failed.Id, failed.Code); // re-drive these
}attribute_not_exists condition is race-free; a separate read-then-write is not.Start with Group A - handle throttling, eventual consistency, and partial failure explicitly - since the rest of the section builds on treating those as normal, expected conditions rather than edge cases.
No. Reserve breakers for dependencies whose sustained failure meaningfully affects your service. A rarely-called, low-stakes dependency does not need one.
No. At-least-once triggers like SQS standard queues, and any circuit breaker letting calls back through after reopening, can redeliver or retry without your code explicitly asking for it - so idempotent design matters even for "automatic" retries.
When a mistake or compromise in one environment or team's resources should not be able to reach another's. Small prototypes can reasonably stay in one account; production workloads handling real data or spend usually should not.
If reversing it later would be expensive - in migration effort, cost, or risk - it is worth recording. Routine implementation choices that are easy to change later usually are not.
Adding resilience patterns (a breaker, a bulkhead, an idempotency guard) around one dependency or operation at a time, driven by evidence it needs one, rather than redesigning the whole service's architecture in a single big-bang effort.
Whenever you add a new downstream dependency, cross a new account boundary, or the service's traffic or scope changes meaningfully - a pattern that was fine at low volume can violate several of these practices once it grows.
No, it condenses them into a review checklist. Each item links conceptually back to a page - Designing for AWS's Failure Modes, Circuit Breakers & Bulkheads, and the rest - for the full reasoning and code.
Stack versions: This page was written for boto3 1.43.x (Python 3.10+) and the AWS SDK for JavaScript v3 (Node.js 18+).
Revisado por Chris St. John·Última actualización: 23 jul 2026