Nov 9, 20266 min read

Amazon S3 vs Google Cloud Storage

How S3 and Google Cloud Storage compare on storage classes, locations and replication, consistency, access control, signed URLs, S3 compatibility and pricing, for backends that store user files and assets.

Amazon S3 and Google Cloud Storage solve the same problem: durable storage for files addressed by key, from user uploads and generated reports to static assets and backups. For a backend, the choice usually follows the cloud the rest of the app runs on, since egress between clouds costs money and IAM is easiest within one provider. The differences still matter when you design buckets, pick classes and write code that may move between providers.

S3 vs Cloud Storage at a glance

Amazon S3Google Cloud Storage
ConsistencyStrong read-after-writeStrong read-after-write
LocationsRegional buckets, replication configured per ruleRegional, dual-region or multi-region buckets
Storage classesStandard, Intelligent-Tiering, Standard-IA, One Zone-IA, Express One Zone, Glacier tiersStandard, Nearline, Coldline, Archive
Automatic tieringIntelligent-TieringAutoclass
Access controlIAM policies, bucket policies, Block Public AccessIAM at project and bucket level, uniform bucket-level access
Temporary accessPresigned URLs (SigV4)Signed URLs (V4)
ImmutabilityObject LockRetention policies, Bucket Lock, object retention
Event notificationsS3 Event Notifications, EventBridgePub/Sub notifications, Eventarc
S3 APINativeXML API with HMAC keys

Storage classes

S3 has more classes, chosen per object, and the S3 storage classes range from Standard through Standard-IA and One Zone-IA for infrequent access to the Glacier tiers for archives, with minimum storage durations and retrieval fees on the colder ones. Intelligent-Tiering moves objects between access tiers by observed access, for a small monitoring fee per object.

Cloud Storage classes are Standard, Nearline, Coldline and Archive, with minimum storage durations of 30, 90 and 365 days for the three colder classes. All four use the same API and have millisecond access, including Archive, which differs from Glacier Flexible Retrieval and Deep Archive, where objects are restored before they can be read. Autoclass moves objects between classes by access pattern.

For typical backend data, such as user uploads and generated files read soon after they are written, both end up on the standard class, and lifecycle rules move old objects to a colder class.

Locations and replication

An S3 bucket lives in one region and spreads data across availability zones. Copies in another region need replication rules, with Replication Time Control as an option for a 15 minute target. Cloud Storage makes location a bucket setting: a regional bucket, a dual-region bucket in two named regions, or a multi-region bucket across a continent, with turbo replication as an option for dual-region buckets. If the requirement is geo-redundant storage with one bucket name, Cloud Storage needs less configuration.

Access control and signed URLs

S3 combines IAM policies on roles with bucket policies on the bucket, and Block Public Access settings at the account and bucket level guard against accidental exposure. Cloud Storage grants IAM roles on the project or bucket, and uniform bucket-level access turns off per-object ACLs so only IAM applies. Both generate time-limited URLs for direct uploads and downloads, which keeps large files out of the API servers.

S3 compatibility

Many tools speak only the S3 API, which is why Cloud Storage's XML API accepting S3 requests with HMAC keys matters: rclone, the AWS CLI and S3 SDKs work with an endpoint override for common operations. The compatibility is partial, and S3-specific features fall outside it, so an app that depends on them stays on S3 or uses the Cloud Storage client libraries.

Pricing

Standard-class storage prices per GB are in the same range on both, as listed on the S3 pricing and Cloud Storage pricing pages. What moves the bill is everything around storage: per-request charges for writes and reads, retrieval fees and minimum durations on colder classes, and internet egress, which for user-facing downloads is often the largest line. A CDN in front of public files reduces both egress and request counts on either cloud.

Same bucket code on both with Encore

Encore

Encore combines an open source infrastructure SDK with a platform that provisions and deploys into your own AWS or GCP account. A bucket is declared in the application code, and the cloud is chosen per environment, so the S3 versus Cloud Storage decision follows the environment instead of the code:

package media import ( "context" "time" "encore.dev/beta/auth" "encore.dev/storage/objects" "github.com/google/uuid" ) // Private bucket: S3 on AWS, Cloud Storage on GCP. var uploads = objects.NewBucket("uploads", objects.BucketConfig{Versioned: true}) // Public bucket served through a CDN when deployed. var assets = objects.NewBucket("public-assets", objects.BucketConfig{Public: true}) type UploadURLResponse struct { Key string URL string } // UploadURL returns a signed URL the client can PUT a file to directly. // The key is generated for the authenticated caller, so a client cannot // overwrite another object. // //encore:api auth method=POST path=/uploads/url func UploadURL(ctx context.Context) (*UploadURLResponse, error) { uid, _ := auth.UserID() key := string(uid) + "/" + uuid.NewString() u, err := uploads.SignedUploadURL(ctx, key, objects.WithTTL(15*time.Minute)) if err != nil { return nil, err } return &UploadURLResponse{Key: key, URL: u.URL}, nil } type AssetResponse struct { URL string } // AssetURL returns the public URL of an asset. // //encore:api public method=GET path=/assets/*key func AssetURL(ctx context.Context, key string) (*AssetResponse, error) { return &AssetResponse{URL: assets.PublicURL(key).String()}, nil }

The same code produces an S3 presigned URL on AWS and a Cloud Storage signed URL on GCP. On deploy, Encore provisions the buckets with unique names and configures public buckets to be publicly readable behind a CDN, as described in the object storage docs, and it provisions an IAM role for the service on AWS and a service account per service on GCP, per the AWS and GCP infrastructure docs. encore run serves both buckets from a local object storage server, so signed uploads work in development without either cloud. TypeScript has the same primitives through Bucket.

Best fit: teams that want object storage code that runs locally and on either cloud, with buckets provisioned in their own account.

How to choose

Pick the store that matches the cloud your compute runs on, since egress and IAM both favor keeping files next to the app. Within that, S3 offers more storage classes, Intelligent-Tiering and the native S3 API that third-party tools expect, and Cloud Storage offers dual-region and multi-region buckets as a simple setting and immediate access on every class. If the app may run on both clouds, keep provider-specific storage calls out of the application code.

Frequently asked questions

What is the difference between Amazon S3 and Google Cloud Storage?

Both are object stores with strong consistency, versioning, lifecycle rules and signed URLs. The main differences are location and classes: Cloud Storage offers dual-region and multi-region buckets as a location choice and four classes that share one API, while S3 buckets are regional with replication configured separately and has more classes, including Intelligent-Tiering and Glacier archive tiers. Access control follows each cloud's IAM model.

Is Google Cloud Storage compatible with the S3 API?

Partly, since Cloud Storage's XML API accepts many S3 requests when you authenticate with HMAC keys, so tools like the AWS CLI, rclone and many S3 SDK calls work with an endpoint override. Features with no Cloud Storage equivalent, and some newer S3 APIs, are not supported, so test the calls your app makes.

Which is cheaper, S3 or Google Cloud Storage?

Per-GB storage prices for the standard classes are close, and the total depends on operations, retrieval fees for colder classes, minimum storage durations and internet egress. Egress and request charges often outweigh storage for user-facing apps, so price your read and write pattern on both pricing pages.

How do I use the same object storage code on S3 and Google Cloud Storage?

Use an abstraction that maps to both: with Encore you declare a bucket with objects.NewBucket in Go or new Bucket in TypeScript, and the Encore platform provisions S3 on AWS or Cloud Storage on GCP, with the same Upload, Download and SignedUploadURL calls in your code and a local bucket under encore run.

Deploy to your cloud on AWS and Google Cloud
without managing infrastructure

Encore lets developers and agents define application infrastructure directly in code, then automatically provisions it from local development to production in your AWS or GCP account.

~/orders — claude
Claude Code
Claude Code v2.1.180Opus 5.5~/orders