The modern way to archive on AWS is not a separate service - it is an S3 storage class. You write an object into GLACIER_IR, GLACIER, or DEEP_ARCHIVE with the same put_object you already know, and the object still lives in your bucket under its normal key.
This page walks the everyday archival operations: writing straight into a cold class, checking an object's class and restore state, restoring a GLACIER object so you can read it, and reading a GLACIER_IR object with no restore at all. Every example mirrors between boto3 and the AWS SDK v3.
head_object returns the storage class without downloading the body. Standard objects report no StorageClass field (it defaults to Standard); archival objects name their class.
Glacier Instant Retrieval needs no restore. A get_object works exactly as it does for Standard, just at a lower storage price.
# --- Python (boto3) ---import boto3s3 = boto3.client("s3")# The object was written with StorageClass="GLACIER_IR" - no restore needed.obj = s3.get_object(Bucket="my-bucket", Key="archive/thumbnail.jpg")data = obj["Body"].read()print(len(data), "bytes")
// --- TypeScript (AWS SDK v3) ---import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";const s3 = new S3Client({});// The object was written with StorageClass "GLACIER_IR" - no restore needed.const obj = await s3.send(new GetObjectCommand({ Bucket: "my-bucket", Key: "archive/thumbnail.jpg" }));const data = await obj.Body!.transformToByteArray();console.log(data.length, "bytes");
GLACIER_IR is the only archival class you can get directly, in milliseconds.
Trying the same get_object on a GLACIER or DEEP_ARCHIVE object raises InvalidObjectState.
Use GLACIER_IR for archives you rarely read but must read instantly when you do.
Storage is cheaper than Standard-IA, but per-GB retrieval fees are higher, so read sparingly.
GLACIER and DEEP_ARCHIVE objects must be restored first. restore_object asks S3 to create a temporary readable copy that lasts for Days, using the retrieval Tier you pick.
After a restore starts, head_object reports a Restore header. It reads ongoing-request="true" while the job runs, then flips to a completed form with an expiry date - at which point get_object works.