There are two ways to reach "Glacier" on AWS, and they are easy to confuse. The old way is a standalone service - Glacier Vaults, archives, and jobs, with its own API. The modern way is far simpler: Glacier is just a set of S3 storage classes you use through the S3 API you already know.
This page is about the modern way. You write objects into GLACIER_IR, GLACIER, or DEEP_ARCHIVE with put_object, and you read them back with restore_object plus get_object. Same bucket, same keys, same client. Reach for the Vault API only when maintaining an existing Vault workload.
You set StorageClass on put_object, on copy_object (to re-tier an existing object in place), and on multipart uploads via create_multipart_upload. The value is just a string - GLACIER_IR, GLACIER, or DEEP_ARCHIVE. The object keeps its key and bucket; only its storage tier changes.
restore_object takes a RestoreRequest with two parts: Days, how long the temporary readable copy should live, and GlacierJobParameters.Tier, which retrieval speed to buy (Expedited, Standard, or Bulk). The call returns quickly - it queues a job. When the job finishes, the object is readable via get_object until the copy's expiry-date, after which it goes cold again without changing storage class.
head_object (or get_object_attributes) returns a Restore header once a restore exists:
ongoing-request="true" - the restore job is still running.
ongoing-request="false", expiry-date="..." - the copy is ready and expires at that date.
Polling this works for scripts, but the production-grade pattern is an S3 event notification on s3:ObjectRestore:Completed, so your code reacts instead of looping.
The standalone Glacier Vault service predates these storage classes. It has its own vaults, archive ids, and job model, and it does not share S3's bucket, key, lifecycle, or event ecosystem. AWS positions S3 Glacier storage classes as the path forward. New work should use the S3 API; the Vault API is legacy, covered on its own page only for existing deployments.
Reading GLACIER or DEEP_ARCHIVE without restoring - a bare get_object fails with InvalidObjectState. Fix: call restore_object first and wait for the restore to complete before get_object.
Expecting restore to be synchronous - restore_object returns immediately but the data is not ready for minutes to hours. Fix: poll the Restore header or subscribe to an ObjectRestore:Completed event.
Restoring twice - a second restore_object while one is in progress raises RestoreAlreadyInProgress. Fix: check the Restore header before issuing a new restore.
Assuming Expedited works for Deep Archive - it does not; only Standard and Bulk apply there. Fix: use Standard or Bulk tiers for DEEP_ARCHIVE.
Deleting before the minimum duration - GLACIER/GLACIER_IR bill a 90-day minimum, DEEP_ARCHIVE 180 days, even if you delete early. Fix: only archive data you expect to keep past the minimum.
Confusing the class with the Vault service - "Glacier" the storage class and "Glacier" the Vault API are different things with different SDK clients. Fix: use the S3 client and storage classes for new work.
What is the difference between S3 Glacier storage classes and the Glacier Vault service?
The storage classes (GLACIER_IR, GLACIER, DEEP_ARCHIVE) are part of S3 - same bucket, keys, and API. The Vault service is a separate, older product with its own vaults, archive ids, and jobs. Use the S3 storage classes for new work.
How do I archive an object with the SDK?
Call put_object (or copy_object to re-tier an existing one) with StorageClass set to GLACIER_IR, GLACIER, or DEEP_ARCHIVE. The object stays in the same bucket under the same key.
Why does get_object fail on my archived object?
Because GLACIER and DEEP_ARCHIVE objects are offline. A direct get_object raises InvalidObjectState. Call restore_object first, wait for the restore, then get_object. Only GLACIER_IR reads directly.
How do I know when a restore has finished?
Check the Restore header from head_object. ongoing-request="true" means it is still running; ongoing-request="false" with an expiry-date means the readable copy is ready. An s3:ObjectRestore:Completed event is the push-based alternative.
How long does the restored copy last?
For the number of Days you pass in the RestoreRequest. After that the temporary readable copy expires and the object is cold again, still in its archival class. Restore again if you need it later.
Which retrieval tier should I use?
Expedited for a fast Flexible-Retrieval restore (minutes, higher cost, not available for Deep Archive), Standard for the balanced default, and Bulk for the cheapest, slowest large-volume restores.
Can I set the storage class on a multipart upload?
Yes. Pass StorageClass to create_multipart_upload (boto3) or CreateMultipartUploadCommand (SDK v3), and all parts assemble into an object in that class.
Does archiving change the object's key or bucket?
No. Storage class is a property of the object. The key and bucket stay the same, and the object still shows up in list_objects_v2 with its StorageClass field set.
Is there a minimum storage duration?
Yes. GLACIER and GLACIER_IR bill a 90-day minimum and DEEP_ARCHIVE a 180-day minimum. Deleting or overwriting earlier still incurs the remaining minimum charge.