Cloud Storage
Google Cloud Storage (GCS) is a unified object storage service for any amount of data. It serves static assets, backups, data lakes, and application data with global availability and strong consistency. GCS is the default object store for GCP — nearly every service integrates with it natively.
Storage Classes
| Class | Min Storage Duration | Use Case | Availability | Retrieval Cost |
|---|---|---|---|---|
| Standard | None | Frequently accessed data | Highest | None |
| Nearline | 30 days | Monthly access | High | Per-GB |
| Coldline | 90 days | Quarterly access | High | Higher per-GB |
| Archive | 365 days | Long-term archival | High | Highest per-GB |
All classes offer 11 nines (99.999999999%) durability through redundant storage across multiple devices and locations.
Location Types
| Location Type | Example | Use Case |
|---|---|---|
| Regional | us-central1 |
Low-latency, single-region apps |
| Dual-region | nam4 (Iowa + South Carolina) |
DR within continent |
| Multi-region | US, EU, ASIA |
Global content delivery |
Create a Bucket
gsutil mb -l us-central1 -c STANDARD gs://learning-gcp-dev-assets/
# Set uniform bucket-level access (recommended)
gsutil uniformbucketlevelaccess set on gs://learning-gcp-dev-assets/
# Enable versioning
gsutil versioning set on gs://learning-gcp-dev-assets/
# Set default encryption (Google-managed is default; CMEK optional)
gsutil encryption set -k \
projects/learning-gcp-dev/locations/us-central1/keyRings/my-ring/cryptoKeys/my-key \
gs://learning-gcp-dev-assets/
Bucket names are globally unique. Choose location based on latency, compliance, and cost requirements.
Upload and Download
# Upload a file
gsutil cp photo.jpg gs://learning-gcp-dev-assets/images/photo.jpg
# Parallel upload for large files
gsutil -m cp -r ./data/ gs://learning-gcp-dev-assets/data/
# List objects
gsutil ls -l gs://learning-gcp-dev-assets/images/
# Download
gsutil cp gs://learning-gcp-dev-assets/images/photo.jpg ./photo.jpg
Python SDK example:
from google.cloud import storage
client = storage.Client()
bucket = client.bucket("learning-gcp-dev-assets")
blob = bucket.blob("images/photo.jpg")
blob.upload_from_filename("photo.jpg")
# Generate signed URL (time-limited access)
url = blob.generate_signed_url(version="v4", expiration=3600, method="GET")
print(url)
Lifecycle Management
Automatically transition or delete objects:
{
"lifecycle": {
"rule": [
{
"action": { "type": "SetStorageClass", "storageClass": "NEARLINE" },
"condition": { "age": 30 }
},
{
"action": { "type": "SetStorageClass", "storageClass": "COLDLINE" },
"condition": { "age": 90 }
},
{
"action": { "type": "Delete" },
"condition": { "age": 365 }
}
]
}
}
Apply with: gsutil lifecycle set lifecycle.json gs://learning-gcp-dev-assets/
Security
| Practice | Implementation |
|---|---|
| Least privilege | IAM roles like roles/storage.objectViewer |
| No public access | Disable public ACLs; use signed URLs or CDN |
| Encryption | Google-managed keys (default) or CMEK |
| Audit | Cloud Audit Logs for data access events |
| Versioning | Enable object versioning for recovery |
| Retention | Bucket lock for compliance (WORM) |
# Grant read-only access to a service account
gsutil iam ch \
serviceAccount:[email protected]:objectViewer \
gs://learning-gcp-dev-assets/
# Block public access
gcloud storage buckets update gs://learning-gcp-dev-assets \
--public-access-prevention=enforced
Cross-Bucket Replication
Replicate objects to a DR bucket in another region:
# Create DR bucket
gsutil mb -l europe-west1 -c STANDARD gs://learning-gcp-dev-assets-dr/
# Configure replication (via Terraform or Console)
# Requires versioning enabled on source bucket
GCS vs. Other Object Stores
| Feature | GCS | AWS S3 | Azure Blob |
|---|---|---|---|
| Consistency | Strong (all operations) | Strong (since 2020) | Strong |
| Storage classes | 4 tiers | 6+ tiers | Hot/Cool/Archive |
| Transfer | Free egress to Cloud CDN | Paid egress | Paid egress |
| Event triggers | Pub/Sub notifications | SNS/SQS/Lambda | Event Grid |
| Max object size | 5 TB | 5 TB | 4.75 TB |
Common Patterns
| Pattern | Architecture |
|---|---|
| Static website | GCS bucket → Cloud CDN → custom domain |
| Data lake | GCS Standard → BigQuery external tables → Dataproc |
| Backup target | Lifecycle rules → Coldline/Archive after 90/365 days |
| User uploads | Signed URL upload → Cloud Function processing → resized image |
| Log archive | Cloud Logging sink → GCS → BigQuery for analysis |
Real-World Scenario: Media Platform
A video platform stores user uploads and serves transcoded content:
- Upload bucket (
uploads-raw) — Standard class, versioning on - Processing pipeline — GCS trigger → Cloud Function → transcode → output bucket
- Delivery bucket (
media-cdn) — Standard class behind Cloud CDN - Archive bucket — Lifecycle moves originals to Coldline after 90 days
- IAM — upload SA has
objectCreatoron raw; CDN SA hasobjectVieweron media
Common Mistakes
| Mistake | Impact | Fix |
|---|---|---|
| Public bucket ACLs | Data breach | Enforce public access prevention |
| Wrong storage class | 3–10x higher cost | Match class to access frequency |
| No lifecycle rules | Storage costs grow forever | Automate tiering and deletion |
| Fine-grained ACLs | Complex, error-prone | Use uniform bucket-level access |
| Ignoring egress costs | Surprise bills on downloads | Use Cloud CDN; keep processing in-region |
Best Practices
- Enable uniform bucket-level access on all buckets
- Use versioning on buckets with critical data
- Apply lifecycle rules from day one
- Generate signed URLs for temporary client access instead of making objects public
- Use labels on buckets for cost allocation
- Monitor with Cloud Monitoring metrics (
storage.googleapis.com/storage/total_bytes) - Use Storage Transfer Service for large migrations from S3 or on-premises
Troubleshooting
“Access denied” on upload:
gsutil iam get gs://learning-gcp-dev-assets/
# Verify caller has storage.objectCreator or storage.objectAdmin
Slow uploads:
gsutil -o GSUtil:parallel_composite_upload_threshold=150M \
-m cp large-file.tar gs://learning-gcp-dev-assets/
Object not found after upload:
Check bucket name spelling (globally unique) and object path. Use gsutil ls -r to verify.
Lifecycle rule not applying:
Lifecycle actions run once per day. Verify rule JSON and check gsutil lifecycle get.
GCS is the default object store for GCP — integrate it with Compute Engine, GKE, Cloud Functions, and analytics services.
Next: Cloud SQL — managed relational databases.