AWS
Beginner 13 min read AWS

S3 & CloudFront

Amazon S3 is object storage: files called objects live in buckets with globally unique names, keyed by a path, with 11 nines durability, versioning and lifecycle rules. CloudFront is the CDN that caches S3 content at edge locations worldwide to cut latency and egress cost. Learn both together — they are deployed as a pair.

S3bucketobjectkeyversioninglifecycleCloudFrontCDNedge locationorigin
Introduction

What is this?

Amazon S3 (Simple Storage Service) is object storage. Files called objects live in buckets — containers with globally unique names — and are addressed by a key (a case-sensitive path like logs/app/2026/08/run.log). S3 offers 99.999999999% (11 nines) durability through synchronous replication across availability zones. Amazon CloudFront is a content delivery network: it caches S3 objects at edge locations around the world so users download from the nearest edge instead of the origin bucket.

Motivation

Why do you need it?

  • S3 is where most AWS data actually lives — logs, backups, static assets, Terraform state and the frontend of modern apps.
  • CloudFront is the standard way to serve that content fast and cheaply to a global audience.
  • Versioning and lifecycle rules turn plain storage into a backup and retention system.
  • Static sites and media served via CloudFront reduce origin load and egress cost.
  • Object storage versus block storage (EBS) is a core distinction every interview covers.
Think about it

Mental model

Imagine

A library with branches worldwide

Think of

S3 and CloudFront

S3 is the central archive: every book lives on a shelf identified by a catalog number (the key), and the library never loses a copy. CloudFront is the neighborhood branch: popular books are copied to branches near you so you grab them instantly instead of waiting for the courier from the central archive. Updates flow to branches, and old editions are kept per versioning.

Mechanics

How it works

  • You create a bucket in a region with a globally unique name; objects are stored with a key, and both appear in the object's URL.
  • Data is redundantly written across availability zones within the region to provide 11 nines of durability.
  • Bucket policies and IAM policies control who can read or write; server-side encryption protects data at rest.
  • CloudFront sits in front of the bucket: the first request fetches from the origin and caches it at an edge location, keyed by the cache policy.
  • Subsequent requests anywhere in the region hit the edge — cutting latency and offloading the origin — until you invalidate the cache after a deploy.

Serving a static site through S3 and CloudFront.

Objects uploaded to S3
CloudFront distribution
First request hits the origin
Subsequent requests hit the edge
Invalidation on deploy
Versioning and lifecycle
Reference

Key commands

aws s3 ls

List buckets in the account.

aws s3 ls s3://my-bucket --recursive

List objects in a bucket by prefix and key.

aws s3 cp file.txt s3://my-bucket/

Upload an object into a bucket.

curl -sI <cloudfront-url>

Inspect the response headers, including x-cache and age.

curl -s https://my-bucket.s3.amazonaws.com/index.html

Fetch an object directly from the S3 endpoint.

Hands-on

Examples

Fetch an S3 object and inspect the CloudFront response

Fetch an S3 object and inspect the CloudFront response
$ aws s3 cp s3://my-app-bucket/index.html .
download: s3://my-app-bucket/index.html to ./index.html
$ curl -sI https://d1abc2xyz.cloudfront.net/index.html
HTTP/2 200
cache-control: public, max-age=31536000
etag: "1a2b3c4d5e6f..."
x-cache: Hit from cloudfront
age: 42

aws s3 cp pulls an object by bucket and key. The curl request to the CloudFront distribution shows HTTP 200, a long max-age so browsers and edges cache aggressively, and x-cache: Hit from cloudfront proving the edge served the object rather than the origin. The etag is the object's content hash, used for conditional requests and invalidation.

Real world

In production

  • Host the build output of a frontend (Vite, Next.js static export) in S3 behind CloudFront.
  • Store application and access logs in S3 with a lifecycle policy that ages them to Glacier and deletes after N years.
  • Enable versioning on critical buckets so accidental overwrites and deletes are recoverable.
  • Serve videos and images from CloudFront with signed URLs for private content.
  • Use S3 for Terraform state, database backups and CI artifacts — the de facto storage layer of DevOps.
Guidelines

Best practices

  • Bucket names are globally unique and use only lowercase letters, numbers, dots and hyphens.
  • Default to versioning enabled and lifecycle rules from day one — you cannot add history after data is gone.
  • Block public access on buckets unless a website needs it; prefer CloudFront and signed URLs.
  • Use prefixes like logs/app/2026/08/ so listing and lifecycle policies stay cheap.
  • Turn on server-side encryption and S3 access logging for auditability.
Watch out

Common mistakes

  • Making a bucket public for one file and accidentally exposing every object in it.
  • Forgetting that S3 is eventually consistent for some operations — a just-written object may briefly not appear in a list.
  • Serving an S3 static site without CloudFront and paying per-request egress from the origin region.
  • Storing unencrypted customer data in a default bucket with no versioning.
  • Using one bucket for everything, then struggling to attach permissions per team.
Root cause analysis

Common issues

Error
403 Forbidden on a public object
Root cause

Block Public Access is on, the bucket policy denies it, or the object ownership blocks it.

Fix

Disable Block Public Access only if intended, set a bucket policy allowing s3:GetObject, and confirm object ownership.

Error
NoSuchKey when downloading a file
Root cause

The key path is wrong — a typo, wrong prefix, or the object is in another bucket or region.

Fix

List the bucket with aws s3 ls s3://bucket/ --recursive and copy the exact key.

Error
CloudFront serves stale content after a deploy
Root cause

Edge caches still hold the old object and the cache policy max-age is long.

Fix

Create a CloudFront invalidation for /* after deploy, or version object keys with a hash so new URLs are fetched.

When things break

Debugging tips

  • Check the exact error code: NoSuchBucket, NoSuchKey, AccessDenied and 403 all mean different fixes.
  • Test with curl -I to see status and cache headers; x-cache tells you edge versus origin.
  • Verify the key path — S3 keys are case-sensitive and the object may sit under a prefix you missed.
  • Use aws s3 ls s3://bucket/prefix/ to confirm the object actually exists before debugging permissions.
  • For 403 on public reads, check both the bucket policy and the Block Public Access settings.
Interviews

Interview checkpoint

Practice

Hands-on lab

Fetch, Inspect and Reorganize Files Like S3
20 min · beginner
In progress
Objectives
  • Create a bucket-like directory structure with prefixes
  • Write objects (files) and confirm them with ls and cat
  • Copy and move objects the way aws s3 cp and mv would
  • Inspect HTTP response headers to reason about caching

Fetch, Inspect and Reorganize Files Like S3

20 min · beginner

0/5 steps
0%
sandbox · Linux sandbox
$
Try these commands
Test yourself

Quick quiz

0/3
1

Which statement about S3 bucket names is true?

2

CloudFront can serve content from origins other than S3, such as EC2 or a load balancer.

3

Users in Europe report slow downloads from your S3-hosted media even though the origin is in us-east-1. What is the best fix?

Quick reference

Cheat sheet

S3 essentials
BucketContainer for objects; globally unique name
ObjectData + metadata addressed by a key
KeyCase-sensitive name within a bucket
VersioningKeeps every version of an object
LifecycleAges objects to cheaper tiers, then deletes
Common S3 CLI patterns
aws s3 ls s3://bucket/List objects
aws s3 cp file s3://bucket/Upload an object
aws s3 sync dir s3://bucket/Mirror a directory
aws s3 rb s3://bucket --forceRemove a bucket
Go deeper

Official documentation