☰ All modules Tier 3 · S3 GuideCheat sheet ‹ containersec2 ›
Contents
  1. Buckets objects keys and metadata
  2. Access control Block Public Access and access logs
  3. Encryption at rest and in transit
  4. Versioning MFA Delete and Object Lock
  5. Replication CRR and SRR
  6. Storage classes and lifecycle rules
  7. Event notifications and EventBridge
  8. Performance multipart uploads and Transfer Acceleration
  9. Presigned URLs CORS and static websites
  10. Access Points and Object Lambda
  11. Numbers to know
  12. Decision rules
  13. Memory hooks

S3 — Cheat Sheet

Verified against AWS documentation on 2026-10-12 · ⚠️ = changed vs older material: learn the value shown here (older practice material may say otherwise; full list in the guide's "Changed vs older material") · ⚠️ unverified = not confirmed in AWS docs, don't rely on it · explanations and examples: notes/s3-guide.md.

Buckets objects keys and metadata

Topic Current facts Memory hook
Bucket names 3–63 chars; lowercase letters, digits, -, .; begin and end with a letter or digit; no ..; not IP-shaped Global per partition
Reserved name parts ⚠️ Prefixes xn--, sthree-, amzn-s3-demo-; suffixes -s3alias, --ol-s3, .mrap, --x-s3, --table-s3 AWS keeps some names for itself
Account regional namespace <prefix>-<account-id>-<region>-an created with x-amz-bucket-namespace: account-regional; only your account can ever own it Your own slice of the namespace
Buckets per account ⚠️ 10,000 by default, raisable to 1,000,000 (older: 100)
Bucket identity Name and Region fixed at creation; ownership not transferable; a deleted name can be re-created by anyone Delete = give the name away
Object size ⚠️ 0 B to 50 TB (48.8 TiB); single PutObject ≤ 5 GB; console ≤ 160 GB One PUT, five gigs
Keys ≤ 1,024 bytes UTF-8, case-sensitive; "folders" are prefixes split on / Flat namespace, painted folders
User metadata x-amz-meta-*, ≤ 2 KB, names stored lowercase, immutable: change with CopyObject + MetadataDirective=REPLACE Carved at upload
System metadata you set Content-Type, Cache-Control, Content-Disposition, Content-Encoding, x-amz-storage-class, x-amz-server-side-encryption, x-amz-website-redirect-location
Object tags ≤ 10 per object; key ≤ 128, value ≤ 256 chars; mutable; PutObjectTagging replaces the whole set; GetObject returns only x-amz-tagging-count Sticky notes you can swap
Tag uses IAM/bucket policy conditions (s3:ExistingObjectTag/<key>), lifecycle and replication filters, Storage Class Analysis
Metadata search ⚠️ S3 Metadata tables (Iceberg, query with Athena, GA 2025-01-27) or an own DynamoDB index; LIST filters by prefix only
Consistency Strong read-after-write for object PUT, DELETE, LIST; bucket configuration eventually consistent Objects instant, settings settle
Conditional writes ⚠️ If-None-Match: * / If-Match: <ETag> on PutObject, CompleteMultipartUpload, CopyObject (since 2025-10-29) → 412 Precondition Failed; a racing delete gives 409 (If-None-Match) or 404 (If-Match) First writer wins
Conditional deletes ⚠️ If-Match: <ETag> on DeleteObject / DeleteObjects since 2025-09-16; enforce with s3:if-match
403 vs 404 Missing key gives 404 NoSuchKey only with s3:ListBucket; without it 403 AccessDenied No list, no 404
ETag MD5 of the data only for single-part, unencrypted or SSE-S3 objects

Access control Block Public Access and access logs

Topic Current facts Memory hook
Same-account access One Allow is enough (identity policy or bucket policy) unless an explicit Deny applies Either key opens it
Cross-account access Caller's IAM policy and the bucket policy (and the KMS key policy for SSE-KMS) Both doors must open
Bucket policy ≤ 20 KB; needs Principal; ListBucket on arn:aws:s3:::bucket, object actions on arn:aws:s3:::bucket/* Bucket ARN lists, slash-star reads
Object Ownership ⚠️ Default Bucket owner enforced = ACLs disabled for every new bucket since April 2023; other ACLs fail with 400 AccessControlListNotSupported ACLs are retired
BPA settings BlockPublicAcls, IgnorePublicAcls, BlockPublicPolicy, RestrictPublicBuckets
BPA levels ⚠️ Organization (Organizations S3 policy, all four together), account (s3control, all Regions), bucket, access point (fixed at creation); most restrictive wins Strictest layer wins
BPA default ⚠️ All four settings on for every new bucket, whatever the creation method, since April 2023
"Public" policy "Principal": "*" without a fixed-value limit such as aws:SourceVpce, aws:PrincipalOrgID or a narrow aws:SourceIp (broader than /8 counts as public)
Force HTTPS Deny statement with "Bool": {"aws:SecureTransport": "false"}
Access logs to S3 Destination in the same Region and account; SSE-S3 only; no Object Lock, no Requester Pays; grant logging.s3.amazonaws.com s3:PutObject in the bucket policy Same Region, same account
Log loop Never log a bucket into itself; each log write creates more logs
Access logs elsewhere ⚠️ CloudWatch Logs delivery: structured JSON, cross-account and cross-Region, KMS
Log timing Best effort, usually within a few hours; not a complete accounting

Encryption at rest and in transit

Topic Current facts Memory hook
SSE-S3 ⚠️ Header x-amz-server-side-encryption: AES256; applied to every new upload since 2023-01-05; free; can't be disabled Always on
SSE-KMS aws:kms + x-amz-server-side-encryption-aws-kms-key-id; symmetric key in the bucket's Region; CloudTrail logs key use Audit trail on the key
SSE-KMS permissions kms:GenerateDataKey to upload, kms:Decrypt to download, both for multipart Write = generate, read = decrypt
aws/s3 key Can't be used cross-account; share with a customer managed key
DSSE-KMS ⚠️ aws:kms:dsse, two AES-256 layers, added 2023-06-13, no S3 Bucket Keys Double lock, no shortcut
SSE-C Headers ...-customer-algorithm (AES256), ...-customer-key, ...-customer-key-MD5; HTTPS only; not in console; key needed on every GET/HEAD/copy You hold the key, every time
SSE-C default ⚠️ Blocked by default since April 2026; enable with PutBucketEncryption and BlockedEncryptionTypes = NONE; else 403 AccessDenied
Client-side Amazon S3 Encryption Client or AWS Encryption SDK; S3 stores ciphertext
Default encryption SSE-S3, SSE-KMS or DSSE-KMS (never SSE-C); applies to uploads without headers; existing objects unchanged
Re-encrypt old objects ⚠️ UpdateObjectEncryption turns SSE-S3/SSE-KMS objects into SSE-KMS (new key or Bucket Key) in place, keeping ETag and Last-Modified; unencrypted, SSE-C, DSSE-KMS → CopyObject or Batch Operations Copy (not SSE-C) Re-key without a rewrite
GET with SSE headers Sending encryption headers on GET/HEAD of SSE-S3/SSE-KMS/DSSE objects returns 400 Bad Request
KMS throttling ⚠️ Shared symmetric quota 10,000/s default, 20,000/s in seven Regions, 100,000/s in us-east-1, us-west-2, eu-west-1 → ThrottlingException
S3 Bucket Key Cuts KMS request costs by up to 99 %; new objects only; encryption context becomes the bucket ARN

Versioning MFA Delete and Object Lock

Topic Current facts Memory hook
Versioning states Unversioned → enabled ↔ suspended; never back to unversioned One-way door
Existing objects Version ID null when versioning is first enabled
Simple DELETE Adds a delete marker (GET → 404); delete the marker to restore Marker hides, doesn't destroy
DELETE with version ID Permanently removes that version
Suspended bucket New writes overwrite the null version; older versions are kept
MFA Delete MFA needed to suspend versioning and to permanently delete versions; root user only; CLI/API only; incompatible with lifecycle Root, CLI, no lifecycle
Object Lock ⚠️ Requires versioning; can be enabled on existing buckets (since 2023-11-20); can't be disabled
Governance mode Bypass with s3:BypassGovernanceRetention + x-amz-bypass-governance-retention: true Governance has a back door
Compliance mode Nobody, root included, can delete or shorten; only extend Compliance has no door
Legal hold On/off, no expiry, s3:PutObjectLegalHold, independent of retention Holds until lifted
Delete on a locked version Simple DELETE adds a marker; permanent delete → 403
Retention limits Max 100 years; cap with s3:object-lock-remaining-retention-days; PUT with retention needs Content-MD5 or a checksum header

Replication CRR and SRR

Topic Current facts Memory hook
Requirements Versioning on source and destination; IAM role trusted by s3.amazonaws.com; caller needs iam:PassRole Versions both ends
What replicates Objects written after the rule, with metadata, tags, ACL updates, Object Lock retention New only
Existing objects S3 Batch Replication (also failed and already-replicated objects) Batch for the backlog
Never replicated Version-ID deletes, lifecycle actions, replicas from another rule, Glacier Flexible/Deep Archive objects, bucket settings No chains
Delete markers Not by default; enable DeleteMarkerReplication (not with tag-based rules)
SSE-KMS objects Opt in with SseKmsEncryptedObjects, set ReplicaKmsKeyID in the destination Region, grant kms:Decrypt + kms:Encrypt KMS needs an invitation
SSE-C objects ⚠️ Replicated by default since 2022-10-24
Cross-account Destination bucket policy must allow the source role; Bucket owner enforced makes the destination own replicas
RTC ⚠️ SLA: 99.9 % of objects replicated within 15 minutes (credits below 99.9 %; 99.99 % is the design figure); metrics and threshold events; 1 Gbps default transfer quota; not for Batch Replication Fifteen-minute promise
Limits 1,000 rules per configuration; 28 destinations per source (adjustable)
Status values PENDING, COMPLETED, FAILED on the source; REPLICA on the copy
CRR vs SRR uses CRR: distant DR or regulator copy, local reads in another Region; SRR: in-country copies, one bucket for many log sources, live prod data in a test account

Storage classes and lifecycle rules

Class AZs · availability · min duration · min billable size Memory hook
Standard ≥ 3 · 99.99 % · none · none Hot by default
Intelligent-Tiering ≥ 3 · 99.9 % · none · none (< 128 KB not monitored); no retrieval fees Let S3 decide
Standard-IA ≥ 3 · 99.9 % · 30 days · 128 KB; per-GB retrieval fee Rare but instant
One Zone-IA 1 · 99.5 % · 30 days · 128 KB; lost if the AZ is destroyed Re-creatable only
Glacier Instant Retrieval ≥ 3 · 99.9 % · 90 days · 128 KB; milliseconds Archive price, instant read
Glacier Flexible Retrieval ≥ 3 · 99.99 % after restore · 90 days · 40 KB overhead; restore needed Minutes to hours
Glacier Deep Archive ≥ 3 · 99.99 % after restore · 180 days · 40 KB overhead; restore needed Cheapest, slowest
Express One Zone ⚠️ 1 (your choice) · 99.95 % · none · none; directory buckets, single-digit ms Fastest, one AZ
Topic Current facts Memory hook
Durability 99.999999999 % (11 nines) for all current classes
Flexible Retrieval restores Expedited 1–5 min, Standard 3–5 h, Bulk 5–12 h (free) 5 minutes, 5 hours, 12 hours
Deep Archive restores Standard ≤ 12 h, Bulk ≤ 48 h, no Expedited 12 and 48
Restore mechanics RestoreObject with Days + Tier; temporary copy billed at Standard; x-amz-restore shows progress; 1,000 restore requests/s
Intelligent-Tiering tiers ⚠️ Infrequent after 30 days, Archive Instant after 90; opt-in Archive Access 90–730 days, Deep Archive Access 180–730 days
Lifecycle actions Transition, Expiration, NoncurrentVersionTransition, NoncurrentVersionExpiration, AbortIncompleteMultipartUpload, ExpiredObjectDeleteMarker
Lifecycle limits 1,000 rules per bucket; filters by prefix, tags, size; PUT replaces the whole configuration Send every rule
Small objects ⚠️ < 128 KB not transitioned to any class by default since September 2024 (older: only IA transitions skipped); override with size filters or varies_by_storage_class
IA transition age ⚠️ No minimum age before Standard-IA/One Zone-IA since 2026-07-16: Days 0 or more (older: 30 days in Standard); 30-day storage minimum still billed
Waterfall Down only; One Zone-IA → only Glacier Flexible or Deep Archive; Glacier Flexible → only Deep Archive; never back up Downhill only
Versioned expiration Adds delete markers; also expire noncurrent versions and orphaned markers Expiring current grows the bucket
Lifecycle timing Rounded to midnight UTC; runs asynchronously; billing changes when the rule is satisfied
Bucket policy vs lifecycle Even a Deny for every principal doesn't stop lifecycle expirations or transitions; disable the rule
Storage Class Analysis Standard → Standard-IA advice only; charts in 24–48 h; result after ~30 days; daily CSV export

Event notifications and EventBridge

Topic Current facts Memory hook
Destinations SNS standard topic, SQS standard queue, Lambda, EventBridge; same Region; one destination per configuration
FIFO SNS FIFO and SQS FIFO aren't direct destinations; reach SQS FIFO through EventBridge FIFO via the bus
Event types ObjectCreated:*, ObjectRemoved:*, ObjectRestore:*, Replication:*, LifecycleExpiration:*, LifecycleTransition, IntelligentTiering, ObjectTagging:*, ObjectAcl:Put, ObjectRetention:Put
Lifecycle deletes ObjectRemoved:* doesn't fire; use LifecycleExpiration:*
Filters Prefix and suffix only, no wildcards, case-sensitive; no overlapping filters for the same event type
Several consumers One SNS topic fan-out or EventBridge rules Fan out, don't duplicate
Delivery Normally a few seconds, no guaranteed bound; at least once; duplicates possible; unordered Idempotent consumers
sequencer Orders events for the same key only (left-pad, then compare)
Event message Up to 64 KB; key URL-encoded (+ for spaces); s3:TestEvent has no Records Decode the key
Permissions Lambda resource policy (lambda:InvokeFunction for s3.amazonaws.com), SNS topic policy (SNS:Publish), SQS queue policy (SQS:SendMessage), scoped by aws:SourceArn + aws:SourceAccount Destination says yes
Saving a configuration S3 validates each destination (SNS/SQS test message, Lambda permission check); one failure fails the whole PUT; the call replaces the entire configuration Destination must say yes first
Encrypted SQS/SNS Key policy must allow s3.amazonaws.com kms:GenerateDataKey + kms:Decrypt
Recursion Output into the triggering bucket/prefix re-triggers the function; separate bucket or prefix
EventBridge "EventBridgeConfiguration": {} sends all events; no extra S3 permissions; filter on any field; ≤ 5 targets per rule; archive and replay
Notifications quota 100 notification configurations per bucket

Performance multipart uploads and Transfer Acceleration

Topic Current facts Memory hook
Request rate Per partitioned prefix: 3,500+ writes and 5,500+ reads per second; any number of prefixes Scale by prefix
503 Slow Down S3 is scaling up; retry with backoff, spread keys over more prefixes
Latency Roughly 100–200 ms for small objects; cache with CloudFront/ElastiCache or use Express One Zone for less
Multipart sizes Recommended from 100 MB, required above 5 GB; ≤ 10,000 parts of 5 MiB–5 GiB (last part smaller)
Multipart lifecycle Parts billed until complete or abort; add AbortIncompleteMultipartUpload Finish or abort
Multipart permissions s3:PutObject for create/upload/complete; s3:AbortMultipartUpload, s3:ListMultipartUploadParts separate; SSE-KMS adds kms:GenerateDataKey + kms:Decrypt
CLI defaults multipart_threshold 8 MB, multipart_chunksize 8 MB, max_concurrent_requests 10
Byte-range GET Range: bytes=0-1023; parallel downloads, partial reads, cheap retries; partNumber reads one part Read just the slice
Transfer Acceleration Edge locations + AWS backbone; <bucket>.s3-accelerate.amazonaws.com; no periods in the name; up to 20 min to take effect Long distance only
S3 Select ⚠️ Closed to new customers since 2024-07-25; use byte ranges, Athena or app-side filtering
Large objects > 5 TB SDK Transfer Manager with the CRT recommended

Presigned URLs CORS and static websites

Topic Current facts Memory hook
Presigned URL Pre-signed request for one operation on one key; uses the creator's permissions; reusable until expiry Borrowed signature
Lifetimes Console 1 min–12 h; CLI/SDK up to 7 days (604,800 s) with IAM user keys; temporary credentials end it sooner Seven days, at most
aws s3 presign GET only; --expires-in default 3,600 s CLI signs reads
Uploads SDK presigned PUT (send the same Content-Type) or presigned POST with conditions like content-length-range
Errors SignatureDoesNotMatch (clock, headers, Region), ExpiredToken (credentials expired), AccessDenied (creator lacks permission or URL expired)
Restrict presigned use s3:signatureAge (ms) in a bucket policy; aws:SourceIp / aws:SourceVpce still apply
CORS preflight Browser OPTIONS with Origin, Access-Control-Request-Method, Access-Control-Request-Headers; S3 uses the first matching rule
CORS rule elements AllowedOrigins, AllowedMethods (GET, PUT, POST, DELETE, HEAD), AllowedHeaders, ExposeHeaders, MaxAgeSeconds; ≤ 100 rules
Where CORS goes On the bucket being called, not on the site that served the page Configure the target
Read ETag in JavaScript List ETag in ExposeHeaders
Website endpoints http://<bucket>.s3-website-<region>.amazonaws.com or ...s3-website.<region>...; HTTP only; GET/HEAD only; no access points HTTPS = CloudFront (or Amplify Hosting)
Public website BPA allowing public policies + bucket policy s3:GetObject for "*" on bucket/*; index document required
Website errors 403 = not publicly readable; 404 = key or index document missing
Custom domain Route 53 alias; bucket name must equal the host name

Access Points and Object Lambda

Topic Current facts Memory hook
Access point Named endpoint for one bucket with its own policy, BPA settings and network origin (Internet or VPC) One door per app
Limits 10,000 per account per Region (adjustable); names 3–50 chars unique per account+Region; policy ≤ 20 KB
Fixed at creation Bucket, network origin, BPA settings
Two policies Access point policy and bucket policy must allow; delegate with s3:DataAccessPointAccount Bucket delegates, door decides
Restrictions Object operations only; HTTPS + SigV4 only; no anonymous access; not a replication destination
Addressing ARN arn:aws:s3:<region>:<account>:accesspoint/<name> or the -s3alias alias in place of a bucket name
VPC origin Requests only from that VPC through an endpoint whose policy allows both the access point and the bucket
Condition keys s3:DataAccessPointArn, s3:DataAccessPointAccount, s3:AccessPointNetworkOrigin
Object Lambda flow Object Lambda Access Point → Lambda → supporting access point; function calls WriteGetObjectResponse within 60 s (s3-object-lambda:WriteGetObjectResponse) No write-back, 500
Object Lambda status ⚠️ Existing customers and selected APN partners only since 2025-11-07
Alternatives Lambda behind a function URL, API Gateway or CloudFront; client-side processing

Numbers to know

Item Value Note
Maximum object size 50 TB (48.8 TiB) ⚠️ Older material: 5 TB
Single PutObject 5 GB Larger → multipart
Console upload 160 GB
Multipart recommended from 100 MB Required above 5 GB
Parts per upload 10,000 Part numbers 1–10,000
Part size 5 MiB – 5 GiB Last part may be smaller
Object key length 1,024 bytes (UTF-8) Prefix counts
User-defined metadata 2 KB Within the 8 KB PUT header limit
Tags per object 10 Key 128, value 256 characters
Buckets per account 10,000 default ⚠️ Up to 1,000,000; older: 100
Bucket name length 3–63 characters
Bucket policy size 20 KB Same for access point policies
Requests per prefix per second 3,500 writes / 5,500 reads Unlimited prefixes
Small-object latency ~100–200 ms First byte for larger objects
Versioning settle time ~15 minutes Before writing after first enable
Lifecycle rules per bucket 1,000 Not adjustable
Notification configurations per bucket 100
Event message size Up to 64 KB Set SQS MaximumMessageSize ≥ 64 KB
Replication rules / destinations 1,000 / 28 Destinations adjustable
Replication Time Control 15 minutes for 99.9 % of objects ⚠️ SLA level; 1 Gbps default transfer quota
Access points per account per Region 10,000 Adjustable
Access point name length 3–50 characters
CORS rules per bucket 100
Presigned URL maximum (SDK/CLI) 7 days = 604,800 s IAM user keys, SigV4
Presigned URL in the console 1 minute – 12 hours
aws s3 presign default 3,600 s GET only
Glacier Flexible Retrieval restores 1–5 min / 3–5 h / 5–12 h Expedited / Standard / Bulk
Glacier Deep Archive restores ≤ 12 h / ≤ 48 h Standard / Bulk
Minimum storage duration 30 d (IA classes) · 90 d (Glacier IR, Flexible) · 180 d (Deep Archive) Early deletes billed
Minimum billable size 128 KB (IA classes, Glacier IR) Archive classes: 40 KB overhead per object
Intelligent-Tiering moves 30 d → Infrequent, 90 d → Archive Instant Archive tiers up to 730 d ⚠️
Lifecycle default minimum transition size 128 KB ⚠️ Since September 2024
Designed availability 99.99 % Standard · 99.9 % IA, IT, Glacier IR · 99.5 % One Zone-IA · 99.95 % Express One Zone
Durability 11 nines All current classes
KMS symmetric request quota 10,000 / 20,000 / 100,000 per second ⚠️ Default / seven Regions / us-east-1, us-west-2, eu-west-1
Object Lock maximum retention 100 years
Transfer Acceleration activation Up to 20 minutes
Storage Class Analysis 24–48 h to first data · ~30 days to a result
Archive restore request rate 1,000 per second per account ThrottlingException above
Object Lambda response window 60 seconds WriteGetObjectResponse

Decision rules

Memory hooks