Cloud Storage stores immutable object data inside globally named buckets. An object name can contain slashes, but those characters usually represent a console convention rather than real directories.
Location, storage class, retention, versioning, lifecycle, encryption, and IAM determine how a bucket behaves over time. Design those controls from the data lifecycle instead of treating them as cleanup settings.
A regional bucket can sit near a regional compute workload. Dual-region and multi-region choices change resilience, placement, replication behavior, and price. Data transfer charges and residency requirements may matter more than the storage rate.
Storage classes reflect expected access frequency and minimum-duration or retrieval economics. Autoclass can manage class transitions for suitable workloads; explicit lifecycle rules offer precise age, state, prefix, and version conditions.
Uniform bucket-level access disables object ACLs and keeps authorization in IAM, which is easier to review at scale. Public access prevention can block accidental public grants where policy requires it.
For temporary downloads, a trusted service can create a signed URL with a narrow method and expiration. The URL is a bearer capability until it expires, so avoid logging it or placing it in analytics data.
PROJECT_ID=tl-cloud-lab
BUCKET="gs://${PROJECT_ID}-lab-assets"
gcloud storage buckets create "$BUCKET" \
--project="$PROJECT_ID" \
--location=us-central1 \
--uniform-bucket-level-access
gcloud storage buckets update "$BUCKET" \
--lifecycle-file=lifecycle.json
gcloud storage buckets describe "$BUCKET"
Versioning can preserve replaced or deleted generations, while retention policies and holds prevent deletion for a defined period. These controls solve different problems and can increase storage usage.
Use checksums for transfer integrity and generation-match preconditions for concurrent updates. Recovery testing should restore a named generation and verify its content, metadata, permissions, and downstream usability.
A bucket defines location, namespace, policy, protection, and default storage behavior. An object is immutable bytes plus metadata identified by a name and generation. Replacing an object creates a new generation rather than modifying bytes in place. Folder-looking names are usually prefixes, though managed folders can provide a resource boundary for hierarchical organization and access.
Cloud Storage provides strong global consistency for object reads, writes, deletes, metadata operations, and listings after a successful response. Public caches can still serve an older object according to `Cache-Control`, and access-policy changes can take time to propagate. Distinguish storage consistency from application cache behavior before adding retry loops or arbitrary delays.
Use generation and metageneration preconditions for read-modify-write workflows. A write with `ifGenerationMatch=0` creates only when no live object exists; a generation match prevents overwriting a version that changed after it was read. Preconditions turn silent lost updates into explicit failures that the application can reconcile.
Choose a region, dual-region, or multi-region from compute locality, availability, residency, recovery, replication, and network-transfer requirements. Keeping a bucket near its primary compute and data processing usually reduces latency and transfer charges. A broader location does not fix a single-region database or application dependency, so document the complete request and recovery path.
Standard, Nearline, Coldline, and Archive classes trade storage price against retrieval and minimum-duration charges. Match class to measured access and retention instead of a label such as backup. Autoclass can manage class transitions for changing access patterns; lifecycle rules can change class or delete eligible objects. Model retrieval, early deletion, operation, soft-delete, replication, and transfer charges before choosing.
A lifecycle action is asynchronous and may interact with versioning, holds, retention policies, multipart uploads, and soft delete. Test rules on a non-production bucket with representative object ages and prefixes. Review changed requirements before deploying a rule that can delete historical data at scale.
Prefer uniform bucket-level access so IAM governs access consistently and object ACLs cannot create hidden exceptions. Grant a dedicated service account only the object actions it needs on the narrowest practical bucket or managed folder. Public access prevention blocks accidental public grants; signed URLs provide time-limited access to a specific operation but must still be protected like bearer credentials until expiration.
For browser uploads, a signed URL or signed policy can move bytes directly without routing them through the application server. Constrain method, object name or prefix, size, content type, expiration, and post-upload validation. Treat uploaded data as untrusted: scan where required, verify actual format, assign server-controlled metadata, and publish only after validation.
For downloads, set cache headers from the mutability contract. Versioned asset names can be cached for a long time, while a mutable name needs revalidation or short freshness. A CDN improves delivery but introduces another cache and purge boundary. Never assume deleting the origin object immediately removes every cached public copy.
Soft delete retains deleted or overwritten objects for a configured period and is enabled by default on new buckets with a seven-day duration unless policy changes it. Object Versioning retains noncurrent generations through a different mechanism. Retention policies and object holds prevent deletion for governance. Select controls by threat and recovery requirement rather than enabling every feature without understanding cost.
A malicious or mistaken bulk deletion can also target recovery settings. Separate permission to write objects from permission to change retention, lifecycle, IAM, soft-delete policy, or bucket deletion. Use Bucket Lock only after legal and operational review because locking a retention policy is irreversible. Monitor configuration changes and restore a sample object on a schedule.
Recovery drills should cover exact-generation restore, many-object restore, metadata preservation, downstream reprocessing, and a deleted bucket where supported. Measure the time to identify the incident, stop destructive automation, select a clean point, restore, verify consumers, and reconcile events generated during recovery. Include the cost of retained deleted data in the design.
Bulk copy, rewrite, restore, or delete operations are collections of individual object outcomes, not one atomic transaction. Build a manifest containing bucket, object name, expected generation, size, checksum, intended action, and result. Retry only failed items with generation preconditions so a concurrent writer is not overwritten by a stale batch.
For migration, compare object count, total bytes, checksums, metadata, retention state, and access behavior. Listing is strongly consistent, but a consumer or CDN can still use cached content. Freeze or version writers when the cutover contract requires a stable set, and record how events arriving during copy are reconciled.
For deletion, generate and review the candidate manifest before execution, use a separate privileged job identity, cap batch rate, and retain recovery evidence. A prefix typo can affect millions of objects quickly. Test cancellation and confirm that partially completed work can be resumed without repeating destructive actions.
When using parallel transfer tools, tune worker count from API quota, network capacity, object size distribution, and destination limits. Many tiny objects behave differently from a few large objects. Monitor retry causes and checksum failures, and avoid increasing concurrency when throttling shows the service or destination is already protecting itself.
A batch job overwrites a manifest with incomplete data.
Constraints: Object versioning is enabled and writers must avoid lost updates.
Decision: Read the current generation, restore the known-good generation with a generation-match precondition, and preserve audit evidence.
Verification: The restored checksum matches and a stale writer receives a precondition failure instead of overwriting it.
Failure test: Retry with an old generation number and confirm the write is rejected.
Expected evidence: The restored checksum matches and a stale writer receives a precondition failure instead of overwriting it.
In ordinary flat-namespace buckets they are name prefixes displayed as folders. Hierarchical namespace buckets add stronger folder semantics for supported workloads.
No. Noncurrent generations remain billable until deleted. Pair versioning with a reviewed lifecycle rule when older generations should expire.
Explore 500+ free tutorials across 20+ languages and frameworks.