Configuring GCP Cloud Storage for object storage

The number of objects keeps growing, and storage stops keeping up: delivery slows down, and costs grow unpredictably. We set up GCP Cloud Storage turnkey: we select storage classes and access rules, and provide ready-made schemes and documentation. Object delivery time is reduced, and the archive stops growing uncontrollably.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

What breaks in GCP Cloud Storage as load grows

The first thing to stop responding in GCP Cloud Storage is object listing. Storage is flat: folders exist only as key prefixes, and listing by a broad prefix is read in full each time.

On tens of thousands of objects, listing takes seconds; on millions of keys, the console times out, and sync scripts built on listing run for minutes and hit request limits.

A separate headache is access denials that appear seemingly on their own.

Most often the cause is mixing permission models: uniform bucket-level access is enabled on the bucket, while part of the code continues to grant permissions on individual objects, and they are silently ignored.

The second source is signed URLs: a short lifetime plus clock skew on the client side, and uploads fail exactly at peak activity. The third is retention policies and object locks: they prohibit deletion, so cleanup jobs accumulate errors instead of freeing up space.

Volume meanwhile grows unnoticed and not where it is expected. Enabled versioning keeps all previous object versions; incomplete multipart uploads sit around as orphaned parts; and data from a month ago remains in the Standard class. Inventory starts taking hours, and exporting the key list no longer fits in the script's memory.

None of these failures is cured by adding requests or capacity. We discuss how this is addressed: with lifecycle rules, distribution across storage classes, and a unified bucket permission model.

What a properly configured storage provides: speed, reliability, control

In Google Cloud Storage, the storage class is the first thing that determines an object's behavior. We keep hot data served directly to users in the class with minimal response latency, and archives with infrequent access in a cold class designed for long-term storage.

The difference in response between classes is measured in orders of magnitude, so layout is determined by access profile, not by guesswork.

Then this layout is described by lifecycle rules: after a given number of days, an object moves to a colder class, old versions are deleted, and incomplete multipart uploads are cleaned automatically.

The rule “keep the latest versions per tag” stops uncontrolled registry growth but leaves the ability to roll back to a previous build.

Fault tolerance is provided by redundancy: objects are distributed across zones, and for critical datasets we enable cross-region replication and versioning.

Deletion protection with a defined retention period prevents data from being erased by an accidental script or a compromised key, and restoring the needed version takes minutes.

Volume stops being a surprise: metrics on the number of objects and occupied space show growth in advance, before you hit the quota, and review of access permissions and policies runs on a schedule.

In sum, this provides sub-second response delivery, removes the class of “data lost” failures from the agenda, and makes storage growth predictable.

Access modes and storage classes: comparison of options

An object in GCP Cloud Storage has two independent decisions: who has the right to read it and how quickly it must be served. The first is set by the access mode — a uniform policy for the whole bucket or object-level ACLs; the second by the storage class.

An error in either is not immediately visible: a link gets into a search engine index, or the archive grows, and the cost of maintaining it grows faster than the archive itself.

For external recipients, public access is rarely justified: a signed URL with a limited lifetime gives the file to a specific person and does not end up in search results.

For internal services, bucket-level permissions are enough — object-level ACLs complicate auditing and almost always leave excess permissions.

Option When it fits Limitations
Uniform bucket policy Primary mode, permissions only via IAM Cannot grant access to a single object bypassing the bucket
Object-level ACLs Legacy structure, point exceptions Hard to audit, conflicts with bucket policy
Public access Website static assets, intentionally public media Object is indexed and remains open after the task changes
Signed URLs Delivering a file to a partner or external recipient Live for a limited time, cannot be revoked early
Nearline class Backups, access once a month Early deletion within the minimum storage duration costs more than storage
Coldline class Archives, access once a quarter Minimum storage duration, serving takes longer than hot
Archive storage Long retention for compliance Longest minimum duration, recovery takes hours

The class is assigned at upload or later — by a lifecycle rule: an object lives as hot for a month, then moves to cold and archive without manual transfers.

The only thing to decide in advance is the minimum retention period; otherwise, early cleanup will cost more than the archive itself.

Configuration procedure: from audit to handover to operations

Configuring object storage in GCP Cloud Storage starts not with the console but with an inventory: how much data is stored now, who reads it and how, what retention periods are required.

Without these numbers, any layout rule is a guess that has to be redone along with the migration six months later.

  1. Storage audit. We collect a list of buckets and volumes, export access logs, mark hot and cold prefixes, and record current permissions and external integrations.
  2. Storage schema design. We distribute data across buckets and prefixes, select classes based on read frequency, and define lifecycle rules — transition to archive and deletion by object age.
  3. Access policy. Unified roles and least privilege, a separate service account for each service, public access closed, operation logging enabled.
  4. Data migration. We migrate in waves with incremental changes so business process downtime remains zero, and we make sure the migration does not saturate the channel for other tasks.
  5. Integrity check. We compare checksums before and after the transfer, investigate discrepancies, and separately verify object metadata and retention periods.
  6. Load testing. We run peak reads and bulk uploads, observe latency and behavior when quotas are exhausted, and refine request rate limits.
  7. Handover to operations. We give the team the schema, policy, instructions for standard operations, and monitoring with alerts for volume growth and access denials.

Documentation, schemas, and storage access rules

Object storage built on Google Cloud Storage outlives any individual release: the team changes, while access rules and container structure remain.

Therefore, at the end of the work we hand over not a history of commands but a document package by which the configuration can be reproduced, verified, and calmly transferred to support.

  • Storage schema — a map of containers and prefixes: what is written where, object naming rules, environment separation, storage classes, and automatic cleanup of outdated versions.
  • Access policies — which roles are assigned to containers, what is closed to public reading, how temporary URLs for export are issued and for how long.
  • Roles and permissions — a “role → allowed actions” matrix based on least privilege: read, write, delete, and rule management are separated.
  • Access grant and revocation procedure — how a request is filed, who approves it, for how long the permission is granted, and what happens when an employee's role changes.
  • Team instructions — standard operations with step-by-step descriptions: uploading artifacts, issuing a link, key rotation, troubleshooting common access denials.
  • Backup policy — what is copied, at what frequency, how long it is stored, how recovery is tested, and what target times are fixed.
  • Integration schemas and monitoring — a diagram of data flows between storage and services plus a list of metrics and notifications: volume growth, spike in access errors, rule failure.

Documents are updated with every configuration change, so the description does not diverge from the actual state of storage.

Case study: how object delivery time and archive volume changed

What it was like before

Storage was used as a common warehouse: one bucket for all environments, objects sat in the hot class without lifecycle rules, and the share of data not accessed for more than a quarter reached 70%.

Each release added new artifacts, old ones remained — volume grew, and with it the scan time during retrieval.

Access was granted manually: a request in a ticket, permissions copied from the previous employee, so some incidents were caused not by a failure but by excess or expired permissions.

What was changed

Environments were separated into individual projects and buckets so permissions did not overlap.

We configured lifecycle rules in Google Cloud Storage: after 30 days an object moves to Nearline, after 90 — to Coldline, after a year — to Archive, with an exception for the last ten versions of each artifact.

We enabled versioning and deletion protection, moved public delivery to short-lived signed URLs, and placed frequently requested objects behind a caching layer.

We described permissions through groups and bucket-level roles, and linked access requests to automatic approval and an expiration period.

What became

Delivery sped up: the 95th percentile response time dropped from about 1.4 seconds to 0.4 — due to the cache and offloading the hot class. The share of inactive data in the hot class fell from 70% to 12%; the rest is stored in cold classes and is retrieved only on request.

Restoring an object or previous version takes minutes instead of a day of searching through backups. Access-related support requests decreased severalfold: from six to eight per month to a few per quarter.

Six months after implementation, the metrics hold without manual intervention: lifecycle rules run on schedule, volume growth has slowed, and new buckets are created from a ready template with already defined policies.

How Cloud Storage differs from file storage

Object storage is a flat key space where each object as a whole is the unit of read and write: it has a name, content, metadata, and access settings. There is no directory hierarchy inside — the “folders” visible in the interface are key prefixes drawn as a tree for convenience.

A directory cannot be renamed with a single action: changing a prefix means rewriting every object under the new key.

File storage is the opposite: a directory tree, locks, partial reads and writes. You can change a byte in the middle of a file, append to the end, open one file from multiple processes, and not rewrite it entirely.

That is why production databases, a shared directory for build nodes, and services that need consistent writes remain on the file model — object storage here causes extra rewrites and state discrepancies.

The object model wins where data grows quickly and rarely changes: media, backups, logs, exports, archives, analytical datasets.

An immutable object is easier to version and replicate, and lifecycle rules themselves move old versions to a cold class and delete what is unnecessary.

Link-based access — a signed URL with a limited lifetime — serves the file directly from storage, without issuing credentials and without traffic through the application.

Choosing a storage model comes down to two questions: whether part of a file needs to be changed in place and whether several nodes need a shared mount point. If the second is not required, we almost always choose object storage.

In practice, the models coexist: hot media and archives live in object storage, while service directories and service states live in file storage. We determine this by access profile and measurements, not by team habit.

Technical concerns when choosing object storage

Questions during assessment are rarely about storage capabilities — more often about migration risks. Four of them come up constantly.

How do you migrate data without stopping the service?

We write new objects to two locations at once while the background copies the accumulated data, and we switch reads only after checksum verification. If there is a discrepancy for any object, the switch is postponed, and the previous location remains operational.

What happens to access when the team composition changes?

We grant permissions with roles on the project and individual bucket, not with personal keys. Service accounts live separately from people, and keys are issued with a limited lifetime.

An engineer's departure is handled by revoking their role — service keys do not need to be reissued.

Will the storage withstand peak load?

We distribute different data types across storage classes, rate-limit heavy requests, and place a cache at the perimeter. We set up observability in advance: metrics show latency growth before the user notices it.

How is data integrity confirmed?

We enable object versioning and deletion protection, and lifecycle rules maintain the required history depth. Checksum verification runs on a schedule, and instead of broken links, external consumers receive signed URLs with a limited lifetime.

Let's discuss the task and come back with an estimate and plan

To come back with an estimate and plan rather than general wording, we need inputs about the storage. Below is the minimum set that allows us to examine the task specifically and break down the scope of work into stages with control points.

  • List of buckets and their purpose: website static assets, backups, media, analytics exports, exchange with contractors.
  • Access profile: who reads and writes, whether there are external counterparties, whether public access is needed or only private via service accounts.
  • Data volume, growth rate, and retention period: what should be deleted, what should be archived, and how many days after last access.
  • Lifecycle rules: how many object versions to keep, whether protection against accidental deletion is needed, and how quickly an object must be restored.
  • Traffic pattern: where requests come from — cloud services, office, another region — and whether there are requirements for encryption and a private channel.
  • Current state: what is already configured, what roles are granted, where operations are performed manually, and what failures have already occurred.
  • Organizational constraints: desired timelines, change windows, and who on the customer side approves access.

Send what you have — even a partial set of inputs already allows us to put together a plan. Describe the task in free form, add inputs about the storage, and we will come back with an estimate, scope of work, and sequence of stages, including the rollback procedure.