intermediate
Cloud Storage
Store objects in buckets with lifecycle rules, signed URLs, IAM controls, retention policy, and static asset delivery.
Cloud Storage holds durable objects in buckets: user uploads, static assets, backups, and build artifacts. For a JavaScript app, signed URLs or resumable uploads keep heavy blobs out of your API memory while IAM and uniform bucket-level access enforce least privilege.
import { Storage } from '@google-cloud/storage';
const storage = new Storage();
const bucket = storage.bucket('app-uploads-prod');
const [url] = await bucket.file(objectKey).getSignedUrl({
version: 'v4',
action: 'write',
expires: Date.now() + 15 * 60 * 1000,
contentType: 'image/jpeg',
});
| Storage class | When to use | |---------------|-------------| | Standard | Hot assets and frequent reads | | Nearline/Coldline/Archive | Backups with lifecycle rules | | Versioning | Recovery from accidental overwrite |
Pair buckets with lifecycle policies, CORS for browser uploads, and CDN or Cloud CDN in front of public static files.
On interviews: signed URL flow versus proxy upload; public bucket risks; storage classes and egress cost; object immutability and eventual listing consistency.
Common pitfalls: world-readable buckets for private user files; generating signed URLs from a browser-exposed service account key; no lifecycle on log or backup buckets.
The trade-off is cheap durable storage versus latency, consistency semantics, and careful access modeling.
Checklist:
- Never expose service account keys to the frontend.
- Use signed URLs or authenticated uploads for user content.
- Apply lifecycle rules to non-hot data.
- Separate buckets per environment and sensitivity.