Well-Architected Framework Through an SDK Lens
The AWS Well-Architected Framework is usually discussed at the infrastructure level - a formal review, Trusted Advisor findings, a whitepaper about VPC design.
Search across all documentation pages
The AWS Well-Architected Framework is usually discussed at the infrastructure level - a formal review, Trusted Advisor findings, a whitepaper about VPC design.
But its six pillars apply just as directly to the SDK code a service calls AWS with, not just to the infrastructure that code runs on. This page walks each pillar through the lens of the code decisions covered throughout this cookbook, so the framework becomes something you apply while writing a client call, not just during a quarterly architecture review.
Treat each Well-Architected pillar as a lens for reviewing SDK code, not only infrastructure.
# --- Python (boto3) ---
import logging
import boto3
logger = logging.getLogger("orders.service")
# Operational Excellence: structured, request-id-carrying logs.
# Security: least-privilege client, no hardcoded credentials.
# Performance Efficiency: client built once and reused.
ddb = boto3.client("dynamodb", region_name="us-east-1")
def get_order(order_id: str):
try:
resp = ddb.get_item(TableName="orders", Key={"id": {"S": order_id}})
logger.info("order read", extra={"order_id": order_id})
return resp.get("Item")
except ddb.exceptions.ClientError as err:
rid = err.response["ResponseMetadata"]["RequestId"]
logger.error("order read failed", extra={"order_id": order_id, "request_id": rid})
raise// --- TypeScript (AWS SDK v3) ---
import { DynamoDBClient, GetItemCommand } from "@aws-sdk/client-dynamodb";
// Operational Excellence: structured, request-id-carrying logs.
// Security: least-privilege client, no hardcoded credentials.
// Performance Efficiency: client built once and reused.
const ddb = new DynamoDBClient({ region: "us-east-1" });
async function getOrder(orderId: string) {
try {
const resp = await ddb.send(new GetItemCommand({ TableName: "orders", Key: { id: { S: orderId } } }));
console.log(JSON.stringify({ level: "info", msg: "order read", orderId }));
return resp.Item;
} catch (err) {
const requestId = (err as { $metadata?: { requestId?: string } }).$metadata?.requestId;
console.error(JSON.stringify({ level: "error", msg: "order read failed", orderId, requestId }));
throw err;
}
}When to reach for this:
Applying all six pillars to a single design decision: how a service reads a DynamoDB table under load.
# --- Python (boto3) ---
import boto3
# Cost Optimization + Performance Efficiency: paginate and batch instead
# of a naive per-item loop; only fetch attributes actually needed.
ddb = boto3.client("dynamodb", region_name="us-east-1")
def list_open_orders():
paginator = ddb.get_paginator("query")
items = []
for page in paginator.paginate(
TableName="orders",
IndexName="status-index",
KeyConditionExpression="#s = :open",
ExpressionAttributeNames={"#s": "status"},
ExpressionAttributeValues={":open": {"S": "OPEN"}},
ProjectionExpression="id, total_cents", # only what the caller needs
):
items.extend(page["Items"])
return items// --- TypeScript (AWS SDK v3) ---
import { DynamoDBClient, paginateQuery } from "@aws-sdk/client-dynamodb";
// Cost Optimization + Performance Efficiency: paginate and batch instead
// of a naive per-item loop; only fetch attributes actually needed.
const ddb = new DynamoDBClient({ region: "us-east-1" });
async function listOpenOrders() {
const items = [];
const pages = paginateQuery({ client: ddb }, {
TableName: "orders",
IndexName: "status-index",
KeyConditionExpression: "#s = :open",
ExpressionAttributeNames: { "#s": "status" },
ExpressionAttributeValues: { ":open": { S: "OPEN" } },
ProjectionExpression: "id, total_cents", // only what the caller needs
});
for await (const page of pages) items.push(...(page.Items ?? []));
return items;
}What this demonstrates:
ProjectionExpression fetches only the attributes needed, reducing read cost on a wide table.The AWS Well-Architected Framework defines six pillars: Operational Excellence, Security, Reliability, Performance Efficiency, Cost Optimization, and Sustainability. Applied to infrastructure, these usually mean things like CloudWatch dashboards, IAM policy scoping, Multi-AZ deployments, instance right-sizing, Savings Plans, and carbon-aware region choice. Applied to the SDK code your service actually runs, they translate into concrete, reviewable habits.
Operational Excellence at the code level means structured logging that includes the AWS request id (so a support case or an incident review can trace a call precisely), small and observable functions rather than large opaque ones, and treating infrastructure-as-code and deploy scripts with the same review rigor as application code.
Security means least-privilege IAM policies scoped to exactly the actions a piece of code calls, never hardcoded credentials, and secrets resolved through the SDK's default credential chain or a secrets manager rather than embedded in source. Cross-account access follows the same principle at a larger scale, covered in Multi-Account Architecture for AWS SDK Applications.
Reliability means designing for AWS's actual failure modes - throttling, eventual consistency, partial failure - rather than assuming every call succeeds, and using circuit breakers, bulkheads, and idempotent design where retries are involved. This whole section exists largely in service of this one pillar.
Performance Efficiency means reusing SDK clients instead of rebuilding them per call, choosing the right data access pattern (query vs scan, batch vs per-item), and picking instance types, indexes, or read/write capacity modes that match actual traffic shape rather than over-provisioning by default.
Cost Optimization means paginating and batching instead of pulling and processing more data than needed, using events over polling, projecting only needed attributes, and setting budgets and alarms so a runaway loop surfaces quickly rather than at the end of the month.
Sustainability is the newest pillar and, at the code level, mostly overlaps with Performance Efficiency and Cost Optimization: minimizing wasted compute and data transfer (right-sized polling intervals, avoiding unnecessary retries and redundant calls) reduces both cost and the underlying resource consumption.
The value of mapping the pillars to code is that it gives a code reviewer or an architect a structured set of questions to ask about any AWS-integration pull request: does this handle throttling and partial failure (Reliability)? Is the IAM policy scoped tightly (Security)? Is the client reused and the query pattern efficient (Performance Efficiency, Cost Optimization)? Revisit this lens as a service evolves - a pattern that was fine at low traffic can violate several pillars at once once traffic grows.
| Alternative | Use When | Don't Use When |
|---|---|---|
| Full AWS Well-Architected Review (via AWS or a partner) | Periodic, formal, infrastructure-plus-code review of a whole workload | You need a lightweight, ongoing lens for day-to-day code review |
| This code-level pillar lens | Reviewing SDK integration code as it is written or changed | You need the infrastructure-level review (networking, compute sizing) this page does not cover |
| Trusted Advisor checks | Automated, infrastructure-focused checks against some Well-Architected best practices | You need code-level review of application logic and SDK usage |
| No structured framework | Never a good default for production AWS-backed services | - |
Operational Excellence, Security, Reliability, Performance Efficiency, Cost Optimization, and Sustainability.
No, though it is usually discussed that way. Every pillar has a direct code-level analog - logging and observability, IAM scoping, retry/idempotency design, client reuse, pagination and batching, and efficient polling.
Designing for AWS's actual failure modes (throttling, eventual consistency, partial failure), using circuit breakers and bulkheads for struggling dependencies, and making operations idempotent so retries are safe.
Sustainability, added to the original five. At the code level it mostly overlaps with Performance Efficiency and Cost Optimization - minimizing wasted compute, data transfer, and unnecessary retries.
Both have a place. This page's lens is for ongoing code review; a formal review (through AWS or a partner) additionally covers infrastructure-level concerns like networking and instance sizing that this page does not.
Periodically, and especially after a meaningful change in traffic or scale - a pattern that satisfied the pillars at low volume can violate several of them once the service grows.
Stack versions: This page was written for boto3 1.43.x (Python 3.10+) and the AWS SDK for JavaScript v3 (Node.js 18+).
Reviewed by Chris St. John·Last updated Jul 23, 2026