Google Cloud Storage offers several storage classes, and the first thing to understand is what they are not. They are not different services, different APIs or, with one zonal exception, different performance tiers. An object in Archive is read with the same gs:// path, the same client library and first-byte latency in the same range as an object in Standard. What changes is the price list: colder classes charge less to keep bytes and more to touch them, and they bill a minimum storage duration whether you keep the object that long or not.

So choosing a class is a cost-modelling exercise, and getting it wrong is expensive in both directions: hot data in Archive pays retrieval and operation fees on every read, while cold data in Standard pays several times too much every month. This article builds the model, walks through a worked example, compares lifecycle rules with Autoclass, and lists the traps that surprise teams on their first bill. Prices change and vary by location, so every price here is labelled illustrative; take real ones from the pricing page. For how the service itself works underneath, see Google Cloud Storage internals.

Advertisement

The classes at a glance

ClassAPI nameMinimum storage durationRetrieval feeSLA (Google's documentation)
StandardSTANDARDNoneNo99.95% in multi-region and dual-region, 99.9% in a region
NearlineNEARLINE30 daysYes99.9% in multi-region and dual-region, 99.0% in a region
ColdlineCOLDLINE90 daysYes99.9% in multi-region and dual-region, 99.0% in a region
ArchiveARCHIVE365 daysYes99.9% in multi-region and dual-region, 99.0% in a region
RapidRAPIDNoneNo99.9%, zonal buckets only

Rapid is the special case: it stores data in zonal buckets, in the same zone as your compute, for lower latency and higher throughput than the other classes. It is aimed at workloads such as AI training and analytics that read the same data at very high rates, and it gives up the regional redundancy that the other classes have. The rest of this article is about the four classes that share a location model and differ only in price.

Availability depends on the class and on the location type, and Google designs these four classes for the same eleven nines of annual durability. Location is a separate choice from class: region, dual-region or multi-region decides where copies live and what happens in a regional outage, as covered in the GCP multi-region guide. The two choices multiply: a multi-region Coldline bucket is a valid and common thing.

Standardno minimum, no retrieval feeNearline30-day minimumColdline90-day minimumArchive365-day minimumColder: storage per GB-month falls; retrieval and per-operation prices rise; minimum duration growsLifecycle rules (you decide)SetStorageClass by age, prefix, custom time; one-way colderAutoclass (Google decides)by last data read: 30 / 90 / 365 days; read returns to StandardSame API and latencygs:// paths do not changeSame durability designlocation sets availabilityRapid (zonal)separate case: zonal bucketsA storage class is a pricing contract on the same service. Choose it from access frequency and object lifetime.
Four classes on one service. Moving right, the storage price falls and the price of access and short lifetimes rises. Lifecycle rules move objects colder on rules you write; Autoclass moves them by observed reads.

The five cost components

A storage bill is the sum of five things, and the class changes four of them.

  1. Storage, per GB-month, prorated. It falls steeply from Standard to Archive.
  2. Retrieval, per GB read, charged on Nearline, Coldline and Archive. Every read of the object data counts, including reads by your own batch jobs and copies to another bucket.
  3. Operations, per thousand requests. Class A operations (writes, lists, metadata changes, class changes) and Class B operations (reads of objects and metadata) are both priced higher for colder classes.
  4. Minimum storage duration. Delete, overwrite or replace an object before its class minimum and you are billed as if it had been stored for the minimum. A Nearline object deleted after ten days is billed for thirty.
  5. Network. Egress and inter-region transfer depend on location and destination, not on class; they are the same for all four classes.

The key insight is that the three class-dependent charges beyond storage are all driven by access and lifetime. The access frequency and how long an object lives decide the right class, not how important the data is. A disaster-recovery backup that must be kept but will almost never be read is Archive material even though it is critical.

Advertisement

A break-even calculator and a worked example

Put the components into a function and compare classes for the workload you actually have. The prices in the table are illustrative, roughly the shape of published US prices at the time of writing, and are only there to show the method.

# Illustrative prices only (USD). Copy current numbers for YOUR location
# from https://cloud.google.com/storage/pricing before using this.
PRICES = {
    #            storage/GB-month  retrieval/GB  classA/1k  classB/1k  min_days
    "STANDARD": (0.020,            0.00,         0.005,     0.0004,    0),
    "NEARLINE": (0.010,            0.01,         0.010,     0.0010,    30),
    "COLDLINE": (0.004,            0.02,         0.020,     0.0100,    90),
    "ARCHIVE":  (0.0012,           0.05,         0.050,     0.0500,    365),
}

def monthly_cost(cls, gb, reads_per_month_gb, writes_k, reads_k, lifetime_days):
    store, retr, a, b, min_days = PRICES[cls]
    # Deleting before the minimum is billed as if stored for the minimum,
    # so short-lived data pays for min_days; amortise that over its real life.
    billed_days = max(lifetime_days, min_days)
    storage = gb * store * billed_days / lifetime_days
    return round(storage + reads_per_month_gb * retr + writes_k * a + reads_k * b)

for read_share in (0.05, 0.5):
    print(read_share, {cls: monthly_cost(cls, gb=50_000,
                                         reads_per_month_gb=50_000 * read_share,
                                         writes_k=100, reads_k=200, lifetime_days=400)
                       for cls in PRICES})
# 0.05 {'STANDARD': 1001, 'NEARLINE': 526, 'COLDLINE': 254, 'ARCHIVE': 200}
# 0.5  {'STANDARD': 1001, 'NEARLINE': 751, 'COLDLINE': 704, 'ARCHIVE': 1325}

The worked example is a 50 TB dataset kept for about 400 days, of which 5 percent (2.5 TB) is read each month, with 100,000 writes and 200,000 reads a month. With these illustrative prices and 5 percent monthly reads, storage dominates: Standard costs about 1,000 a month, Nearline about 526 (500 storage, 25 retrieval), Coldline about 254 and Archive about 200 (60 storage, 125 retrieval, 15 in operations). Archive wins. Raise the read share to 50 percent, 25 TB a month, and the order changes completely: Archive's retrieval alone becomes 1,250, making it the most expensive at about 1,325, while Coldline (about 704) and Nearline (about 751) now beat both Archive and Standard. Read the whole dataset or more each month and Standard catches up with Nearline and then wins.

The general rule of thumb that falls out is simple. A cold class pays off when the monthly storage saving is larger than the retrieval cost of the data you read in a month, and the object lives past the minimum duration. For read-heavy data, the cheapest class to store is not the cheapest class to own.

Early deletion, rewrites and lifecycle transitions

Minimum durations interact with how you change an object's class, and the two ways behave differently.

A lifecycle SetStorageClass action changes the class in place. Google's documentation states that the time the object spent in its original class counts toward the minimum duration of the new class. An object that sat in Nearline for 60 days and is then moved to Coldline has already served 60 of Coldline's 90 days. The transition itself is a Class A operation billed at the destination class's rate, which matters with millions of small objects.

A rewrite with a new class, for example a copy onto itself, replaces the object. The replaced object counts as deleted at that moment, so if it was still inside its own class minimum, the early-deletion charge applies. Rewriting a fresh Nearline object into Coldline therefore bills the remainder of Nearline's thirty days and starts a new object.

Two more interactions matter. Changing the bucket's default storage class affects only new objects; nothing already in the bucket moves. And with object versioning, overwriting an object does not free its bytes: the old version becomes noncurrent and is still billed at its class. Pair versioning with a rule that deletes noncurrent versions after a set number of days, as in the configuration below. If soft delete is enabled on the bucket, deleted objects are retained and billed for the retention window; Google says soft-deleted time counts toward minimum storage duration.

Lifecycle rules: explicit, predictable, one-way

Object Lifecycle Management applies rules you write. A rule has an action (SetStorageClass, Delete or AbortIncompleteMultipartUpload) and conditions, including age, createdBefore, matchesPrefix, matchesSuffix, matchesStorageClass, isLive, numNewerVersions, daysSinceNoncurrentTime, daysSinceCustomTime and size bounds. All conditions in a rule must match. The configuration below moves logs to Nearline at 30 days and Archive at 180, deletes them at two years, cleans up noncurrent versions and abandons unfinished multipart uploads.

{
  "lifecycle": {
    "rule": [
      { "action": { "type": "SetStorageClass", "storageClass": "NEARLINE" },
        "condition": { "age": 30, "matchesPrefix": ["logs/"],
                       "matchesStorageClass": ["STANDARD"] } },
      { "action": { "type": "SetStorageClass", "storageClass": "ARCHIVE" },
        "condition": { "age": 180, "matchesPrefix": ["logs/"],
                       "matchesStorageClass": ["NEARLINE"] } },
      { "action": { "type": "Delete" },
        "condition": { "age": 730, "matchesPrefix": ["logs/"] } },
      { "action": { "type": "Delete" },
        "condition": { "daysSinceNoncurrentTime": 30, "isLive": false } },
      { "action": { "type": "AbortIncompleteMultipartUpload" },
        "condition": { "age": 7 } }
    ]
  }
}
# Apply a lifecycle configuration
gcloud storage buckets update gs://acme-logs --lifecycle-file=lifecycle.json

# Or let Autoclass manage classes, letting cold objects go all the way to Archive
gcloud storage buckets update gs://acme-ml-data --enable-autoclass \
    --autoclass-terminal-storage-class=ARCHIVE

# Where is the data, by class? (Cloud Monitoring metric, grouped by storage_class)
#   storage.googleapis.com/storage/total_bytes

Know the limits. Lifecycle transitions only go colder: Standard to Nearline, Coldline or Archive, Nearline to Coldline or Archive, Coldline to Archive. Nothing brings an object back to Standard when it becomes popular again; that takes a rewrite. Rule changes can take up to 24 hours to take effect, and actions run asynchronously, so do not use lifecycle for anything time-critical. Age counts from object creation, which for data that is rewritten or re-uploaded may not reflect its real age; the Custom-Time metadata field and the daysSinceCustomTime condition let your application set the clock explicitly.

Autoclass: let the service watch reads

Autoclass is a bucket setting that replaces your rules with observed behaviour. Objects start in Standard. One that has not had its data read for 30 days moves to Nearline; if the terminal class is Archive rather than the default Nearline, it continues to Coldline at 90 days and Archive at 365. When an object's data is read, it moves back to Standard. Reading metadata alone does not count.

The pricing is different too. Autoclass buckets do not pay retrieval fees or early-deletion fees, except as part of a one-time enablement charge when you turn it on for an existing bucket, which moves everything to Standard first. In exchange there is a management fee per object, and moving an object from Coldline or Archive back up is billed as a Class A operation. Objects smaller than 128 KiB never leave Standard.

Autoclass fits data with unpredictable access: shared ML datasets, analytics landing zones, user uploads. Lifecycle rules fit data whose access you know: logs, backups, compliance archives. You cannot mix them on one bucket; Autoclass is incompatible with lifecycle rules that use SetStorageClass or matchesStorageClass, although Delete rules still work. If one bucket holds both kinds of data, split it.

Traps that show up on the bill

  • Small objects. Operation charges are per request and do not shrink with size. A billion 4 KB objects in Archive can cost more in writes and class transitions than in storage. Bundle small files into archives or Parquet files before moving them cold.
  • Accidental full scans. A data-lake query engine, a virus scanner, an rsync or a migration tool reading a cold bucket once pays retrieval on every byte. Check which jobs read the bucket before choosing Coldline or Archive; for tables queried from BigQuery external tables, every scan is a read.
  • Short-lived data in cold classes. Temp files, intermediate shuffle output and daily-rotated backups deleted after a week pay the full minimum. Keep them in Standard with a Delete rule.
  • Noncurrent versions. Versioning without a cleanup rule quietly multiplies storage.
  • Serving from cold classes. Public assets fronted by Cloud CDN are still read from the bucket on every cache miss; keep them in Standard.

Workload recipes

WorkloadAccess patternRecommended setup
Website assets, active datasetsRead constantlyStandard, region close to compute or multi-region for users
ML training data shared by teamsBursty, unpredictableAutoclass with terminal class Nearline; Rapid only for proven throughput needs
Application logsRead in the first weeks, rarely afterLifecycle: Nearline at 30 days, Archive later, Delete at retention end
Monthly backupsRestored rarely, kept a year or moreColdline or Archive by restore frequency; test a restore and its cost
Compliance archivesAlmost never read, must be keptArchive with a retention policy
Temporary and staging dataWritten, read, deleted within daysStandard with a Delete rule

Measure before and after: the Cloud Monitoring metric for total bytes can be grouped by storage class, and billing export shows retrieval and operation line items separately. A class change that lowers storage but raises retrieval by more is a regression, and you only see it by looking at both.

What to do next

  1. List your buckets with their current class, size and object count, and pull one month of retrieval and operation charges per bucket from billing export.
  2. For each large bucket, estimate monthly read volume and object lifetime, and run the calculator above with prices for your location.
  3. Split buckets that mix predictable and unpredictable data, then apply lifecycle rules to the first kind and Autoclass to the second.
  4. Add noncurrent-version and incomplete-multipart-upload cleanup rules to every versioned bucket.
  5. Bundle small objects before moving them cold, and keep short-lived data in Standard with a Delete rule.
  6. Check the bill a month later, comparing storage savings with retrieval and operation increases, and revert anything that got more expensive.
Key takeaway: Cloud Storage classes are one service with four price lists. Colder classes store bytes more cheaply but charge for retrieval, charge more per operation and bill a minimum duration, so the right class follows from access frequency and object lifetime, not from how important the data is. Model all five cost components, use lifecycle rules where access is predictable and Autoclass where it is not, and watch for small objects, accidental scans, short lifetimes and noncurrent versions.