## TL;DR

Lifecycle rules (set at bucket creation or after): - Transition objects to Nearline/Coldline/Archive after N days of non-access for backups and logs. - Delete objects after their retention need expires (build artifacts, temp exports). - Abort incomplete multipart uploads after a few days; abandoned uploads bill as storage. `` gcloud storage buckets update gs://[BUCKET] --lifecycle-file [RULES-JSON] ` Versioning: enable it for buckets where overwrites must be recoverable (terraform state, configs).

## Steps

1. Goal: stop paying for data nobody reads, without losing data somebody needs.

2. Lifecycle rules (set at bucket creation or after):
- Transition objects to Nearline/Coldline/Archive after N days of non-access for backups and logs.
- Delete objects after their retention need expires (build artifacts, temp exports).
- Abort incomplete multipart uploads after a few days; abandoned uploads bill as storage.

```
gcloud storage buckets update gs://[BUCKET] --lifecycle-file [RULES-JSON]
```

3. Versioning: enable it for buckets where overwrites must be recoverable (terraform state, configs). Know that every version bills as a full object; pair versioning with a lifecycle rule that deletes noncurrent versions after N days, or costs grow silently.

4. Public access prevention: enforce it on every bucket that should never be public. It makes public ACLs fail closed even if someone misconfigures IAM later.

```
gcloud storage buckets update gs://[BUCKET] --public-access-prevention
```

5. Traps:
- Lifecycle rules apply to current AND noncurrent versions; write rules for both or versions accumulate.
- Archive class has retrieval costs and minimum durations; transitioning tiny frequently-read objects to Archive loses money.
- Uniform bucket-level access plus public access prevention is the sane default for new buckets. Set both at creation.

6. Verify: after applying, check the bucket config, upload a test object, and confirm the lifecycle JSON matches intent. Revisit storage metrics monthly.

## When to use

You are seeing this: Goal: stop paying for data nobody reads, without losing data somebody needs. Use this skill when you run into "GCS cost hygiene: lifecycle rules, versioning, and public access prevention".

## When not to use

If your error message or symptom does not match what is described above, this is probably not your fix. Search for your exact error text instead of forcing this one to fit.

## Versions

No specific versions are mentioned in the source material, so treat the fix as generally applicable and check the examples against whatever you have installed.

## Why this happens

The original report does not dig into a root cause. It documents the symptom and the fix that resolved it.
