Cheat SheetsInterview Q&AAWS & Cloud

AWS & Cloud — Cheat Sheet

Interview Q&A · 100 topics. Download the PDF or the Instagram carousel and share it.

Cheat Sheet · AiCanCode.org
AWS & Cloud
Interview Q&A100 topicsQuick revision reference
1

What is the shared responsibility model?

The provider is responsible for security *of* the cloud; you are responsible for security *in* the cloud. The provider handles the physical facilities, the hardware, the hypervisor and the managed service software. You handle everything you configure: identity and access, network rules, encryption choices, patching of anything you run, and your application code and data. The line moves with the service model. On EC2 you patch the operating system. On RDS the provider patches the database engine but you still control access, encryption and network placement. On S3 the provider runs everything and you are responsible only for access policy and encryption settings — which is precisely where the well-publicised breaches happen. That is the practical point worth making: almost every major cloud data breach has been a customer misconfiguration rather than a provider failure. Public buckets, over-permissive IAM, and exposed databases. So "we use AWS" is not a security posture. The provider gives you strong primitives and the ability to misuse them, and the responsibility for configuration is entirely yours — including for managed services where it is easy to assume otherwise.

2

What is the difference between a region and an availability zone?

A region is a geographic location — separate power, separate network, and legally distinct. Regions are fully isolated from each other by design, so a regional outage does not cascade. An availability zone is one or more data centres within a region, with independent power, cooling and networking, connected to the other zones by low-latency links. The practical distinction. Zones protect against a data centre failure and are cheap to use — spreading instances across zones within a region is the baseline for availability, and the network between them is fast enough that it is transparent for most applications, though not free. Regions protect against a regional failure, and using several is substantially harder: cross-region latency is tens to hundreds of milliseconds, data replication becomes an explicit design problem, and costs rise. So the default architecture is multi-AZ within one region, which handles the overwhelming majority of failures. Multi-region is for genuine disaster recovery requirements or for serving users in different geographies, and it should be a deliberate decision with a stated recovery objective rather than an aspiration. The detail worth knowing: zone identifiers are randomised per account, so your us-east-1a is not the same physical zone as another account's.

3

How does IAM policy evaluation work?

By default everything is denied. An explicit allow in any applicable policy grants access. An explicit deny anywhere overrides every allow. So the evaluation is: is there an explicit deny? Then deny. Is there an allow? Then allow. Otherwise deny. The policies that apply are the union of several types: identity policies attached to the user or role, resource policies attached to the resource such as a bucket policy, permission boundaries which cap what an identity policy can grant, service control policies at the organisation level which cap everything in an account, and session policies. The practical consequences. A permission boundary or an SCP can prevent an action even though the identity policy allows it, which is the usual explanation for "the policy clearly allows this and it is still denied". Cross-account access requires both sides: the resource policy in the target account and the identity policy in the source. The tools that matter: the IAM policy simulator, and CloudTrail to see the actual denial with its reason. Guessing at policy evaluation is slower than reading the denied event.

4

What is the difference between an IAM role and an IAM user?

A user is a permanent identity with long-lived credentials — an access key or a password. A role is an identity with no credentials of its own, assumed temporarily to obtain short-lived credentials. Roles are almost always the right answer. For anything running on AWS — EC2, Lambda, ECS, EKS — attach a role. The credentials are delivered automatically, rotate themselves, and never need to be stored. An access key in an environment variable or a configuration file is the thing that leaks, and it is the most common root cause of cloud compromise. For humans, federate from an identity provider through SSO so people authenticate against the corporate directory and assume roles, rather than having individual IAM users. That means offboarding removes access in one place. For CI systems, OIDC federation lets the pipeline exchange its identity token for temporary credentials, again with no stored key. So the target state is essentially no IAM users at all. The remaining legitimate cases are narrow — some third-party integrations that cannot assume a role — and each should be justified, scoped tightly, and monitored.

5

How do you scope IAM permissions well?

Start from deny-all and grant specific actions on specific resources, rather than starting broad and narrowing later — which never happens. The practical technique: grant the permissions an application actually uses, discovered by running it with logging and reading the calls, or by using IAM Access Analyzer which generates a policy from CloudTrail history. That produces a far tighter policy than writing one by hand. Scope by resource ARN rather than wildcard. s3:GetObject on a specific bucket prefix is very different from s3:* on everything. Use conditions: restrict by source VPC, by tag, by whether the request is over TLS, or by MFA presence for sensitive actions. Use permission boundaries so a role that can create roles cannot escalate beyond a ceiling — privilege escalation through IAM is a real and often-overlooked path. And use SCPs at the organisation level to prevent whole categories regardless of account-level policy — disabling regions you do not use, or preventing anyone from turning off CloudTrail. The things to watch for: iam:PassRole without a resource constraint, and any policy with Action and Resource both wildcarded.

6

Why use multiple AWS accounts?

Accounts are the strongest isolation boundary AWS provides — stronger than VPCs, tags or IAM policies within one account. The reasons. Blast radius: a mistake or a compromise in a development account cannot touch production, because they are separate trust domains. Within one account, a sufficiently broad IAM policy reaches everything. Quota isolation: service limits are per account, so a runaway process in one environment cannot exhaust capacity for another. Cost attribution: per-account billing makes spend obvious without depending on tagging discipline, which always decays. And simpler policies: an account dedicated to one purpose needs less intricate IAM than one hosting everything. The usual structure is an organisation with accounts per environment and per workload, with SCPs applying guardrails centrally, and a separate account for logging and audit that nobody can write to freely. The cost is management overhead, which Control Tower and Organizations exist to reduce, and cross-account access complexity. The anti-pattern is a single account with everything in it, separated only by tags and naming conventions — which provides no real boundary and is very hard to retrofit.

7

How do you handle credentials for an application running on AWS?

You should not have credentials at all. Attach a role to the compute — an instance profile for EC2, an execution role for Lambda, a task role for ECS, IRSA or Pod Identity for EKS — and the SDK obtains temporary credentials automatically from the instance metadata service. Those credentials rotate themselves and never exist in your configuration, your repository or your environment variables. The SDK credential chain looks in a defined order, so simply not setting any credentials means it finds the role. For secrets that are not AWS credentials — a database password, a third-party API key — use Secrets Manager or Parameter Store, fetched at runtime using the role. Secrets Manager supports automatic rotation, which is its main advantage over Parameter Store; Parameter Store is cheaper. The things to avoid: access keys in environment variables, in a config file, or in the image. And keys in the repository, which is the most common serious mistake. One security detail worth knowing: the metadata service should be configured to require IMDSv2, which uses a session token and defeats the SSRF attack where a vulnerable application is tricked into fetching credentials from the metadata endpoint.

8

What is CloudTrail and what should you do with it?

CloudTrail records API calls made in your account — who called what, when, from where, and whether it succeeded. It is the audit log, and it is the primary tool for two things: investigating an incident, and understanding why a permission was denied. That second use is underrated. A denied call appears in CloudTrail with the principal and the action, which is far faster than reasoning about policy evaluation. The configuration that matters. Enable it in every region, including regions you do not use, since an attacker will use an unmonitored region. Deliver logs to a bucket in a separate logging account that the workload accounts cannot write to or delete from, so a compromise cannot erase the evidence. Enable log file validation. Data events for S3 and Lambda are separate and are not on by default — object-level access is often exactly what you need during an investigation, and discovering it was not recorded is too late. And set up alerting on high-signal events: root account usage, IAM policy changes, security group changes, and CloudTrail being disabled. GuardDuty consumes these logs and provides detection without you writing the rules.

9

What is infrastructure as code and which tool would you choose?

Defining infrastructure in version-controlled files that a tool reconciles, rather than clicking in a console. The benefits: reproducibility, review, history, and the ability to recreate an environment. A console-built environment exists only in one place and nobody knows how it got there. The options. Terraform is cloud-agnostic, has the largest ecosystem, and uses its own declarative language with an explicit state file. OpenTofu is the open-source fork after the licence change. CloudFormation is AWS-native with no state file to manage, since AWS tracks it. CDK lets you write in a real programming language and synthesises CloudFormation, which suits teams who want abstraction and types. Pulumi is similar but multi-cloud. The practical recommendation: Terraform if you are multi-cloud or want the ecosystem; CDK if the team prefers a programming language and you are AWS-only. The things that matter more than the choice: remote state with locking so concurrent applies do not corrupt it, plan output reviewed in the pull request, and drift detection so manual console changes are caught. And never mix console changes with IaC — a resource managed by code and edited by hand produces confusing plans.

10

What are service quotas and why do they cause outages?

Every AWS service has limits — number of instances, API request rates, concurrent Lambda executions, VPC counts, and many more. Some are adjustable, some are hard. They cause outages because they are invisible until you hit them, and you usually hit them at the worst moment: during a traffic spike, during a failover when you are launching replacement capacity, or during a deployment that briefly doubles instance count. The classic examples: Lambda concurrent execution limits throttling under load; EC2 instance limits preventing an auto-scaling group from scaling out; and API rate limits causing throttling that appears as intermittent failures in unrelated services. The practices: know the limits relevant to your architecture, monitor usage against them with CloudWatch — Service Quotas publishes usage metrics — and alert well before the ceiling. Request increases proactively rather than during an incident, because the request takes time and may need justification. And design for throttling: SDKs retry with exponential backoff and jitter by default, but application code should handle throttling errors as a distinct case rather than as a generic failure. Quotas are per account and per region, which is another argument for multiple accounts.

11

What is the difference between IaaS, PaaS and serverless in practice?

The distinction is where the boundary of your operational responsibility sits. IaaS gives you virtual machines — EC2. You manage the operating system, patching, scaling and everything above. Maximum control, maximum operational burden. PaaS gives you a managed runtime — Elastic Beanstalk, App Runner, or a managed database. You provide the application or the schema; the provider handles the infrastructure and much of the operations. Serverless removes the notion of a server from your model entirely — Lambda, S3, DynamoDB, SQS. You are billed for usage rather than for provisioned capacity, scaling is automatic, and there is nothing to patch. The practical trade-offs. Serverless has the lowest operational burden and the best economics at low or spiky load, since idle costs nothing. It has constraints — execution duration, cold starts, limited runtime control — and can be more expensive at sustained high load. IaaS is right when you need specific control, have licensing constraints, or are migrating something as-is. The honest guidance is to prefer managed services unless there is a concrete reason not to, because the operational cost of running things yourself is consistently underestimated.

12

How do you think about the Well-Architected Framework?

It is six pillars AWS uses to structure architecture review: operational excellence, security, reliability, performance efficiency, cost optimisation, and sustainability. The value is as a checklist that prompts questions teams otherwise skip — particularly around failure modes, cost and operations, which get less attention than features. The honest framing is that the pillars are in tension, and the framework does not resolve that for you. Reliability costs money; performance costs money; security adds friction. The engineering work is choosing where on each axis this particular system should sit, based on what it actually needs. A prototype and a payments system warrant different answers, and applying maximum rigour everywhere is its own failure — it is expensive and slows delivery for no benefit. So the useful way to use it is as a set of prompts: what happens when this dependency fails, what does this cost at ten times the traffic, who gets paged and what do they do, what would a compromise of this component reach. And the review is most valuable early, when the answers can still change the design cheaply.

13

What is the principle of designing for failure in the cloud?

Assume every component will fail and design so that failure is contained and recoverable, because at cloud scale individual failures are routine rather than exceptional. The concrete practices. Spread across availability zones, so a data centre failure removes capacity rather than the service. Use managed services with built-in redundancy where possible. Make instances disposable: no state on local disk, so an instance can be terminated and replaced without consequence. Auto-scaling groups then replace unhealthy instances automatically. Set timeouts and use circuit breakers on every dependency, so a slow downstream does not exhaust your capacity. Retry with exponential backoff and jitter, and only for idempotent operations. Degrade gracefully: a failure in a non-essential dependency should reduce functionality rather than fail the request. And test it — chaos engineering, or at minimum terminating an instance during business hours to verify the replacement works. AWS Fault Injection Simulator does this deliberately. The cultural half is treating instance failure as unremarkable rather than as an incident, which is what "cattle not pets" means.

14

How do you decide between AWS, GCP and Azure?

For most workloads the capabilities are comparable, so the decision is usually driven by non-technical factors — existing commitments, enterprise agreements, and where the team already has expertise. That is a legitimate answer rather than a dodge: operational familiarity is worth more than a marginal feature advantage. Where genuine differences exist. AWS has the broadest service catalogue and the deepest ecosystem, which matters for unusual requirements. GCP has strong data and machine learning tooling, and Kubernetes is native to its heritage. Azure integrates tightly with Microsoft enterprise estates, which is decisive if you are already there. Pricing differs in detail but not usually enough to drive the decision, and comparisons are hard because the units differ. The more important architectural question is how much lock-in to accept. Using managed services deeply gives lower operational cost and higher switching cost. Staying portable — containers, open-source data stores — preserves optionality at the price of running more yourself. The pragmatic position is that lock-in at the data layer is expensive to reverse and worth thinking about, while lock-in at the compute layer is comparatively cheap to unwind.

15

When would you choose Lambda over a container service?

Lambda suits event-driven, spiky or low-volume workloads where you want no infrastructure to manage and want to pay nothing when idle. Good fits: responding to S3 events or queue messages, scheduled jobs, API backends with variable traffic, and glue between services. The constraints that push you away from it. A 15-minute execution limit, so long-running work does not fit. Cold starts, which add latency on the first invocation of an environment — mitigable with provisioned concurrency, though that reintroduces a fixed cost. Limited runtime control. And a payload size limit. The economics invert at sustained high load: Lambda is excellent when traffic is intermittent and expensive when a container running continuously would be cheaper. The crossover is usually around consistently high utilisation. Containers on ECS or EKS suit steady traffic, long-running processes, workloads needing specific runtimes, and anything where you want portability. Fargate sits between them — containers without managing servers — which is often the pragmatic middle ground. The architectural caution is that a large system built entirely from Lambdas can become hard to reason about and to test locally, so the granularity is worth deciding deliberately.

16

What causes Lambda cold starts and how do you reduce them?

A cold start is the time to provision an execution environment, download and initialise your code before the handler runs. A warm environment reuses it. The contributors: package size, since the code must be downloaded and unpacked; runtime, with interpreted languages generally starting faster than JVM or .NET; initialisation work outside the handler such as loading configuration or establishing connections; and VPC attachment, though that penalty was largely removed by improvements to how ENIs are provisioned. The reductions. Keep the deployment package small — remove unused dependencies, and use layers carefully since they add to the size too. Do expensive initialisation outside the handler so it happens once per environment rather than per invocation, and reuse SDK clients and database connections across invocations by declaring them at module scope. Choose a faster runtime where you have the choice. Provisioned concurrency keeps environments warm at a fixed cost, which is the direct fix when latency matters — and SnapStart does something similar for Java by snapshotting the initialised state. The judgement worth making: for asynchronous or background work, cold starts usually do not matter and paying to avoid them is waste.

17

How does Lambda concurrency work and what is throttling?

Each concurrent invocation needs its own execution environment. Concurrency is therefore the number of simultaneous executions, which is roughly the request rate multiplied by the average duration. There is an account-level limit per region — 1000 by default — shared across all functions. Exceeding it means throttling: invocations are rejected with a throttle error. The consequences differ by invocation type. Synchronous invocations return an error to the caller immediately. Asynchronous invocations are retried by Lambda for a period and then sent to the dead-letter or failure destination. Event source mappings such as SQS retry according to the queue configuration. The controls. Reserved concurrency guarantees a function a share and simultaneously caps it, which is how you stop one function consuming the whole account limit and starving everything else — that is the important use, and it is often the fix for a noisy neighbour within your own account. Provisioned concurrency pre-warms environments and is about latency rather than capacity. And the downstream matters: a function scaling to hundreds of concurrent executions opens hundreds of database connections, which is why RDS Proxy exists.

18

What is the difference between ECS and EKS, and Fargate?

ECS is AWS's own container orchestrator — simpler, tightly integrated with AWS services, and with no control plane to manage or upgrade. Its concepts are fewer, so the learning curve is short. EKS is managed Kubernetes. You get the Kubernetes API and its entire ecosystem — Helm, operators, the portability of standard manifests — at the cost of significantly more complexity, and you still manage upgrades and add-ons. Fargate is a launch type for either: containers run without you provisioning or managing instances. You specify CPU and memory per task and AWS runs it. The practical decision. ECS when you want containers on AWS with minimal operational overhead and no requirement for Kubernetes. EKS when you need the Kubernetes ecosystem, have multi-cloud or portability requirements, or the team already has that expertise. Fargate when you do not want to manage instances, accepting a higher per-unit cost and some constraints — no daemonsets, no GPU on some configurations, and limited control over the host. EC2 launch type when you need control, GPUs, or better economics at steady high utilisation with reserved capacity. The honest note is that EKS is frequently chosen for portability that is never exercised.

19

How does auto scaling work and what should it scale on?

An auto-scaling group maintains a desired number of instances, replacing unhealthy ones and adjusting the count according to a policy. The policy types: target tracking, which maintains a metric at a target value and is the simplest and usually the right choice; step scaling, which adds capacity in defined increments as a metric crosses thresholds; and scheduled scaling for known patterns. What to scale on is the important question. CPU is the default and is often wrong — a service bound by I/O or by a downstream dependency shows low CPU while being fully saturated. Better signals: request count per target for a web service, queue depth for a worker, or a custom metric reflecting actual saturation such as concurrent requests or connection pool utilisation. The practical concerns. Scaling out takes time — instance launch plus application startup plus health check — so it lags a spike, which is why a warm buffer or predictive scaling matters. Scale in should be more conservative than scale out, or you flap. And termination should be graceful with connection draining, or scaling in drops requests. And the downstream must scale too, or you just move the bottleneck.

20

What are spot instances and when can you use them?

Spare capacity offered at a large discount — often 60 to 90 percent — which AWS can reclaim with two minutes of notice. The suitability test is whether an interruption is tolerable. Good fits: batch processing, CI runners, stateless web tiers behind a load balancer with enough capacity to absorb losses, and anything checkpointed so work resumes rather than restarts. Bad fits: stateful services, anything where an interruption causes data loss, and workloads that cannot tolerate reduced capacity. The practices that make it work. Diversify across instance types and availability zones, since interruption is per capacity pool and diversification makes simultaneous reclamation unlikely. Handle the interruption notice — drain connections, checkpoint, deregister. And mix spot with on-demand so a baseline of capacity is guaranteed, which is what a mixed-instances auto-scaling group provides. The economics are compelling enough that not using spot for interruptible work is leaving substantial money on the table — CI and batch in particular. The alternatives for steady workloads are Savings Plans and Reserved Instances, which discount for commitment rather than for interruptibility, and the two combine.

21

How do you choose an EC2 instance type?

From the workload's actual constraint, measured rather than assumed. The families map to that: general purpose (M) for balanced workloads, compute optimised (C) for CPU-bound work, memory optimised (R and X) for caches and in-memory databases, storage optimised (I and D) for high local IOPS, and accelerated (P and G) for GPUs. The method is to run the workload, observe which resource saturates first, and pick a family matching that ratio — then size for the actual usage with headroom. The specifics worth knowing. Graviton instances are ARM-based and typically offer better price-performance for workloads that run on ARM, which most interpreted and JVM languages do without modification — that is often the single easiest cost reduction available. Burstable instances (T family) accumulate credits when idle and spend them under load. They are excellent for low-average-utilisation workloads and dangerous for sustained load, because exhausting credits throttles the instance severely — which appears as sudden unexplained slowness. Newer generations are usually cheaper and faster than older ones, so staying current is a free improvement. And network and EBS bandwidth scale with instance size, which sometimes forces a larger instance than CPU alone would suggest.

22

What is the difference between vertical and horizontal scaling in the cloud?

Vertical means a bigger instance; horizontal means more instances. Vertical is simpler — no changes to the application, no distribution concerns — but it has a ceiling, requires downtime or a failover to change on most services, and leaves you with a single point of failure. Horizontal has no practical ceiling, provides redundancy as a side effect, and allows scaling in as well as out. It requires the application to be stateless, or for state to be externalised, which is the main constraint. The cloud makes horizontal much more attractive than it is on-premises, because capacity is elastic and you pay for what you use — so scaling in when load drops is a real saving rather than idle hardware. The practical guidance: design stateless from the start, since retrofitting is expensive. Session state goes to Redis or a token; uploads go to S3; nothing important lives on instance disk. Databases are the usual exception, since they are stateful by nature. There, vertical scaling plus read replicas is the standard approach until sharding becomes necessary — and sharding is a substantial architectural change that should be deferred as long as it reasonably can be.

23

How do you handle deployments on ECS or EKS without downtime?

A rolling update with correct health checks and graceful shutdown — the same requirements as any orchestrated deployment, with AWS-specific details. On ECS, the deployment configuration controls minimum healthy percent and maximum percent, which determine how many tasks are replaced at once. The load balancer health check determines when a new task receives traffic, and deregistration delay controls connection draining on the old one. That deregistration delay is the setting most often left at a default that does not match the application — too short and in-flight requests are cut. The application must handle SIGTERM: stop accepting new work, finish in-flight requests, exit. ECS sends SIGTERM then SIGKILL after a stop timeout, so that timeout must exceed the longest request. The health check must reflect genuine readiness, including dependency connectivity, or traffic reaches tasks that cannot serve it. On EKS the equivalents are readiness probes, preStop hooks and terminationGracePeriodSeconds. And backward compatibility during the mixed-version window applies as always — the schema and the API must work with both versions simultaneously.

24

What is the difference between an ALB, an NLB and CloudFront?

An Application Load Balancer operates at layer 7. It understands HTTP, so it can route by path, host and header, terminate TLS, and provide per-request features such as sticky sessions and health checks against a URL. It is the default for web applications. A Network Load Balancer operates at layer 4. It forwards TCP and UDP with very low latency and extremely high throughput, preserves the client IP, and supports static IP addresses. It is right for non-HTTP protocols, for extreme performance, and when you need a fixed IP. CloudFront is a CDN. It caches at edge locations near users, terminates TLS at the edge, and reduces both latency and origin load. It also absorbs traffic spikes and provides a layer of DDoS protection. The practical combination for a web application is CloudFront in front of an ALB in front of the application, with WAF attached. The details worth knowing: an ALB distributes requests while an NLB distributes connections, so a long-lived connection pins to one target on an NLB. And CloudFront caching requires attention to the cache key, particularly for anything personalised — serving one user's response to another is a real incident pattern.

25

How do you run scheduled or background jobs?

The options, roughly by weight. EventBridge Scheduler invoking a Lambda is the lightest for short periodic work. It replaced CloudWatch Events rules for scheduling and supports one-off schedules and time zones. ECS scheduled tasks or Kubernetes CronJobs for work that needs a container, longer runtime, or a specific environment. AWS Batch for large compute jobs with queuing and dependency management. Step Functions for multi-step workflows with retries, branching and long waits — which is the right answer when the job is a sequence with failure handling rather than a single task, since building that orchestration by hand is where bugs live. The things that apply regardless. Jobs need idempotency, because retries and duplicate triggers happen. They need a timeout, or a hung job runs forever. They need monitoring on failure, and — more importantly — dead-man alerting on not running, since silent non-execution is the failure nobody notices. And concurrency control, or a slow run overlaps with the next. Running cron on an EC2 instance works but reintroduces a pet server and has no visibility.

26

What is the metadata service and why does IMDSv2 matter?

The instance metadata service is an endpoint at a link-local address — 169.254.169.254 — that an EC2 instance queries for information about itself, including temporary credentials for its attached role. IMDSv1 answered any GET request to that address. That made it a prime target for server-side request forgery: an application with a vulnerability allowing an attacker to make it fetch a URL could be pointed at the metadata endpoint, and the response contained working AWS credentials. That is exactly how the Capital One breach worked, and it is the canonical cloud SSRF scenario. IMDSv2 requires a session token obtained with a PUT request carrying a specific header, and the token has a hop limit. That defeats the attack, because a naive SSRF can usually only trigger a GET and cannot set arbitrary headers, and the hop limit prevents the response being proxied out of the instance. The practical action is to require IMDSv2 — it can be enforced per instance, as an account default, and via SCP — and to set the hop limit to 1 unless containers on the host need it, where 2 is required. Newer AMIs and launch templates increasingly default to it, but existing instances need checking.

27

How do you handle configuration and feature flags across environments?

Parameter Store for non-sensitive configuration and Secrets Manager for secrets, read at runtime using the instance or task role. Parameter Store is cheaper and adequate for most configuration; Secrets Manager adds automatic rotation, which is its main justification, and costs per secret. The practices. Namespace parameters by environment and service so access can be scoped by IAM path — a service should only be able to read its own configuration, which a wildcard grant defeats. Cache values in the application rather than fetching per request, since these are API calls with rate limits and latency, but with a TTL so a change takes effect without a deployment. Validate at startup and fail fast on a missing required value. For feature flags specifically, AppConfig provides validation, gradual rollout and automatic rollback on a CloudWatch alarm — which is meaningfully better than storing flags as plain parameters, because a bad flag value rolls back automatically. The alternative is a dedicated flag service such as LaunchDarkly, which gives richer targeting. And never bake environment configuration into the image, or you cannot promote one artifact across environments.

28

What is the difference between stateless and stateful workloads in the cloud, and why does it matter so much?

A stateless workload keeps nothing durable on the instance, so any instance can serve any request and instances can be created and destroyed freely. That property is what makes almost every cloud benefit available. Auto-scaling requires it, because scaling in must not lose anything. Rolling deployments require it. Spot instances require it. Self-healing by replacing unhealthy instances requires it. And multi-AZ redundancy requires it. So statelessness is not a nice-to-have — it is the precondition for elasticity. What must be externalised: session state to Redis, DynamoDB or a signed token; uploaded files to S3; logs to a collector; and any cache that must be shared. The things that quietly break it: writing to local disk, in-memory sessions, in-memory rate limiting or caching that assumes one instance, and scheduled work that assumes a single node. Stateful workloads — databases, message brokers — are the legitimate exception, and the guidance there is to use a managed service where possible, because operating them well is genuinely hard and the failure modes are unforgiving. The design test: could you terminate any instance right now with no consequence?

29

How is a VPC structured?

A VPC is a private network with a CIDR block, divided into subnets, each of which lives in one availability zone. The fundamental distinction is between public and private subnets, and it is defined by routing rather than by any setting called "public". A public subnet has a route to an internet gateway; a private subnet does not. Instances in a private subnet reach the internet outbound through a NAT gateway in a public subnet, and cannot be reached inbound from the internet at all. The standard layout: public subnets containing load balancers and NAT gateways; private subnets containing application instances; and often a third tier of isolated subnets for databases with no internet route in either direction. All of that replicated across at least two availability zones for redundancy — including the NAT gateway, since a single NAT gateway is a single point of failure and cross-zone NAT traffic also costs money. The sizing decision matters because CIDR blocks are painful to change later: size subnets generously, and avoid overlapping ranges with other VPCs or on-premises networks, since overlapping CIDRs make peering impossible.

30

What is the difference between a security group and a network ACL?

A security group is stateful and attaches to an instance or interface. A network ACL is stateless and attaches to a subnet. Stateful means return traffic is automatically allowed: permitting inbound on port 443 means the response goes out without an outbound rule. That is why security groups are simple to configure correctly. Stateless means every direction needs an explicit rule, including return traffic on ephemeral ports. Forgetting the outbound ephemeral range is the single most common NACL mistake, and it produces a connection that establishes and then hangs. Security groups only have allow rules — you cannot express a deny. NACLs have both allow and deny, evaluated in numbered order, which is what makes them useful for blocking a specific address. The practical guidance: use security groups as the primary control and keep NACLs permissive. Security groups can reference other security groups as sources, which is far better than IP ranges — allowing traffic from the load balancer's group rather than from a CIDR means the rule stays correct as instances change. Use NACLs only for coarse subnet-level rules or explicit denies. And a timeout usually means a security group; a refusal means the application.

31

What is a NAT gateway and why is it expensive?

It allows instances in a private subnet to make outbound internet connections while remaining unreachable from the internet. It is expensive on two axes: an hourly charge per gateway, and a per-gigabyte data processing charge on top of normal data transfer costs. For a workload moving significant traffic, the processing charge dominates and is frequently a surprising line item. And because you need one per availability zone for redundancy, the hourly cost multiplies. The reductions worth knowing. VPC endpoints route traffic to AWS services without going through the NAT gateway at all — a gateway endpoint for S3 and DynamoDB is free and removes what is often the largest share of NAT traffic. That is usually the single biggest saving available, and it also improves security by keeping the traffic off the public internet. Interface endpoints for other services cost per hour but can still be cheaper than NAT processing at volume. Check what is actually generating the traffic — container image pulls, package downloads and telemetry are common culprits, and a registry cache or an interface endpoint for ECR addresses them. And instances that need no outbound internet should not have a NAT route at all.

32

What is a VPC endpoint and when do you need one?

A VPC endpoint provides private connectivity to an AWS service without traversing the internet or a NAT gateway. There are two kinds. Gateway endpoints exist for S3 and DynamoDB, work by adding a route to the route table, and are free — so there is essentially no reason not to use them. Interface endpoints use PrivateLink and place an elastic network interface in your subnet with a private IP. They cover most other services, and they cost per hour per availability zone plus per gigabyte. The reasons to use them. Cost, since traffic avoids NAT gateway processing charges — for an S3-heavy workload this is a large saving. Security, since the traffic never leaves the AWS network and endpoint policies can restrict which resources are reachable. And it allows instances with no internet route at all to still use AWS services, which is the strongest isolation posture. The practical caution: an interface endpoint changes DNS resolution for that service within the VPC, which is usually what you want but can surprise you. And endpoint policies are a separate layer of access control that can deny access even when IAM allows it.

33

How do you connect two VPCs or connect to on-premises?

VPC peering creates a direct connection between two VPCs. It is simple and cheap, but it is not transitive — A peered to B and B peered to C does not let A reach C — so a mesh of peerings becomes unmanageable past a handful of VPCs. Transit Gateway is the answer at scale: a hub that VPCs and on-premises connections attach to, with routing controlled centrally. It scales to hundreds of attachments and supports transitive routing. For on-premises: Site-to-Site VPN over the internet is quick to set up and cheap, with bandwidth and latency limited by the internet path. Direct Connect is a dedicated private circuit with consistent latency and higher bandwidth, at higher cost and with a lead time measured in weeks. The common practice is Direct Connect with a VPN as backup. The constraint that governs all of this is CIDR overlap. Two networks with overlapping ranges cannot be connected without NAT, and discovering that after the fact is expensive — which is why IP address planning across the whole estate matters before the first VPC is created. PrivateLink is the alternative when you only need to expose one service rather than connect networks.

34

How does Route 53 support high availability?

Through routing policies combined with health checks. Failover routing sends traffic to a primary and switches to a secondary when the primary's health check fails. Latency-based routing sends each user to the region with the lowest latency for them. Weighted routing splits traffic by proportion, which supports gradual migration and blue-green at the DNS level. Geolocation routing directs by user location, which matters for data residency. Health checks can test an endpoint directly, or reference a CloudWatch alarm, or aggregate other health checks — the last being how you express "healthy only if these three things are healthy". The important limitation is DNS caching. Failover is bounded by the record TTL plus whatever resolvers and clients cache beyond it, and some clients cache far longer than the TTL — Java historically cached indefinitely. So DNS failover is measured in minutes, not seconds, and is not a substitute for a load balancer. The practical architecture uses DNS for regional failover and a load balancer for instance-level failover within a region, since the load balancer reacts in seconds. And alias records to AWS resources are free to query and track the target's address automatically.

35

What does CloudFront actually do for you?

It caches content at edge locations close to users and terminates connections there. The benefits, in order of what usually matters. Latency: content served from a nearby edge rather than a distant origin, and TLS terminated at the edge so the handshake round trips are short. That improves perceived performance substantially for geographically distributed users even for uncached content, because the connection to the origin is over AWS's backbone rather than the public internet. Origin offload: cached responses never reach your infrastructure, which reduces cost and absorbs spikes. DDoS absorption, since the edge network has far more capacity than your origin, and Shield and WAF attach at that layer. The things to get right. The cache key must include everything the response varies by — omitting a header or cookie that matters means serving one user's content to another, which is a serious and recurring incident pattern. Cache invalidation is slow and charged, which is why content-hashed asset filenames are better than purging. And the origin sees CloudFront's address, so client IPs come from headers, and the origin should be locked down to accept traffic only from CloudFront.

36

How do you debug a connectivity problem in a VPC?

Work through the layers in order, because each has an independent failure mode. Security groups on both ends: the source must allow outbound and the destination must allow inbound on the port. Referencing the source security group rather than a CIDR is both more correct and easier to verify. Network ACLs, remembering they are stateless — the return path on ephemeral ports needs an explicit rule, and this is the usual cause when security groups look right. Route tables: does the subnet have a route to the destination, and is the target correct? A private subnet with no NAT route explains no outbound internet. DNS: is the name resolving, and to the address you expect? Private hosted zones and endpoint DNS override can produce surprises. The tool that shortcuts all of this is VPC Reachability Analyzer, which traces the path between two resources and reports exactly which component blocks it. That is far faster than reasoning through the configuration, and it is underused. VPC Flow Logs show accepted and rejected traffic, which confirms whether packets arrive at all. And the shorthand: timeout means a network control, refusal means the application.

37

What are VPC Flow Logs used for?

They record metadata about IP traffic in the VPC — source and destination address and port, protocol, packet and byte counts, and whether the traffic was accepted or rejected. They do not capture packet contents, so they are for connectivity and volume analysis rather than for inspecting payloads. The uses. Debugging connectivity: a REJECT entry tells you traffic arrived and was blocked, which distinguishes a security group problem from traffic never arriving. That single distinction saves a lot of time. Security investigation: identifying unexpected outbound connections, which is how data exfiltration and compromised instances are detected. Cost analysis: understanding which traffic flows are generating data transfer charges, particularly cross-AZ traffic, which is a commonly overlooked cost. And compliance evidence. The practical considerations: they generate substantial volume, so send them to S3 rather than CloudWatch Logs for cost reasons unless you need real-time queries, and set a lifecycle policy. Athena is the usual query tool. They can be enabled at VPC, subnet or interface level, and the aggregation interval affects how quickly you see recent traffic.

38

What is PrivateLink and how does it differ from peering?

PrivateLink exposes a single service privately rather than connecting networks. With peering or Transit Gateway, two VPCs become mutually routable — anything in one can potentially reach anything in the other, subject to security groups. That is a network-level connection with a broad surface. With PrivateLink, the consumer gets an endpoint in their own VPC that reaches one specific service behind a network load balancer in the provider's VPC. Nothing else is reachable, and the networks are not routable to each other at all. The consequences. It is unidirectional: the consumer initiates, the provider cannot reach back. CIDR overlap does not matter, because there is no routing between the networks — which is a significant practical advantage when connecting to a third party whose addressing you do not control. And the exposure is minimal by construction rather than by policy. So it is the right choice for exposing a service to another account or to a customer, and for consuming a SaaS product privately — many vendors offer PrivateLink endpoints for exactly this. Peering remains right when you genuinely need general network connectivity between environments you own.

39

How does cross-AZ data transfer cost work and why does it matter?

Traffic between availability zones within a region is charged per gigabyte in both directions, unlike traffic within a zone which is free. It matters because it is invisible in the architecture diagram and can become a large line item. A chatty microservice architecture spread across three zones sends most of its internal traffic across zone boundaries by default, and every one of those hops is charged. The common contributors: application-to-database traffic when the database is in a different zone from the caller; service-to-service calls load balanced across zones; and replication between zones. The reductions. Zone-aware routing, so a service prefers a target in its own zone and only crosses when necessary — Envoy and some service meshes support this, and ALBs have cross-zone load balancing settings. Caching to reduce the volume crossing zones. And for very chatty pairs, co-locating them in one zone with the redundancy provided at a coarser level, though that trades availability for cost and should be deliberate. The tension is real: multi-AZ is the baseline for availability, and it has a running cost. The right response is measuring it and reducing unnecessary chatter rather than abandoning zone redundancy.

40

What is WAF and what should it protect against?

A Web Application Firewall inspects HTTP requests at the edge — attached to CloudFront, an ALB or API Gateway — and blocks those matching rules. What it is genuinely good for. Rate limiting per IP or per identifier, which is the most valuable rule for most applications because it mitigates brute force, scraping and application-layer denial of service. Blocking known-bad sources and bot traffic. Geographic restrictions where they apply. And managed rule groups covering common attack patterns. What it is not. A substitute for fixing the application. A WAF rule blocking SQL injection patterns is defence in depth over parameterised queries, not a replacement — signature matching is bypassable and false-negative-prone. The practical cautions. Managed rules produce false positives that block legitimate traffic, so deploy in count mode first and review what would have been blocked before enforcing. That step is skipped often enough that it is worth stressing. Rules are evaluated in order with a capacity limit, so rule design matters at scale. And logging matters as much as blocking: WAF logs show attack patterns and are what you review after an incident.

41

How do you expose a service to the internet securely?

Layered, with the application as far from the internet as possible. The standard shape: Route 53 for DNS, CloudFront at the edge with WAF attached, an ALB in public subnets, and the application in private subnets with no inbound internet route at all. The database in isolated subnets reachable only from the application tier. The controls at each layer. TLS terminated at CloudFront and re-encrypted to the origin if the traffic crosses anything untrusted. The ALB's security group allows only CloudFront, using the managed prefix list, so nobody can bypass the edge by hitting the load balancer directly — which is a step commonly missed. The application's security group allows only the ALB's security group. The database's security group allows only the application's. That chain of security group references, rather than CIDR ranges, is what keeps the rules correct as things change. Beyond the network: authentication and authorisation in the application, since network controls are not access control; rate limiting; and Shield Advanced if DDoS is a real concern. And nothing in a public subnet except load balancers and NAT gateways.

42

What is the difference between public, private and isolated subnets?

The distinction is entirely about routing, not about a flag. A public subnet has a route to an internet gateway, so resources with a public IP are reachable from the internet and can reach it directly. A private subnet has no internet gateway route but has a route to a NAT gateway, so resources can make outbound connections — to pull packages, call APIs, reach AWS services — but cannot be reached inbound. An isolated subnet has neither, so resources have no internet connectivity in either direction. AWS services are reachable only through VPC endpoints. The placement guidance. Public: load balancers, NAT gateways, and bastion hosts if you use them. Private: application instances and containers. Isolated: databases, and anything handling sensitive data where outbound connectivity would be an exfiltration path. The isolated tier is the one teams often skip, and it is worth having for databases — a database with no outbound route cannot be used to exfiltrate data even if compromised. The practical consequence of isolation is that everything the workload needs must come through endpoints, which is more configuration but is the stronger posture.

43

What consistency guarantees does S3 provide?

S3 has provided strong read-after-write consistency for all operations since December 2020 — a PUT is immediately visible to a subsequent GET, and a delete is immediately reflected, with no additional cost or performance penalty. That is worth knowing precisely, because a great deal of older material and a great deal of application code assumes the previous behaviour, where new objects were strongly consistent but overwrites and deletes were eventually consistent. The practical consequence is that workarounds built for the old model — retry loops after a write, sentinel objects, waiting before reading — are now unnecessary complexity, and code carrying them can be simplified. What is still not guaranteed. Listing is strongly consistent for the object list, but concurrent writers to the same key have last-writer-wins semantics with no conditional update primitive historically — though S3 now supports conditional writes with If-None-Match and If-Match, which enables optimistic concurrency and is the right tool for "create only if absent". And cross-region replication remains asynchronous, so a replica lags. So within a region, treat S3 as strongly consistent; across regions, do not.

44

How do S3 storage classes work and how do you choose?

The classes trade retrieval cost and latency against storage cost. Standard for frequently accessed data. Standard-Infrequent Access is cheaper to store and charges per retrieval, with a 30-day minimum duration. One Zone-IA is cheaper still but stores in a single availability zone, so it is only appropriate for reproducible data. Glacier Instant Retrieval gives archive pricing with millisecond access. Glacier Flexible Retrieval and Deep Archive are much cheaper with retrieval times measured in minutes to hours. The honest recommendation for most cases is Intelligent-Tiering, which moves objects between tiers automatically based on access patterns for a small monitoring fee per object. It removes the need to predict access patterns, which teams predict badly, and it has no retrieval charges in the frequent and infrequent tiers. Where explicit lifecycle rules are better: when you genuinely know the pattern — logs accessed for 30 days then archived for compliance — and when objects are small, since the per-object monitoring fee makes Intelligent-Tiering uneconomic below roughly 128 KB. The mistake to avoid is moving data to a cheap class and then retrieving it often, where retrieval charges exceed the storage saving.

45

How do you secure an S3 bucket?

Start from the account-level Block Public Access setting, enabled at the organisation level so it cannot be turned off per bucket. That single control prevents the most common serious cloud breach — the accidentally public bucket — regardless of what any individual policy says. Then: encryption at rest, which is now on by default with SSE-S3, upgraded to SSE-KMS when you need key control, audit of key usage, or the ability to revoke access by revoking key access. KMS adds cost and API calls, so bucket keys reduce that substantially. Access through IAM roles, scoped to specific prefixes rather than the whole bucket. Bucket policies to enforce conditions — requiring TLS by denying requests where aws:SecureTransport is false is a standard baseline, and requiring a specific VPC endpoint prevents access from outside your network entirely. Versioning to survive accidental deletion and ransomware, with MFA delete for critical buckets, and Object Lock where immutability is required for compliance. Access logging or CloudTrail data events, so you know who read what. And IAM Access Analyzer to flag any bucket reachable from outside the account.

46

What is a presigned URL and when do you use it?

A URL carrying a time-limited signature that grants a specific S3 operation on a specific object without the recipient having AWS credentials. The two standard uses. Upload: the browser or mobile client requests a presigned URL from your backend, then uploads directly to S3. That keeps large file bodies out of your application servers entirely, which matters for cost, memory and timeouts — proxying uploads through the application is the pattern this replaces, and it scales badly. Download: serving private content without making it public, so an authorisation check happens in your backend and the URL is issued only if it passes. The details that matter. Expiry should be short — minutes for downloads, long enough for the upload to complete on a slow connection. The signature is derived from the credentials that created it, so if the signing role's access is revoked the URL stops working, and a URL signed by a long-lived credential outlives your intent. For uploads, use a presigned POST with conditions on content type and size, or a client can upload anything of any size. And the URL is a bearer token — anyone holding it has the access, so it must not be logged or put in a referrer-visible position.

47

How do you handle large file uploads to S3?

Multipart upload: the file is split into parts, each uploaded independently and possibly in parallel, then assembled by S3. It is required above 5 GB and worth using well below that — typically above about 100 MB — because it gives parallelism, so throughput improves substantially, and it gives resumability, since a failed part is retried without restarting the whole transfer. The SDK transfer managers handle the splitting, parallelism and retries automatically, so you rarely implement it by hand. The operational detail that costs money: incomplete multipart uploads leave parts stored in the bucket, and they are billed, but they are invisible in the normal object listing. A lifecycle rule to abort incomplete multipart uploads after a few days is essentially mandatory, and its absence is a recurring source of unexplained storage cost. For browser-based uploads, presigned URLs per part let the client upload directly with the backend coordinating initiation and completion. And S3 Transfer Acceleration routes uploads through CloudFront edge locations, which helps meaningfully for geographically distant clients and not at all for clients near the region — so it is worth measuring before enabling, since it carries a per-gigabyte charge.

48

What is the difference between EBS, EFS and S3?

They are three different storage models, and picking the wrong one produces either poor performance or unnecessary complexity. EBS is a block device attached to one instance — effectively a virtual disk. It is what a filesystem or a database sits on. It lives in one availability zone, and it is the right answer when you need a filesystem for a single instance with predictable low-latency IO. EFS is a managed NFS filesystem that many instances can mount simultaneously, across availability zones. It is the answer when multiple instances genuinely need a shared filesystem, and it is meaningfully slower and more expensive per gigabyte than EBS. S3 is object storage accessed over an API. It is not a filesystem — no partial writes, no rename, no directory semantics beyond key prefixes. It is by far the cheapest, effectively unlimited, and the right home for anything the application treats as a whole object: uploads, backups, artifacts, logs, static assets. The guidance: default to S3 and reach for the others only when you truly need filesystem semantics. Mounting S3 as a filesystem is usually a sign that the design should have used the API directly.

49

How do EBS volume types and IOPS work?

gp3 is the general-purpose default. It provides a baseline of 3,000 IOPS and 125 MB/s regardless of size, with throughput and IOPS provisionable independently of capacity. That independence is the reason gp3 replaced gp2 for most workloads: under gp2, performance scaled with volume size, so the standard workaround was over-provisioning capacity purely to get IOPS. With gp3 you buy the performance directly, which is usually cheaper. io2 and io2 Block Express provide much higher provisioned IOPS with a durability guarantee, and are for demanding databases. st1 and sc1 are HDD-backed, throughput-optimised and cheap, suited to large sequential workloads such as log processing — and badly suited to random access. The practical points. The instance type has its own EBS bandwidth limit, so a large volume attached to a small instance is capped by the instance, and that is a common reason provisioned IOPS are not observed. Volumes can be resized and their type changed while attached, though the filesystem must then be grown. And snapshots are incremental to S3, with restored volumes lazily loading blocks, so the first read of each block is slow unless the volume is initialised or fast snapshot restore is enabled.

50

How do you design a backup and recovery strategy?

Start from two numbers stated by the business: recovery point objective — how much data you can afford to lose — and recovery time objective — how long you can be down. Every technical choice follows from those, and a strategy chosen without them is guesswork. The mechanisms. Automated RDS backups with point-in-time recovery, which covers RPO to within minutes. Snapshots for EBS, orchestrated by AWS Backup or Data Lifecycle Manager. Versioning and cross-region replication for S3. The properties that matter beyond taking the backup. Isolation: backups in a separate account that the production account cannot delete, because ransomware and a compromised credential both delete backups first. Immutability via Object Lock or vault lock for the same reason. And cross-region copies if a regional failure is in scope. Retention aligned to actual requirements rather than kept forever by default, since storage accumulates. And the part that is skipped and matters most: restore testing on a schedule. An untested backup is a hypothesis. Restoring proves the backup is complete, the process is documented, and the RTO is real rather than aspirational.

51

How does S3 lifecycle management work?

Rules that transition objects between storage classes or expire them, based on age or on tags and prefixes. The typical policy: keep objects in Standard for 30 days, transition to Infrequent Access, transition to Glacier after 90 days, expire after the retention requirement. The details that catch people out. Minimum storage durations are charged whether or not the object survives — moving an object to IA and deleting it a week later still incurs the 30-day charge, so lifecycle rules on short-lived data cost more than leaving it in Standard. Transitions themselves cost per object, which makes lifecycle rules uneconomic for very large numbers of very small objects. Versioned buckets need separate rules for noncurrent versions, and their absence is a common cause of a bucket costing far more than its visible contents suggest — old versions accumulate invisibly. Similarly, a rule to abort incomplete multipart uploads should be on every bucket. Storage Lens and the S3 storage class analysis reports show what is actually accumulating, which is the right starting point before writing rules.

52

What is KMS and how does envelope encryption work?

KMS manages encryption keys, controls access to them via IAM, and logs every use to CloudTrail. Envelope encryption is how it scales. KMS does not encrypt your data directly — it would be slow and there are size limits. Instead the service asks KMS to generate a data key, receives it in both plaintext and encrypted form, encrypts the data locally with the plaintext key, discards the plaintext key from memory, and stores the encrypted data key alongside the ciphertext. To decrypt, the encrypted data key is sent to KMS, which returns the plaintext key, and decryption happens locally. The consequences. The master key never leaves KMS, so it cannot be exfiltrated. Access is revocable centrally: removing access to the KMS key makes all data encrypted under it unreadable, immediately, everywhere — which is a genuinely powerful control. And every decryption is logged, so you can see who read what. The practical concerns: KMS API calls cost money and are rate limited, which is why S3 bucket keys and data key caching exist. And customer-managed keys allow key policies and rotation control, where AWS-managed keys do not — that is the main reason to pay for them.

53

How do you optimise S3 request performance?

S3 scales to very high request rates — thousands of requests per second per prefix — and it partitions automatically based on key prefixes. The historical advice to add a random hash to the start of keys is obsolete: S3 now scales prefixes automatically, so sequential or date-based keys are fine for most workloads. Extremely high sustained rates still benefit from spreading across prefixes, because the scaling is per prefix and adaptation takes time. What matters more in practice. Parallelism: S3 throughput comes from concurrent requests, not from a faster single request, so a client doing one request at a time is leaving most of the available bandwidth unused. Byte-range fetches let a single large object be downloaded in parallel. Request count is a cost as well as a performance factor — many small objects cost more in requests than fewer large ones, which is why log aggregation and columnar formats matter for analytics workloads. S3 Select and Glacier Select push filtering into S3 so less data crosses the network, though Athena is usually the better tool now. And co-locating compute in the same region as the bucket avoids both latency and transfer charges.

54

How do you handle data residency and compliance requirements?

Start from what the requirement actually says, because "data must stay in India" and "data must not be accessible from outside the EU" are different obligations with different controls. The primary control is region selection: data stored in a region stays in that region unless you configure replication. So choosing the right region is most of the answer for storage residency. The enforcement layer is SCPs at the organisation level denying resource creation outside approved regions, which prevents accidental drift and is far more reliable than policy documents. The subtleties. Some services are global or replicate globally by default — IAM, Route 53, CloudFront — so understand where their data sits. Backups and snapshots must be constrained too, since a cross-region copy defeats the whole arrangement. Logs frequently contain personal data and are often overlooked. And third-party integrations may move data out. Encryption with customer-managed keys, plus tight key policies, addresses some access-control formulations of the requirement. And the practical advice is to document the data flows explicitly — where each category of data is stored, processed and transmitted — because that document is what an auditor asks for and what reveals the gaps.

55

What does RDS Multi-AZ give you and what does it not?

Multi-AZ maintains a synchronous standby in another availability zone and fails over to it automatically, typically within a minute or two, with a DNS change behind the endpoint. What it gives you: availability during a zone failure, host failure, or maintenance. Because replication is synchronous, no committed transactions are lost. What it does not give you, and this is the common misconception: it is not a read replica. In the classic Multi-AZ configuration the standby serves no traffic, so it adds no read capacity. It doubles cost for availability alone. It is also not a backup. A dropped table replicates to the standby instantly. Recovery from a logical error needs point-in-time restore, which is a separate mechanism. And it is not disaster recovery for a regional failure — that requires a cross-region read replica or a snapshot copy. The Multi-AZ DB cluster deployment is different: two readable standbys, faster failover, and read capacity from the standbys. The application implication of any failover is that connections break, so the application needs connection retry and a pool that recognises a dead connection — otherwise the failover works and the application still errors.

56

When would you choose DynamoDB over a relational database?

When the access patterns are known, simple and stable, and you need predictable single-digit millisecond latency at any scale with no operational overhead. DynamoDB excels at key-value and simple query workloads: fetch by id, fetch a range within a partition. It scales horizontally without you doing anything, has no connection limits, and on-demand capacity means no provisioning. What it costs you is flexibility. There are no joins, no ad-hoc queries and no aggregations. Every access pattern must be designed into the key schema or a secondary index before you write the data, and adding an unanticipated query later can require rebuilding the table. So the decisive question is whether the access patterns are known and stable. For a session store, a shopping cart, an event log, a high-volume write-heavy workload, or anything with a clear key, DynamoDB is excellent. For a system where the queries will evolve, where reporting matters, or where relationships are genuinely relational, a relational database is the right default and PostgreSQL on RDS or Aurora is the standard answer. The common mistake is choosing DynamoDB for scale that never arrives, and paying for it in modelling pain.

57

How do you model data in DynamoDB?

Backwards from the access patterns, which is the opposite of relational modelling. You list every query the application will make first, then design a key schema that serves them. The partition key determines distribution; the sort key enables range queries and hierarchy within a partition. The single-table design pattern puts multiple entity types in one table with generic key attributes, using key prefixes to distinguish them — so a query on one partition returns a customer and their orders together in a single request. That is the technique for avoiding joins, and it is powerful and genuinely hard to read. The honest position is that single-table design is often over-applied. It is right when you need the co-location for performance, and unnecessarily painful when the entities are independent — multiple tables are fine and much more maintainable in that case. Secondary indexes extend access patterns: a global secondary index has its own partition key and is eventually consistent with its own capacity; a local secondary index shares the partition key. The pitfalls: hot partitions from an uneven key distribution, which throttle despite spare overall capacity, and the 400 KB item limit.

58

What is Aurora and how does it differ from standard RDS?

Aurora is AWS's MySQL- and PostgreSQL-compatible engine with a re-architected storage layer. The key difference is that storage is separated from compute and distributed across six copies in three availability zones, with the database writing log records rather than pages. That gives fast failover, since a replica promotes without copying data; replicas that share the same storage, so replica lag is milliseconds rather than seconds; storage that grows automatically; and backups that do not affect performance. The practical benefits: better throughput than standard RDS on the same instance size for most workloads, up to fifteen replicas with minimal lag, near-instant clones for testing against production-sized data, and backtrack on the MySQL edition which rewinds the cluster. The costs: more expensive per instance-hour, plus IO charges on the standard configuration — which for IO-heavy workloads can dominate, and is why Aurora I/O-Optimized exists. Aurora Serverless v2 scales capacity automatically and suits variable or intermittent load. The decision is usually straightforward: Aurora when you want the performance, replica behaviour and failover speed and can absorb the cost; standard RDS for smaller or cost-sensitive workloads.

59

How do you handle database connections from Lambda?

This is the classic serverless-plus-relational problem. Each concurrent Lambda execution is a separate environment with its own connections, so scaling to hundreds of concurrent executions opens hundreds of database connections and exhausts the limit — which manifests as connection errors under exactly the load you wanted to handle. The fixes, in order of preference. RDS Proxy sits between Lambda and the database, pooling and multiplexing connections so many Lambda executions share a small pool. It also improves failover behaviour by holding client connections while the database fails over. This is the intended answer. Declare the connection outside the handler so it is reused across invocations within an environment, which reduces connection churn substantially — creating a connection per invocation is both slow and wasteful. Set reserved concurrency on the function to cap how many connections can exist at all. Use the Data API for Aurora Serverless, which is HTTP-based and has no connection concept at all. And the design-level answer: if the workload is genuinely high-concurrency key-value access, DynamoDB avoids the problem entirely because it has no connections.

60

When do you add a read replica and what are its limits?

When reads dominate and the primary is saturated by read traffic — which is the common case for most applications. A replica takes read load off the primary, and several replicas scale reads nearly linearly. They can also serve as a failover target, and cross-region replicas provide disaster recovery. The limits that matter. Replication is asynchronous on standard RDS, so a replica lags. A read immediately after a write may not see it, which breaks read-your-own-writes and produces bugs that are intermittent and hard to reproduce. The mitigation is routing reads that must be current to the primary — typically anything within a user's own session after a write. Replicas do not help write throughput at all, so a write-bound database gains nothing. And lag grows under heavy write load or long transactions, exactly when you least want it. The alternatives to reach for first: caching, which often removes more read load than a replica for less complexity, and query optimisation, since an unindexed query hammering the primary is a cheaper fix. Aurora replicas lag far less, which makes them more usable for near-current reads.

61

What is ElastiCache and when do you use Redis versus Memcached?

ElastiCache is managed Redis or Memcached — an in-memory store used as a cache, session store, rate limiter or lock coordinator. Redis is the default choice for nearly everything. It has rich data structures, persistence, replication and failover, pub/sub, Lua scripting, and cluster mode for horizontal scaling. Those features cover the use cases that actually arise: sorted sets for leaderboards and rate limiting, hashes for objects, and atomic operations for counters and locks. Memcached is simpler — a pure multi-threaded key-value cache with no persistence and no replication. It is faster for the narrow case of caching opaque blobs across many cores, and it scales by adding nodes with client-side sharding. The honest guidance is to use Redis unless you have a specific reason for Memcached, and most teams do not. The operational points that matter more than the choice. Set a maxmemory policy so eviction happens gracefully rather than the node running out of memory. Set TTLs on everything, because unbounded cache growth is the usual failure. And treat the cache as strictly optional — the application must work, slower, when it is empty or unavailable.

62

How do you run a database migration safely in production?

Expand and contract, so the schema is always compatible with both the currently running code and the code being deployed. The sequence. Add the new column as nullable, or add the new table — additive changes only. Deploy code that writes to both old and new. Backfill existing rows in batches, throttled so replication lag and load stay acceptable. Deploy code that reads from the new. Verify. Then, in a later release, drop the old. The things that cause incidents. A long-running ALTER holding a lock and blocking every query behind it — on PostgreSQL, adding an index must use CONCURRENTLY, and adding a NOT NULL column with a default was historically a full table rewrite. A backfill run as one statement, which holds a long transaction and inflates replication lag. And migrations that run automatically on deploy with no timeout, so a slow migration blocks the whole rollout. The practices: test the migration against a production-sized copy — Aurora clones make this cheap and are underused — set statement and lock timeouts so a migration fails fast rather than blocking, and make every migration reversible or forward-only by design rather than by accident.

63

What is DynamoDB on-demand versus provisioned capacity?

Provisioned capacity means you specify read and write capacity units and pay for them whether used or not, with auto-scaling adjusting within bounds. On-demand means you pay per request with no capacity management at all. On-demand is roughly six to seven times the per-request cost of fully utilised provisioned capacity. So the economics turn on utilisation. On-demand wins for unpredictable or spiky traffic, for new applications where you cannot forecast, for development environments, and for anything with long idle periods — because provisioned capacity sitting idle is pure waste. Provisioned wins for steady, predictable, high-volume traffic, where sustained utilisation makes the lower unit price decisive, and reserved capacity discounts it further. The practical approach is to start on-demand, observe the real pattern for a few weeks, and switch to provisioned with auto-scaling if the traffic proves steady and the volume justifies the management overhead. Switching is allowed, with a cooldown. The failure mode of provisioned capacity is throttling when traffic exceeds it, which auto-scaling reacts to too slowly for a sharp spike — that is the risk you are buying the discount with.

64

How do you choose between Athena, Redshift and a data warehouse approach?

Athena queries data in place in S3 using SQL, with no infrastructure and per-terabyte-scanned pricing. It suits ad-hoc analysis, log querying and infrequent reporting, and it is the right first choice because it costs nothing when idle. Redshift is a provisioned columnar warehouse. It suits sustained analytical workloads with many concurrent users, complex joins across large tables, and dashboards needing consistent fast response. It costs continuously. The crossover is about query frequency and latency expectations. Occasional queries over data you already have in S3: Athena. A BI layer serving an organisation all day: Redshift, or Redshift Serverless which softens the idle cost. What matters more than the choice is data layout, because it dominates both cost and speed on Athena and helps everywhere. Columnar formats — Parquet — so only the needed columns are read. Partitioning by the common filter, usually date, so scans skip irrelevant data. And compaction, since many small files are slow and expensive. Those three changes routinely reduce Athena cost by an order of magnitude, and they are the first thing to check when a query is expensive.

65

What is DynamoDB Streams and what is it used for?

A time-ordered log of item-level changes to a table, retained for 24 hours, readable by Lambda or by a consumer application. Each record can carry the old image, the new image, or both, so a consumer sees exactly what changed. The uses. Propagating changes to another system — updating a search index, invalidating a cache, feeding an analytics pipeline. Maintaining a derived aggregate or materialised view, since DynamoDB has no aggregation. Cross-region replication, which is what Global Tables are built on. And emitting domain events, which combined with a write to the table gives a transactional outbox for free — the change and the event cannot diverge because the event is derived from the change. That last property is genuinely valuable and is the strongest argument for streams. The operational details. Ordering is guaranteed per partition key, not globally. Delivery is at-least-once, so consumers must be idempotent. A failing Lambda blocks its shard, so failure handling with a destination or bisect-on-error matters or one bad record stalls the pipeline. And Kinesis Data Streams is the alternative when you need longer retention or multiple independent consumers.

66

How do you decide where a piece of data belongs?

By the access pattern, the consistency requirement and the durability requirement — not by defaulting everything into the relational database, which is the usual pattern. The rough map. Transactional business data with relationships and evolving queries: a relational database. High-volume key-based access with known patterns: DynamoDB. Ephemeral or derived data needing microsecond access: Redis. Large objects, files and anything treated as a blob: S3. Append-only event data for later analysis: S3 in Parquet, queried with Athena. Full-text and faceted search: OpenSearch. The judgement calls that matter. Do not put files in the database — store them in S3 and keep the reference in the database. Do not put a queue in the database if the volume is meaningful; the polling and locking patterns are painful and SQS exists. Do not use a cache as a system of record, because it will be lost. And resist adding a store per use case, because each one is an operational commitment — backups, monitoring, upgrades, expertise. Three well-run stores beat seven poorly-run ones, and consolidating onto PostgreSQL is a defensible position further than most people expect.

67

When do you use SQS versus SNS versus EventBridge?

SQS is a queue: one message goes to one consumer, and it is held until processed. It is for decoupling work — a producer enqueues, a worker dequeues, and the queue absorbs the difference in rate between them. SNS is pub/sub: one message fans out to many subscribers simultaneously. It is for notifying several interested parties of the same thing. EventBridge is a routing bus: events are matched against content-based rules and routed to targets, with a schema registry, replay, and native integrations with AWS services and SaaS providers. The practical guidance. Use SQS whenever you want a buffer and retry semantics, which is most background work. Use SNS to SQS — a topic with queues subscribed to it — when several services need the same event and each needs its own retry behaviour; that fan-out-to-queues pattern is the workhorse. Use EventBridge when routing is genuinely rule-based, when you want loose coupling with the producer unaware of consumers, or when you need its AWS service integrations. EventBridge has higher latency and lower throughput than SQS, so it is not a replacement for a high-volume work queue.

68

What delivery guarantees does SQS provide?

A standard queue provides at-least-once delivery and best-effort ordering. A message can be delivered more than once, and order is not guaranteed. A FIFO queue provides exactly-once processing within a five-minute deduplication window and strict ordering within a message group, at much lower throughput. The consequence that governs everything is that consumers must be idempotent. Duplicates are not an edge case — they are normal, produced by visibility timeout expiry when processing is slow, by retries, and by at-least-once semantics. The standard approach is a deduplication key: the message carries an identifier, the consumer records processed identifiers, and a repeat is discarded. Or the operation is naturally idempotent — a conditional write, or a set rather than an increment. Even FIFO does not remove the requirement, since its guarantee is bounded by the deduplication window and depends on the producer supplying a deduplication id. The practical position: design consumers so a duplicate is harmless, and then the delivery guarantee stops mattering. Teams that instead try to prevent duplicates end up with subtle bugs under exactly the load that causes them.

69

What is a visibility timeout and how do you set it?

When a consumer receives a message it becomes invisible to other consumers for the visibility timeout. If the consumer deletes it within that window, it is gone. If not, it becomes visible again and another consumer receives it. That is the mechanism that makes SQS reliable — a consumer that crashes mid-processing does not lose the message. Setting it. It must exceed the worst-case processing time, not the average. Too short and a slow message is redelivered while still being processed, producing duplicate work and, if processing is not idempotent, duplicate side effects. That is the most common SQS misconfiguration and it presents as mysterious repeated processing under load. Too long and a genuine consumer failure delays redelivery, which hurts latency. The better approach for variable processing time is to set a modest timeout and extend it from the consumer as work continues, using ChangeMessageVisibility as a heartbeat. That gives fast recovery from crashes without truncating long work. For Lambda consumers the function timeout must be less than the visibility timeout, and the recommendation is roughly six times the function timeout on the queue.

70

What is a dead-letter queue and how do you use it well?

A queue that receives messages which failed processing a configured number of times, so a poison message stops blocking the pipeline and is preserved for inspection. Without one, a message that always fails is retried forever, consuming capacity and, on FIFO queues or ordered streams, blocking everything behind it. Using it well means more than configuring it. The DLQ must be monitored with an alarm on depth greater than zero, because a DLQ nobody watches is a silent failure — messages are being dropped from the business process and nobody knows. The messages need enough context to diagnose: the original payload, the failure reason, and a correlation id. SQS provides the receive count; the error itself needs logging with the message id so the two can be joined. There needs to be a redrive path — SQS supports redrive from the DLQ back to the source, which is the recovery step after the bug is fixed. And the maximum receive count should be low, typically three to five. High counts mean a genuinely broken message is retried many times before anyone finds out. Set the DLQ retention long — fourteen days — since you need time to notice.

71

How does Lambda consume from SQS and what can go wrong?

An event source mapping polls the queue on your behalf, batches messages and invokes the function, scaling the number of pollers with queue depth. The failure mode that surprises people: by default, if the function throws, the entire batch returns to the queue and is retried — including the messages that succeeded. With a batch of ten where one fails, nine are reprocessed. The fix is partial batch response: the function returns the identifiers of the failed messages, and only those are retried. This requires enabling ReportBatchItemFailures on the mapping and returning the right structure, and it is the correct default configuration. Other issues. Scaling can overwhelm a downstream — Lambda scales pollers aggressively, so a database behind it sees a sudden burst. Maximum concurrency on the event source mapping is the control for that, and it is better than reserved concurrency because it does not cause throttling errors that count as failures. The visibility timeout must exceed the function timeout, or messages redeliver while still being processed. And a DLQ must be on the source queue rather than configured on the function, since the mapping handles retries.

72

What is Kinesis and how does it differ from SQS?

Kinesis Data Streams is an ordered, replayable log partitioned into shards. SQS is a queue where a message is consumed and deleted. The differences that matter. Kinesis retains data for a configured period — up to a year — and multiple independent consumers can each read the whole stream at their own position. SQS delivers each message to one consumer and then it is gone. Kinesis guarantees ordering within a shard, determined by the partition key. SQS standard queues do not order at all. Kinesis is therefore the choice for event streaming: analytics pipelines, multiple consumers of the same events, replay after a bug, and anything where ordering per entity matters. SQS is the choice for work distribution: independent tasks, no ordering requirement, and elastic consumers. The operational costs of Kinesis are real. Shards must be provisioned and scaled, though on-demand mode removes that. A hot partition key concentrates load on one shard. Consumers must checkpoint their position. And a stalled consumer blocks its shard. Kinesis is conceptually close to Kafka, and MSK is the answer when you want Kafka specifically.

73

What is Step Functions for?

Orchestrating a multi-step workflow as an explicit state machine, with retries, error handling, branching, parallelism and waits handled by the service rather than by your code. The case for it is that this orchestration logic is where bugs concentrate when written by hand — partial failures, retry storms, and state left inconsistent when step three fails after steps one and two succeeded. Step Functions makes the flow declarative and visible: you can see which execution failed and at which state, with the input and output at each step, which is enormously better than reconstructing it from logs. The good fits. Long-running processes with waits, including waiting for human approval or for a callback, since it can wait for up to a year. Sequences with compensating actions — a saga. Fan-out over a large collection with the distributed map. And anything where the retry and error policy per step differs. The costs: standard workflows are charged per state transition, which is expensive for high-volume fine-grained flows; express workflows are cheaper for high throughput with weaker guarantees. And the state machine language is verbose, though the point is that the logic is visible rather than buried.

74

How do you achieve exactly-once semantics in a distributed system?

You do not, at the transport level. You achieve effectively-once by combining at-least-once delivery with idempotent processing, and that is the honest answer to give. The reason is that a consumer can process a message and then fail before acknowledging it, and the sender cannot distinguish that from a message never processed. So some duplication is unavoidable. The practical construction. Every message carries a stable identifier from the producer — not generated at send time, or a retry produces a new one. The consumer records processed identifiers in a store with a uniqueness constraint, and a repeat is rejected. Better still, make the operation naturally idempotent: a conditional update, an upsert keyed by the message id, or setting a value rather than incrementing it. Where the side effect is external and not idempotent — sending an email, charging a card — use the provider's idempotency key mechanism, which most payment APIs offer precisely for this. And the transactional outbox pattern ensures the message is published if and only if the database change committed, which removes the other half of the problem: messages sent for changes that rolled back.

75

How do you handle backpressure between services?

By making the queue the buffer and controlling how fast consumers drain it, rather than letting a fast producer overwhelm a slow consumer directly. The mechanisms. A queue absorbs bursts, so the producer is never blocked by consumer speed — that is the primary reason to introduce one, and it converts a cascading failure into a growing backlog. Consumer concurrency limits cap how much load reaches the downstream: maximum concurrency on a Lambda event source mapping, or a bounded worker pool. Rate limiting at the boundary, so a client cannot exceed what the system can serve. Circuit breakers, so a failing downstream stops receiving requests and gets time to recover rather than being hammered by retries. And retries with exponential backoff and jitter — the jitter matters, because synchronised retries from many clients produce a thundering herd that prevents recovery. The monitoring that makes this manageable: queue depth and message age. Age is the better signal, because depth alone does not tell you whether the backlog is being worked through. A rising oldest-message age means consumers are not keeping up, and that is what should page. And shedding load explicitly is better than degrading for everyone.

76

What is the transactional outbox pattern and why does it matter on AWS?

The problem: a service needs to update its database and publish an event, and there is no transaction spanning both. Writing to the database and then publishing means a crash in between loses the event. Publishing first means a rollback leaves an event for a change that did not happen. The outbox pattern writes the event into an outbox table in the same database transaction as the change. A separate process reads the outbox and publishes, marking rows as sent. Since the write is atomic, the event exists if and only if the change committed. Publication is at-least-once, so consumers must be idempotent — which they must be anyway. On AWS the relay is usually a Lambda polling the table, or change data capture via DMS, or a Debezium connector feeding Kinesis or MSK. The neat special case is DynamoDB, where Streams gives you the pattern for free: the stream is derived from the committed write, so a consumer of the stream sees exactly the changes that happened, with no outbox table to maintain. The alternative — dual writes with best-effort publishing — silently loses events at a low rate, and those gaps are very hard to detect later.

77

What are the three pillars of observability and how do they map to AWS services?

Logs, metrics and traces — though the more useful framing is what question each answers. Metrics answer "is something wrong" — aggregated numeric time series, cheap to store and query, good for alerting and dashboards. CloudWatch Metrics. Logs answer "what exactly happened" — detailed per-event records, expensive at volume, good for investigation once you know where to look. CloudWatch Logs, queried with Logs Insights. Traces answer "where in the request path" — the causal path of a request across services with timing at each hop. X-Ray, or OpenTelemetry into a vendor. The workflow they support: an alert fires on a metric, a trace identifies which service and which call is slow, and logs for that trace explain why. Each pillar hands off to the next. What makes that workflow actually work is correlation. A trace id propagated through every service and included in every log line is what lets you pivot from one pillar to another. Without it you are searching by timestamp, which is painful. The practical advice is to instrument with OpenTelemetry rather than a proprietary SDK, since it keeps the backend replaceable.

78

What should you alert on?

Symptoms that users experience, not causes — and only things a human should act on immediately. The canonical set is the four golden signals: latency, traffic, errors and saturation. For most services, alerting on error rate and on high-percentile latency against a stated objective covers the majority of real incidents, because almost every underlying cause eventually shows up in one of them. What not to alert on. CPU above a threshold, which is a cause and frequently harmless. Individual instance failures, which auto-scaling handles. Anything that recovers by itself. And anything nobody will act on at three in the morning. The discipline that matters is that every page must be actionable, and there should be a documented response. Alerts that fire regularly and are routinely ignored are worse than no alerts, because they train people to ignore the one that matters — and alert fatigue is the most common cause of a missed incident. The practices: alert on error budget burn rate rather than raw thresholds, which reduces noise while catching genuine degradation faster. Use composite alarms to suppress downstream noise. And route non-urgent signals to a dashboard or a ticket rather than to a pager.

79

How do you control CloudWatch Logs cost?

Logs are charged on ingestion, on storage, and on query, and ingestion usually dominates. Costs grow with traffic, so a log line added casually becomes expensive at scale. The reductions. Log at an appropriate level — debug logging left on in production is the single largest avoidable cost, and it also makes the logs less useful. Structure logs as JSON so one line carries the fields rather than several lines carrying prose, and sample high-volume repetitive events rather than logging every occurrence. Set retention on every log group. The default is never expire, and log groups created automatically by Lambda and other services inherit that, so old logs accumulate indefinitely. Setting retention across all groups is often an immediate large saving. Export to S3 for long-term retention, where storage is far cheaper, and query with Athena when needed. Use embedded metric format to derive metrics from logs rather than emitting both. And check what is actually generating volume — Logs Insights can group by log stream, and it is common to find one noisy component producing most of the bill.

80

What is distributed tracing and why is it necessary?

A trace records the path of a single request across every service it touches, with a span per operation showing timing and metadata, linked by a propagated trace id. It is necessary because in a distributed system no single log tells you where time went. A request taking two seconds might be slow in the service you are looking at, or in one of six downstream calls, or in a queue between them. Without tracing you correlate timestamps across services by hand, which is slow and unreliable. What tracing gives you concretely: the critical path of a slow request, so you optimise the thing that matters; discovery of the actual call graph, which is usually more tangled than anyone believes; identification of N+1 patterns across service boundaries, which are invisible locally; and the causal chain when an error propagates. The requirements. Context propagation through every hop, including asynchronous ones through queues, which is the part usually incomplete and where traces break. Sampling, since tracing every request is expensive — with tail sampling preferred so errors and slow requests are kept rather than sampled uniformly. And trace ids in logs, so the two connect.

81

How do you structure logs so they are actually useful?

As structured JSON with consistent field names, one event per line, emitted to stdout and collected by the platform rather than written to files. The fields that should be on every line: timestamp, level, service, version, trace id and request id. Those make correlation possible, and their absence is what turns an investigation into guesswork. The fields that should be on relevant lines: user or tenant id, the operation, the outcome, and duration. What to avoid. Multi-line messages, particularly stack traces, unless the collector reassembles them — otherwise one error becomes thirty unrelated log entries. Interpolating values into the message text rather than putting them in fields, which makes them unsearchable. Logging the same event at several points. And logging secrets, tokens, full request bodies or personal data, which is both a compliance problem and a cost problem. The test for whether logging is good: during an incident, can you find every log line for one failing request across all services in one query? If yes, the structure is right. If you are searching by timestamp and guessing, it is not. Log levels should be adjustable at runtime, so debug can be enabled without a deploy.

82

What is an SLO and how does it change how you operate?

A service level objective is a target for a measurable aspect of service quality — for example, 99.9 percent of requests succeed within 300 milliseconds over a rolling 30 days. The error budget is the complement: at 99.9 percent, roughly 43 minutes of failure per month is acceptable by definition. That reframing is the point. It converts reliability from an absolute — which leads to arguing about whether any failure is tolerable — into a quantity that can be spent. Within budget, ship features and take risks. Budget exhausted, stop feature work and spend the effort on reliability. That gives an objective, pre-agreed rule for a decision that is otherwise political. It also changes alerting: rather than thresholds, alert on burn rate — how fast the budget is being consumed. A fast burn pages immediately; a slow burn raises a ticket. That catches real degradation earlier and produces far less noise. The practical requirements: the SLI must be measured from the user's perspective, not from server-side success; the target must be chosen deliberately rather than by adding nines; and someone must actually honour the budget rule, or it is decoration.

83

How do you investigate a production incident on AWS?

Stabilise first, diagnose second. The goal is restoring service, and the fastest route is usually reverting whatever changed rather than understanding it. So the first questions are: what changed recently — a deployment, a configuration change, a feature flag, an infrastructure change — and can it be reverted. CloudTrail and the deployment history answer that, and most incidents are caused by a change. If nothing changed on your side, check the AWS Health Dashboard for a provider issue, and check whether load changed. Then the layers: is the load balancer reporting healthy targets, are instances or tasks running, is the database saturated, are queues backing up, are dependencies responding. The tooling that shortcuts this: a dashboard showing the golden signals per service, so degradation is visible rather than searched for; traces for slow requests; and Logs Insights filtered by trace id. Throughout, communicate — a status update at fixed intervals even with nothing new, because silence generates its own escalation. Afterwards, a blameless postmortem focused on why the system allowed the failure and how it would be detected faster next time, with actions that are actually scheduled.

84

What is a health check and what makes a good one?

An endpoint the load balancer or orchestrator polls to decide whether an instance should receive traffic. A good health check reflects whether this instance can actually serve requests right now. That means checking the things required for service — a database connection, an essential cache — and returning unhealthy when they are unavailable. But there is a critical distinction. A shallow check that only confirms the process is alive lets traffic reach an instance that cannot serve. A deep check that verifies every dependency causes a shared dependency failure to mark every instance unhealthy simultaneously, which takes the whole service down rather than degrading it — and worse, prevents recovery, because there is nothing to route to. The usual resolution is separate checks. A liveness check that is shallow, deciding whether to restart. A readiness check that includes essential dependencies, deciding whether to route traffic. And essential means the request genuinely cannot be served without it — an optional cache should not fail readiness. Other practices: the check must be cheap, since it runs constantly from several sources; it must have its own timeout; and it should not require authentication in a way that makes it fragile.

85

How do you do a safe deployment and roll back quickly?

By making the change gradual and reversible, and by deciding to revert on data rather than on debate. The strategies. Rolling deployment replaces instances gradually, which is the default and requires backward compatibility during the mixed-version window. Blue-green runs a second full environment and switches traffic, giving instant rollback at the cost of running two environments. Canary sends a small percentage of traffic to the new version and increases it if metrics hold. CodeDeploy and ALB weighted target groups support canary and blue-green natively, with automatic rollback on a CloudWatch alarm — that automation is the important part, because it reverts faster than a human notices. The things that make rollback actually possible. Database changes must be backward compatible, or the code rolls back and the schema cannot. Feature flags separate deployment from release, so a feature can be turned off without a deploy — which is usually the fastest mitigation available. Artifacts must be immutable and the previous version still deployable. And the decision criterion should be pre-agreed: if error rate exceeds a threshold, revert first and investigate afterwards.

86

What is chaos engineering and is it worth doing?

Deliberately injecting failure into a system to verify it behaves as designed — terminating instances, adding latency, failing a dependency, exhausting a resource. The justification is that resilience mechanisms which are never exercised do not work. Failover configurations, retry logic, circuit breakers and runbooks all have a strong tendency to be subtly broken, and discovering that during a real incident is the expensive path. It is worth doing, with conditions. It should start small and in non-production. It needs monitoring good enough to observe the effect, or you learn nothing. It needs a stated hypothesis — "if this instance dies, requests continue with no errors" — so the experiment either confirms or refutes something. And it needs an abort mechanism. The honest sequencing: chaos engineering is not the first investment. A team without reliable monitoring, without tested backups, and without a rollback procedure has cheaper improvements available. But a mature system benefits, and AWS Fault Injection Simulator makes it straightforward with pre-built actions and automatic stop conditions tied to alarms. The cheapest version, worth doing regardless: terminate an instance during working hours and watch what happens.

87

How do you monitor cost as an operational concern?

Treat a cost anomaly like any other production signal, with alerting, because the failure mode is a bill discovered a month later. The mechanisms. AWS Budgets with alerts at thresholds, including a forecast-based alert so you are warned before the month ends rather than after. Cost Anomaly Detection, which learns normal spend patterns per service and flags deviations — that catches the runaway process or the misconfigured job within a day rather than at invoice time. Cost Explorer for analysis, grouped by service, account and tag. The prerequisite for any of it being useful is tagging: a consistent tag scheme applied by policy through tag policies and enforced in infrastructure code, so spend can be attributed to a team or product. Retrofitting tags is painful, and untagged spend is unattributable spend. Multiple accounts do much of this structurally, which is another argument for them. The practices that follow: a regular review of the largest line items, showback to the teams generating spend so the incentive lands where the decisions are made, and cost estimates in infrastructure pull requests via Infracost so the effect is visible before merge rather than after.

88

What is a runbook and why does it matter more than documentation?

A runbook is a specific procedure for a specific situation — what to check, in what order, and what to do about each outcome. It is written for someone at three in the morning who did not build the system. It matters more than general documentation because during an incident nobody reads architecture prose. They need the exact command, the exact dashboard link, and the decision criterion. What makes one good. Every alert links to its runbook, so the pager delivers the procedure rather than just a symptom. The steps are concrete — actual commands and actual links, not "check the database". Escalation is explicit: who to contact and when. And it states what not to do, since the dangerous actions during an incident are usually the improvised ones. The maintenance problem is real: runbooks go stale, and a stale runbook is actively harmful. The practices that help are updating it as part of every postmortem, and using it during drills so errors surface outside an incident. The progression worth aiming at is automating the runbook away — anything mechanical enough to be written as steps is usually automatable, and Systems Manager documents are one way to run it as code.

89

Where does cloud spend usually go, and where are the easy savings?

Compute is usually the largest line, followed by storage, then data transfer, then managed services. The savings that are consistently available and cheap to obtain, roughly in order of return per effort. Rightsizing: instances provisioned for peak or for a guess, running at low utilisation. Compute Optimizer identifies these directly. Over-provisioning is the default outcome of estimating rather than measuring. Unattached and idle resources: EBS volumes left after instance termination, old snapshots, idle load balancers, unassociated elastic IPs, and development environments running overnight and at weekends. Scheduling non-production shutdown outside working hours saves roughly two-thirds of that spend for a trivial change. Commitment discounts: Savings Plans and Reserved Instances for the steady baseline, which is a discount for a commitment you were making anyway. Spot for interruptible work. Graviton, which is usually a straight price-performance improvement for workloads that run on ARM. Storage lifecycle and log retention, which accumulate silently. And VPC endpoints to remove NAT gateway processing charges. The pattern is that most savings come from removing waste rather than from clever architecture.

90

How do Savings Plans and Reserved Instances work?

Both trade a commitment for a discount, typically up to around 70 percent against on-demand. Reserved Instances commit to a specific instance family in a region for one or three years. Standard RIs give the deepest discount with the least flexibility; convertible RIs allow exchange. Savings Plans commit to an hourly spend rather than to specific instances. Compute Savings Plans apply across instance families, regions, and to Fargate and Lambda, which makes them far more flexible. EC2 Instance Savings Plans give a deeper discount tied to a family in a region. The practical guidance for most teams is Compute Savings Plans, because the flexibility means the commitment keeps applying as the architecture changes — and architectures do change, which is how organisations end up with unused RIs for instance types they no longer run. The method: commit to the baseline you are confident about, not to peak. Analyse the last few months of usage, commit to the floor, and cover the variable portion with on-demand and spot. Under-committing costs a little; over-committing is paid for whether used or not. One year with no upfront is the low-risk starting point, layered over time as confidence grows.

91

What is the total cost of ownership argument for managed services?

A managed service usually costs more per unit than running the equivalent yourself on raw instances, and comparing only those numbers is the mistake. The costs not in that comparison: engineering time to build and operate it, patching and upgrades, capacity planning, backup and restore testing, monitoring, on-call burden, and the incidents caused by getting any of it wrong. Engineering time is the dominant term, and it is expensive and finite. An engineer spending a day a week operating a self-managed database is a real cost that does not appear on the AWS invoice. The honest counterpoints. At sufficient scale the unit economics can genuinely favour self-managing, which is why very large organisations do it. Some managed services have real constraints — limited configuration, version lag, or missing extensions. And lock-in is higher. The practical position for most teams: use the managed service. The break-even scale is much higher than people assume, and teams consistently underestimate the operational load of running stateful infrastructure well. The question worth asking is whether operating this thing is a differentiator for your business. If not, pay someone to do it.

92

How do you design for multi-region and should you?

Start with whether you should, because the cost is substantial and the requirement is often assumed rather than stated. The legitimate drivers: a recovery objective that a single region cannot meet, a regulatory requirement, or users in geographies where latency from one region is unacceptable. The patterns, by cost and complexity. Backup and restore — snapshots copied cross-region, recovery in hours. Pilot light — core infrastructure running minimally, scaled up on failover, recovery in tens of minutes. Warm standby — a scaled-down full environment, recovery in minutes. Active-active — both regions serving, near-zero recovery. The hard part is always data. Asynchronous replication means a failover loses recent writes, and you must decide how much loss is acceptable. Active-active means writes in two regions, which requires either partitioning users by region, or accepting conflicts and resolving them, or using a globally consistent store — each of which is a significant design commitment. The honest guidance: multi-AZ handles the overwhelming majority of failures. Multi-region should follow a stated objective with a tested failover, and an untested failover plan is a document rather than a capability.

93

How do you approach a migration to the cloud?

By choosing a strategy per workload rather than one for everything, and the usual framing is the seven Rs. Retire what is unused, which is always more than expected and is the cheapest win. Retain what should not move yet. Rehost — lift and shift onto instances, fastest and lowest risk, capturing little cloud benefit. Replatform — modest changes such as moving to a managed database, which captures much of the benefit for modest effort. Repurchase — replace with SaaS. Refactor — rearchitect for the cloud, highest cost and highest return. Relocate — move a VMware estate as-is. The practical sequencing that works: start with an inventory and dependency map, since the surprises are always dependencies nobody documented. Move something low-risk first to build capability and confidence. Replatform where a managed service maps cleanly. And defer refactoring until after the migration, because doing both at once means neither is debuggable. The mistakes to avoid: lifting and shifting everything and then being surprised the bill went up, since on-premises sizing assumptions are wrong in the cloud; and rewriting during migration, which compounds risk. And landing zone first — accounts, networking, identity and guardrails — before workloads arrive.

94

What is lock-in and how much should you worry about it?

Lock-in is the cost of switching, and the useful framing is that it is a spectrum with a price rather than a binary to be avoided. The layers differ enormously. Compute lock-in is low — containers move between providers with modest effort. Managed database lock-in is moderate; PostgreSQL on RDS moves, Aurora mostly moves, DynamoDB does not. Proprietary service lock-in is high — a system built around Step Functions, EventBridge and DynamoDB has substantial rewriting to move. Data gravity is the real constraint, since moving petabytes is slow and egress is expensive. The judgement. Avoiding managed services to remain portable means running more infrastructure yourself, which has a certain and continuous cost, to preserve optionality that is usually never exercised. That is frequently a bad trade. The defensible position: accept lock-in where the service provides real leverage, keep the business logic separable from the provider SDK behind interfaces so the coupling is at the edges, and be deliberate about data — where it lives, in what format, and how it would be extracted. Multi-cloud as insurance is expensive and usually delivers the lowest common denominator rather than resilience.

95

How do you decide between a monolith and microservices on AWS?

By whether the organisation needs independent deployment more than it needs simplicity, because that is what microservices buy and what they cost. The honest default for a new system is a well-structured monolith. It has one deployment, one datastore, local function calls instead of network calls, transactions that actually work, and no distributed debugging. A small team ships far faster. Microservices become worth it when several teams are blocked by a shared release, when parts of the system have genuinely different scaling or availability requirements, or when the codebase is large enough that reasoning about it is the bottleneck. What they cost: every local call becomes a network call that can fail, timeout and retry; transactions become sagas; debugging requires distributed tracing; and the operational surface multiplies. The cloud makes the infrastructure side cheap — it is easy to run twenty services — which disguises the fact that the design and operational complexity is unchanged. The pragmatic path is a modular monolith with clear internal boundaries, extracting a service when a specific pressure justifies it. That keeps the option open without paying for it upfront, and the boundaries you discover by running the system are better than the ones you guess.

96

How do you size infrastructure for a new application with no traffic data?

Start small, measure, and make scaling automatic — rather than estimating, because estimates without data are wrong in both directions and over-provisioning is the more expensive error. The approach. Deploy the smallest reasonable configuration with auto-scaling configured on a meaningful metric, so growth is handled without a decision. Use on-demand or serverless initially, since commitment discounts require usage patterns you do not yet have. Load test before launch to find the breaking point and the resource that saturates first. That is worth doing even roughly, because it tells you whether you are ten times or a hundred times from capacity, and it reveals the actual bottleneck — which is usually the database, not the application tier. Instrument thoroughly from day one, since the data you did not collect is the data you will want. Then revisit after a few weeks of real traffic: rightsize, add commitment discounts for the observed baseline, and adjust scaling policies. The things to get right upfront rather than later, because they are expensive to change: statelessness, CIDR planning, account structure, and the data model. Instance sizes are trivially adjustable; those are not.

97

What is caching strategy and where should a cache sit?

Caching is the highest-leverage performance and cost technique available, and the question is at which layer. The layers, from the user inward. Browser cache, controlled by Cache-Control headers — free and the fastest possible. CDN at CloudFront, which offloads the origin entirely for cacheable content. Application-level cache in Redis for computed results and query results. And the database's own buffer cache, which is why memory sizing matters. The guidance is to cache as close to the user as the correctness requirement allows, because each layer inward costs more and saves less. The hard parts. Invalidation: TTL-based expiry is simple and gives bounded staleness; explicit invalidation is precise and easy to get wrong. Most systems should prefer short TTLs and accept brief staleness. The cache key must capture everything the response varies by, particularly identity — serving one user's cached response to another is a real and serious incident pattern. And cache stampede: when a popular key expires, many requests miss simultaneously and hit the origin together. Mitigations are locking on regeneration, or serving stale while revalidating. A cache must always be optional — the system works slower without it.

98

How do you think about security in a cloud architecture beyond IAM?

In layers, assuming any single control fails. Identity is the foundation — roles rather than keys, least privilege, MFA, no long-lived credentials — and it is where most breaches begin. Network segmentation limits reach: the application in private subnets, the database isolated, security groups referencing each other so the paths are explicit and minimal. This is what turns a compromised web tier into a contained problem. Encryption in transit everywhere and at rest by default, with KMS giving revocability and an audit trail. Secrets in Secrets Manager, rotated, never in code or images — and secret scanning in CI to catch the mistake. Supply chain: pinned dependencies, vulnerability scanning of images with ECR scanning or Inspector, and signed artifacts. Detection, because prevention is incomplete: GuardDuty for threat detection, Security Hub for posture, Config for drift, and CloudTrail preserved in an account nobody can delete from. And the human layer — code review, restricted production access through approved paths, and an incident plan that has been rehearsed. The recurring theme is that the expensive breaches come from configuration and identity, not from exotic attacks.

99

What would you check first if the AWS bill doubled unexpectedly?

Cost Explorer, grouped by service and filtered to the period, with daily granularity. That identifies which service changed and on which day, which is most of the diagnosis. Then group by usage type within that service, because the specific charge matters — for EC2, whether it is instance hours or data transfer; for S3, whether it is storage, requests or retrieval. Then by account and tag to find the owner. The common causes, roughly by frequency. A misconfigured job or a retry loop generating enormous request volume — a Lambda invoking itself, or a poison message being reprocessed indefinitely. A test environment left running at production scale. Data transfer, particularly NAT gateway processing or cross-AZ traffic from a new deployment. Logs, when debug logging was enabled and forgotten. Storage accumulating — old snapshots, unexpired object versions, incomplete multipart uploads. And a forgotten resource in an unused region. A genuinely malicious cause is possible — compromised credentials mining cryptocurrency — and CloudTrail plus GuardDuty answer that, so it is worth ruling out early rather than assuming waste. The preventive measure is Cost Anomaly Detection, which flags this within a day instead of at invoice time.

100

What are the mistakes you most often see in cloud architectures?

A short list, weighted by how much damage each causes. Treating the cloud as a data centre — lifting and shifting with no change, keeping pet servers, manual configuration — which captures the costs and none of the benefits. No cost awareness until the bill arrives, with no tagging, no budgets and no anomaly detection. Over-permissive IAM, because wildcards are quick and narrowing them later never happens. State on instances, which quietly prevents auto-scaling, spot usage, and painless replacement. Single availability zone deployments, usually by accident rather than decision. Backups that are never restored, so nobody knows whether they work. Premature microservices, buying distributed-system complexity before the organisational problem it solves exists. Missing observability, so incidents are diagnosed by guessing. And console-configured infrastructure with no code, so nothing is reproducible or reviewable. The thread connecting most of them is deferring an inexpensive decision that becomes expensive later — tagging, statelessness, identity, and infrastructure as code are all cheap at the start and painful to retrofit. Those are the things worth getting right before the system is large.

Learn this free with Aria, your AI tutor → AiCanCode.org/learn/interview