GCP Storage
Object storage, block storage, and file storage — GCP equivalents to S3, EBS, and EFS.
Storage Services Map
| Use case | AWS | GCP |
|---|---|---|
| Object storage | S3 | Cloud Storage (GCS) |
| Block storage (VM disk) | EBS | Persistent Disk / Hyperdisk |
| Shared file system (NFS) | EFS | Filestore |
| Local NVMe (ephemeral) | Instance Store | Local SSD |
| Transfer acceleration | S3 Transfer Acceleration | Storage Transfer Service |
| Archival | S3 Glacier | GCS Archive class |
| Auto-tiering | S3 Intelligent-Tiering | GCS Autoclass |
Cloud Storage (GCS)
GCS is GCP's S3. Globally consistent, durable (11 nines), and multi-region by default when you want it.
Bucket Locations
| Type | Example | Availability | Cost |
|---|---|---|---|
| Region | us-central1 |
Single region | Lowest |
| Dual-region | NAM4 (Iowa+S.Carolina) |
2 regions, auto-replication | Medium |
| Multi-region | US, EU, ASIA |
3+ regions | Highest |
# Create a regional bucket
gsutil mb -l us-central1 gs://my-unique-bucket-name
# Multi-region (equivalent to S3 Cross-Region Replication, but built-in)
gsutil mb -l US gs://my-multi-region-bucket
# Uniform bucket-level access (recommended — disables per-object ACLs, use IAM only)
gsutil uniformbucketlevelaccess set on gs://my-bucket
Storage Classes
| Class | Min storage | Retrieval cost | Price/GB/mo | Use case |
|---|---|---|---|---|
| Standard | None | None | $0.020 | Frequently accessed data |
| Nearline | 30 days | $0.01/GB | $0.010 | Monthly access (backups) |
| Coldline | 90 days | $0.02/GB | $0.004 | Quarterly access |
| Archive | 365 days | $0.05/GB | $0.0012 | Annual+ access (DR copies) |
# Upload to specific storage class
gsutil -o "GSUtil:default_project_id=my-project" cp \
-Z -c ARCHIVE \
large-backup.tar.gz gs://my-backup-bucket/
# Change class of existing object
gsutil rewrite -s nearline gs://my-bucket/large-file.parquet
Autoclass — Automatic Tiering
GCS Autoclass automatically moves objects between Standard → Nearline → Coldline → Archive based on access patterns. Equivalent to S3 Intelligent-Tiering.
gsutil buckets update gs://my-bucket --autoclass
Basic Operations
# Upload
gsutil cp local-file.txt gs://my-bucket/path/file.txt
# Upload directory (recursive)
gsutil cp -r ./local-dir/ gs://my-bucket/prefix/
# Sync (like aws s3 sync)
gsutil rsync -r ./local-dir/ gs://my-bucket/prefix/
gsutil rsync -r -d gs://my-bucket/prefix/ ./local-dir/ # -d deletes destination files not in source
# Download
gsutil cp gs://my-bucket/path/file.txt ./local-file.txt
# List
gsutil ls gs://my-bucket/
gsutil ls -l gs://my-bucket/ # long format with sizes
# Delete
gsutil rm gs://my-bucket/path/file.txt
gsutil rm -r gs://my-bucket/prefix/ # recursive
# Signed URL (pre-signed URL equivalent — time-limited access)
gsutil signurl -d 1h -m GET service-account-key.json gs://my-bucket/file.txt
# Better: use Workload Identity and generate via SDK, not key files
Access Control
# Grant read access to a service account (use IAM, not ACLs)
gcloud storage buckets add-iam-policy-binding gs://my-bucket \
--member="serviceAccount:my-app@project.iam.gserviceaccount.com" \
--role="roles/storage.objectViewer"
# Common storage IAM roles
# roles/storage.objectViewer → read objects (not list bucket)
# roles/storage.objectUser → read + write objects
# roles/storage.objectAdmin → full object control
# roles/storage.admin → bucket + object admin
# roles/storage.legacyBucketReader → list bucket (needed for gsutil ls)
Lifecycle Rules
{
"rule": [
{
"action": {"type": "SetStorageClass", "storageClass": "NEARLINE"},
"condition": {"age": 30, "matchesStorageClass": ["STANDARD"]}
},
{
"action": {"type": "SetStorageClass", "storageClass": "COLDLINE"},
"condition": {"age": 90}
},
{
"action": {"type": "Delete"},
"condition": {"age": 365}
}
]
}
gsutil lifecycle set lifecycle.json gs://my-bucket
Versioning
# Enable versioning (equivalent to S3 versioning)
gsutil versioning set on gs://my-bucket
# List all versions
gsutil ls -a gs://my-bucket/file.txt
# Restore a version
gsutil cp gs://my-bucket/file.txt#1234567890 gs://my-bucket/file.txt
Persistent Disk (Block Storage)
Persistent Disk is GCP's EBS — network-attached block storage for GCE VMs.
Disk Types
| Type | Max IOPS | Max throughput | Price/GB/mo | AWS analog |
|---|---|---|---|---|
pd-standard |
3,000 IOPS/TB | 0.12 MB/s/GB | $0.040 | gp2 (old) |
pd-balanced |
3,000 IOPS/TB | 0.28 MB/s/GB | $0.100 | gp3 |
pd-ssd |
30,000 IOPS | 0.48 MB/s/GB | $0.170 | io1/io2 |
pd-extreme |
120,000 IOPS | Custom | $0.220 | io2 Block Express |
hyperdisk-balanced |
160,000 IOPS | Configurable | $0.120 | io2 Express |
hyperdisk-throughput |
3,000 IOPS | 2,400 MB/s | $0.080 | Throughput-optimized |
# Create and attach a disk
gcloud compute disks create my-data-disk \
--zone=us-central1-a \
--size=200GB \
--type=pd-ssd
gcloud compute instances attach-disk my-vm \
--disk=my-data-disk \
--device-name=data \
--zone=us-central1-a
# Inside VM: format and mount
sudo mkfs.ext4 -m 0 -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/disk/by-id/google-data
sudo mkdir -p /mnt/data
sudo mount /dev/disk/by-id/google-data /mnt/data
# Resize a disk online (no reboot needed — unlike AWS)
gcloud compute disks resize my-data-disk \
--size=400GB \
--zone=us-central1-a
# Then grow filesystem online:
sudo resize2fs /dev/disk/by-id/google-data
Multi-Reader Disks
A PD disk can be attached to multiple VMs in read-only mode. Useful for shared datasets (ML model weights, reference data).
# Attach same disk to multiple VMs in read-only mode
gcloud compute instances attach-disk vm-1 --disk=my-shared-disk --mode=ro --zone=us-central1-a
gcloud compute instances attach-disk vm-2 --disk=my-shared-disk --mode=ro --zone=us-central1-a
gcloud compute instances attach-disk vm-3 --disk=my-shared-disk --mode=ro --zone=us-central1-a
AWS EBS multi-attach is only supported on io1/io2 and only for cluster-aware applications. GCP PD read-only multi-attach works for any disk type.
Disk Snapshots
# Manual snapshot (= EBS snapshot)
gcloud compute disks snapshot my-data-disk \
--snapshot-names=my-data-disk-snap-$(date +%Y%m%d) \
--zone=us-central1-a
# Restore from snapshot
gcloud compute disks create restored-disk \
--source-snapshot=my-data-disk-snap-20240115 \
--zone=us-central1-a
# Scheduled snapshots (= Data Lifecycle Manager in AWS)
gcloud compute resource-policies create snapshot-schedule daily-backup \
--region=us-central1 \
--max-retention-days=7 \
--on-source-disk-delete=keep-auto-snapshots \
--daily-schedule \
--start-time=04:00
gcloud compute disks add-resource-policies my-data-disk \
--resource-policies=daily-backup \
--zone=us-central1-a
Local SSD
Local NVMe drives physically attached to the server. Much faster than Persistent Disk, but ephemeral — data is lost on VM stop/restart. Like AWS instance store.
# Attach local SSD at instance creation (can't attach after)
gcloud compute instances create my-vm \
--machine-type=n2-standard-8 \
--local-ssd=interface=nvme # 375 GB per SSD
# Multiple local SSDs (can be striped for more throughput)
gcloud compute instances create my-vm \
--machine-type=n2-standard-16 \
--local-ssd=interface=nvme \
--local-ssd=interface=nvme # 750 GB total
Use cases: temp files, shuffle space for batch jobs, buffer layers on top of Persistent Disk.
Filestore (Managed NFS)
Filestore is GCP's EFS — managed NFS server for shared file access across multiple VMs or GKE pods.
graph LR
classDef gcp fill:#4285f4,stroke:#2a56c6,color:#fff
classDef orange fill:#e67e22,stroke:#d35400,color:#fff
VM1["GCE VM 1"]:::orange
VM2["GCE VM 2"]:::orange
GKE["GKE Pods"]:::gcp
FS["Filestore (NFS)<br/>10.0.0.100:/vol"]:::gcp
VM1 -->|mount NFS| FS
VM2 -->|mount NFS| FS
GKE -->|PVC / CSI| FS
Filestore Tiers
| Tier | Capacity | IOPS | Use case | AWS analog |
|---|---|---|---|---|
| Basic HDD | 1-63.9 TB | 600/TB | Dev/test | EFS IA |
| Basic SSD | 2.5-63.9 TB | 30,000 | Production web/content | EFS General |
| Enterprise | 1-10 TB | 120,000 | Databases, high-perf | EFS Max I/O |
| Zonal | 1-9.75 TB | 80,000 | Single-zone, lower cost | EFS Standard |
# Create Filestore instance
gcloud filestore instances create my-nfs \
--zone=us-central1-a \
--tier=BASIC_SSD \
--file-share=name=vol,capacity=2.5TB \
--network=name=my-vpc
# Mount on VM
sudo apt-get install nfs-common
sudo mkdir /mnt/shared
sudo mount 10.0.0.100:/vol /mnt/shared
# Mount in GKE (via CSI driver)
# StorageClass is pre-installed on GKE
# PVC for Filestore in GKE
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-nfs-pvc
spec:
accessModes:
- ReadWriteMany # multiple pods can mount simultaneously
storageClassName: standard-rwx # uses Filestore CSI driver
resources:
requests:
storage: 2560Gi
Storage Transfer Service
Move data into GCS from S3, Azure Blob, HTTP, on-prem. Equivalent to AWS DataSync or S3 Transfer Acceleration (for migration).
# Create a transfer job from S3 to GCS
gcloud transfer jobs create \
--source-agent-pool="" \
--source-creds-file=aws-creds.json \
--source=s3://my-aws-bucket/ \
--destination=gs://my-gcp-bucket/ \
--schedule-repeats-every=24h
GCS vs S3 — Key Differences
| GCP Cloud Storage | AWS S3 | |
|---|---|---|
| Consistency | Strong consistency (always) | Strong consistency (since 2020) |
| Storage classes | Standard/Nearline/Coldline/Archive | Standard/IA/Glacier/Deep Archive |
| Auto-tiering | Autoclass | Intelligent-Tiering |
| Multi-region | US/EU/ASIA built-in | Cross-Region Replication (separate config) |
| Access control | Uniform (IAM) or fine-grained (ACLs) | Bucket policies + ACLs |
| Signed URLs | gsutil signurl or client library |
aws s3 presign |
| Event notifications | Pub/Sub, Eventarc | S3 Events → SNS/SQS/Lambda |
| Versioning | Yes | Yes |
| Lifecycle rules | Yes | Yes |
| Replication | Turbo Replication (dual-region) | CRR/SRR |
| CLI | gsutil or gcloud storage |
aws s3 |
# New gcloud storage CLI (faster than gsutil for large transfers)
gcloud storage cp local-file.txt gs://my-bucket/
gcloud storage ls gs://my-bucket/
gcloud storage rm gs://my-bucket/file.txt