Skip to main content

AWS S3

import "github.com/KARTIKrocks/objstore/s3"

store, err := s3.New(ctx,
s3.DefaultConfig().
WithBucket("my-bucket").
WithRegion("us-west-2").
WithCredentials("ACCESS_KEY", "SECRET_KEY"),
)

// With custom endpoint (MinIO, DigitalOcean Spaces, etc.)
store, err := s3.New(ctx,
s3.DefaultConfig().
WithBucket("my-bucket").
WithEndpoint("https://nyc3.digitaloceanspaces.com").
WithPathStyle(true),
)

// With IAM role (no credentials needed)
store, err := s3.New(ctx,
s3.DefaultConfig().
WithBucket("my-bucket").
WithRegion("us-east-1"),
)

// With path prefix
store, err := s3.New(ctx,
s3.DefaultConfig().
WithBucket("my-bucket").
WithPrefix("uploads/user-123"),
)

The WithEndpoint + WithPathStyle combination works against any S3-compatible service — MinIO, DigitalOcean Spaces, Cloudflare R2, Backblaze B2, Wasabi — so those providers are supported without a dedicated backend.

Multipart uploads​

Put uploads through the AWS SDK's multipart uploader, so it isn't capped at S3's 5GB single-PutObject limit — bodies larger than 5MiB are automatically split into parts and uploaded with bounded memory, regardless of whether the source io.Reader is seekable. With default settings the ceiling is 10,000 parts × 5MiB ≈ 48.8GB; for anything larger, raise the part size with WithUploadPartSize (S3 allows up to 5GiB per part, giving headroom well past S3's actual 5TB max object size). By default up to 5 parts (5MiB each, 25MiB total) are buffered in memory at once; tune part size and parallelism independently with WithUploadPartSize / WithUploadConcurrency:

// Lower memory ceiling: one 8MiB part in flight at a time.
store, err := s3.New(ctx,
s3.DefaultConfig().
WithBucket("my-bucket").
WithUploadPartSize(8*1024*1024).
WithUploadConcurrency(1),
)

An ETag returned for an object uploaded via multipart is S3's composite multipart ETag ("<hex>-<partcount>"), not a plain content MD5 — this differs from small objects (under 5MiB), which still get a plain-MD5 ETag from a direct PutObject. Treat FileInfo.ETag as an opaque version tag, not a content hash, if your objects may cross that size threshold.

Conditional writes (WithOverwrite(false), WithIfMatch) are sent as S3's native If-None-Match / If-Match headers. For multipart uploads they go on CompleteMultipartUpload. Some S3-compatible services don't support conditional writes yet. See Conditional Writes.

Batch delete​

The S3 backend implements objstore.BatchDeleter:

s3Store.DeleteMultiple(ctx, []string{"file1.txt", "file2.txt"})