Skip to main content

What is Amazon S3? Learn the Basics and Pricing

Tags:

When storing documents or images on AWS, S3 is usually the first option to consider. However, using S3 without understanding the basics can lead to security and cost issues later. This article explains the fundamentals of Amazon S3.

What is Amazon S3?

Amazon S3 is a storage service where you can store documents, images, videos, and other data. In S3, stored data is called an object, and the resource that holds objects is called a bucket. While S3 is essentially an object storage service, you need to be mindful of cost optimization and security to prevent unintended public exposure.

S3 offers high durability (99.999999999%) and requires no upfront capacity reservation, so you can store as much data as you need without worrying about limits. Common use cases include serving images and videos for websites, storing application logs, backing up and archiving data, and hosting static websites. S3 integrates easily with other AWS services like EC2 and Lambda, making it a central component in many system architectures.

Pricing

S3 uses a pay-as-you-go model — you only pay for what you use. The cost is primarily determined by how much data you store and which storage class you use. There are also charges for requests and data transfer, but these have minimal impact when usage is low.

Storage Classes

There are several options, but the commonly used storage classes are listed below. The default is S3 Standard, so if you're using S3 for backups or infrequent access, consider switching to a lower-cost storage class.

Use CaseStorage ClassPrice (US East, N. Virginia)
Frequent accessS3 StandardUSD 0.023/GB
A few times a monthS3 Standard-IAUSD 0.0125/GB
Once a quarterS3 Glacier Instant RetrievalUSD 0.004/GB
Rarely accessedS3 Glacier Deep ArchiveUSD 0.00099/GB

Security

S3 security incidents are common, and if your bucket is publicly accessible, confidential data can be leaked. Restrict access permissions so that only the users and services that need access can reach your bucket. If you have no plans to make data publicly available, block public access on the bucket.

Public access is granted to buckets and objects through access control lists (ACLs), access point policies, bucket policies, or a combination of these. To ensure that all public access to your Amazon S3 access points, buckets, and objects is blocked, we recommend that you enable all four settings to block public access for your account.

Bucket Policy

A bucket policy lets you attach a JSON-formatted policy directly to a bucket for fine-grained access control. You can restrict access to specific IAM users or roles, or allow requests only from a specific IP address range. Here's an example policy that grants read access to a specific IAM user only.

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/example-user"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::exrecord-test-bucket/*"
}
]
}

You can configure bucket policies from the AWS Console or via the AWS CLI. Since a misconfigured policy can result in unintended access control, verify the behavior in a test environment before applying. You can also use bucket policies to restrict access to a specific VPC or require MFA authentication. Combined with IAM policies, they enable more granular access management.

Encryption

S3 can encrypt objects at rest. Server-side encryption with S3-managed keys (SSE-S3) is enabled by default, so objects are automatically encrypted using keys managed by AWS. If you have stricter compliance requirements, you can opt for SSE-KMS, which uses keys managed in AWS KMS. Encryption settings can be configured at bucket creation time or changed later from the bucket properties.

Versioning

When you enable versioning, S3 retains previous versions of objects when they are overwritten or deleted. This means you can recover an earlier version even if you accidentally overwrite or delete an object, so it's worth enabling for buckets that hold important data.

Run the following command to enable versioning:

❯ aws s3api put-bucket-versioning --bucket exrecord-test-bucket --versioning-configuration Status=Enabled

Once enabled, each upload to the same key adds a new version while keeping previous ones. List all versions with:

❯ aws s3api list-object-versions --bucket exrecord-test-bucket

Keep in mind that versioning increases storage costs as more versions accumulate. Setting up a lifecycle rule to automatically delete old versions makes the bucket easier to manage. Also note that deleting an object in a versioned bucket only adds a delete marker — previous versions are still retained. To permanently delete an object, you must specify its version ID.

Using S3 with the AWS CLI

Let's try using S3 via the AWS CLI. The results of running each command are shown below.

Creating a Bucket

Bucket names must be globally unique across all AWS accounts, so use a distinctive name. The bucket will be created in the region specified by your AWS CLI profile.

❯ aws s3 mb s3://exrecord-test-bucket
make_bucket: exrecord-test-bucket

Verify that the bucket was created:

❯ aws s3 ls
2026-04-12 05:07:26 exrecord-test-bucket

Check the public access settings. If all values are true, the bucket is secure and inaccessible from the public:

❯ aws s3api get-public-access-block --bucket exrecord-test-bucket
{
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": true,
"IgnorePublicAcls": true,
"BlockPublicPolicy": true,
"RestrictPublicBuckets": true
}
}

Uploading an Object

Upload a local file to your S3 bucket:

❯ aws s3 cp test.txt s3://exrecord-test-bucket
upload: ./test.txt to s3://exrecord-test-bucket/test.txt

List the objects in the bucket using the same command with the bucket specified:

❯ aws s3 ls s3://exrecord-test-bucket
2026-04-12 05:10:22 0 test.txt

Downloading an Object

Download a file from S3 to your local machine. Note that the argument order is reversed compared to the upload command:

❯ aws s3 cp s3://exrecord-test-bucket/test.txt .
download: s3://exrecord-test-bucket/test.txt to ./test.txt

Deleting an Object

Delete an object from your S3 bucket. Unless versioning is enabled, deleted objects cannot be recovered, so double-check the key before running this command.

❯ aws s3 rm s3://exrecord-test-bucket/test.txt
delete: s3://exrecord-test-bucket/test.txt

To delete all objects in a bucket at once, use the --recursive option. This is useful when you want to remove everything in bulk.

❯ aws s3 rm s3://exrecord-test-bucket --recursive

Deleting a Bucket

To delete a bucket, you first need to remove all objects inside it — deletion will fail if any objects remain. Adding --force removes all objects and the bucket itself in one step.

❯ aws s3 rb s3://exrecord-test-bucket --force
remove_bucket: exrecord-test-bucket

Note that if versioning is enabled, --force alone is not enough. You need to delete all versions and delete markers before the bucket can be removed.

Summary

This article covered what S3 is and its basic usage. Since S3 is used in nearly every AWS setup, keep the following points in mind:

  • Verify your Block Public Access settings
  • Grant only the minimum necessary access permissions
  • Choose the appropriate storage class based on access frequency to optimize costs
  • Enable versioning on buckets with important data to protect against accidental deletion

By following these practices, you can operate S3 securely and cost-effectively.