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.