What Is a Cloud Storage Bucket in GCP? Naming, Location, and Configuration
A Cloud Storage bucket is the top-level container for objects in Google Cloud Storage. Before you can store a single file, you need a bucket. The choices you make at creation time — name, location, and access model — are permanent or very difficult to change later. This page explains what buckets are, how they work, and what you need to know before creating one.
What is a Cloud Storage bucket?
A Cloud Storage bucket is the primary container in Google Cloud Storage. It holds objects: the files, images, archives, logs, and binary data you upload. You cannot store objects without first creating a bucket to put them in.
Every bucket has three permanent properties you set at creation:
- Name. Must be globally unique across every GCP project worldwide.
- Location. The geographic region or multi-region where the data is physically stored.
- Default storage class. The cost and availability tier objects inherit unless you override it at upload time.
Everything else — access controls, versioning, lifecycle rules, labels — can be adjusted after creation. But name and location are fixed. Get those right before you create anything.
Think of Cloud Storage like a global network of warehouses. A bucket is a named locker inside one of those warehouses. When you reserve a locker, you choose which warehouse it lives in (location) and give it a unique name that no one else in the world can use. You cannot move the locker to a different warehouse later. Everything you store goes inside that locker (objects), and you control who has a key (IAM).
How Cloud Storage buckets work
Buckets sit between your application and the objects it stores. The bucket holds configuration that applies to everything inside it. Objects hold the actual data.
Here is the typical flow from creation to use:
- Create the bucket. Choose a name, location, and default storage class.
- Configure access. Enable uniform bucket-level access and apply IAM bindings.
- Set defaults. Configure versioning, lifecycle rules, and labels if needed.
- Upload objects. Files land in the bucket and inherit the default storage class.
- Access objects. Via HTTPS URL, the gcloud CLI, client libraries, or signed URLs.
- Manage over time. Lifecycle rules automatically move or delete objects as they age.
The bucket URL format is gs://bucket-name. An individual object
is addressed as gs://bucket-name/path/to/file.jpg. Object names
can contain slashes, which the console renders as folders, but there is no
real directory structure. The full object name including slashes is just a
flat string key.
For details on uploading and managing objects after your bucket exists, see Uploading Files with gsutil.
Why bucket decisions matter
If you get either wrong, your only fix is to create a new bucket, copy every object, update all application references, and delete the old bucket. At scale, that is a significant migration. Plan before you create.
Here is what is actually at stake:
Latency. A bucket in
us-central1served to users in Europe adds round-trip overhead on every request. Choose a location close to your compute and your users.Cost. Multi-region and dual-region buckets cost more per GB than regional buckets, and egress between regions is billed separately. See Regional vs Multi-Regional Cloud Storage for a cost breakdown.
Security. Access control decisions at the bucket level affect all objects inside it. Uniform bucket-level access prevents objects from being accidentally exposed via legacy ACLs. See Cloud Storage Security for more on securing buckets in production.
Governance. Data residency rules in some industries require data to remain within a specific geography. A bucket in the
EUmulti-region does not guarantee data stays in a specific EU country. A regional bucket ineurope-west2does.Migration effort. Renaming, moving, or splitting a bucket later is a significant operational task. Plan your bucket structure before you upload production data.
Bucket naming rules
Bucket names have strict requirements because they form part of the public
URL for your data. A bucket named my-app-assets is reachable
at storage.googleapis.com/my-app-assets. You cannot rename a
bucket after it is created, so get this right from the start.
The rules
- Must be globally unique across every GCP project in the world
- Must be between 3 and 63 characters long (up to 222 characters if the name contains dots)
- Can only contain lowercase letters, numbers, and hyphens
- Must start and end with a letter or number, not a hyphen
- Cannot resemble an IP address (for example,
192.168.0.1is rejected) - Cannot begin with
googor containgoogle
Naming best practices
The recommended pattern is {project-id}-{purpose}. Including
the project ID avoids naming conflicts and makes ownership obvious in
billing exports and audit logs:
my-app-prod-assets— project context and purpose are clearmy-app-prod-backups— environment and function are explicitmy-app-staging-uploads— staging data is separated from prodmy-bucket— almost certainly already taken; no ownership contexttest— too short, too generic, creation will failcustomer-pii-data-prod— reveals architecture in a globally visible namespace
Bucket names are visible in URLs, network logs, and billing exports, and
they are globally public. A name like customer-data-prod-encrypted
tells anyone who intercepts a request that you have a production bucket
containing customer data. Use project ID and purpose only.
Location types
You choose a location when creating a bucket. This controls where Google physically stores the data and cannot be changed after creation. Choosing the wrong location means either a migration or permanent latency and cost overhead.
| Type | Redundancy | Latency | Cost | Best for |
|---|---|---|---|---|
| Region | Multi-zone within one region | Lowest (same region) | Lowest | Compute in one region; cost-sensitive workloads |
| Dual-region | Two specific regions | Low (within region pair) | Higher | Disaster recovery with defined RPO; geo-redundancy without global overhead |
| Multi-region | Multiple data centres across a large area | Low (within the area) | Highest | Global audiences; high-availability static content |
Start with a regional bucket in the same region as your compute. It is the lowest-cost option and the right default for most workloads. Move to dual-region only when you have a specific disaster recovery requirement, and multi-region only when you are genuinely serving a global audience.
Region
Data is stored redundantly across multiple zones within a single region
(for example, europe-west2 for London). Regional buckets have
the lowest latency for workloads running in the same region and the lowest
per-GB storage cost. Use regional buckets when all your compute is in one
region and cross-region redundancy is not required.
Dual-region
Data is stored across two specific regions (for example, EUR4
covers europe-north1 and europe-west4). Dual-region
provides automatic geo-redundancy. Turbo Replication can be enabled to
guarantee replication to the second region within 15 minutes, which is useful
for disaster recovery with a defined RPO. For a full cost analysis of when the
premium is justified, see
Regional vs Multi-Regional Cloud Storage.
Multi-region
Data is stored across multiple data centres within a large geographic area.
Available options are US, EU, and ASIA.
Multi-region buckets are optimised for high availability and throughput when
serving global audiences. They cost more than regional buckets and do not
give you control over exactly which regions store your data within the
multi-region boundary. If data residency within a specific country is a
legal requirement, use a regional bucket instead.
Key bucket configuration options
Uniform bucket-level access
When enabled, all access to the bucket and its objects is controlled exclusively by IAM. Legacy object ACLs are disabled. This is the recommended setting for every new bucket. It makes permissions auditable from a single place and prevents objects from being accessible via an ACL that is invisible in the IAM policy view.
Once uniform bucket-level access has been enabled for 90 days, it becomes permanent and cannot be disabled. Treat this as a feature: it removes a whole category of unintended access. For a detailed explanation of the difference between bucket-level IAM and legacy ACLs, see Cloud Storage IAM vs ACLs.
Without uniform bucket-level access, IAM and legacy ACLs run in parallel. An object can be accessible even if the IAM policy looks correct, because a separate ACL is granting access. Enable it at creation and you will never need to worry about that category of mistake.
Default storage class
Objects uploaded to a bucket inherit the bucket’s default storage class unless you specify one explicitly at upload time. Set the default based on how frequently objects in this bucket will be accessed. For a breakdown of Standard, Nearline, Coldline, and Archive, see Storage Classes in GCP.
Versioning
When enabled, overwriting or deleting an object creates a historical version rather than permanently removing the previous content. Versioning protects against accidental overwrites and application bugs that corrupt data.
Every overwrite and deletion creates a new stored version billed at the full storage rate. Without lifecycle rules to expire noncurrent versions, costs grow silently as your bucket accumulates history. Always configure version expiry at the same time you enable versioning. See Versioning in Cloud Storage for how to set it up correctly.
Lifecycle policies
Rules that automatically delete objects or transition them to a cheaper storage class after a set number of days. Lifecycle policies are essential for controlling costs in buckets that accumulate data over time. Logs, exports, and backups especially need these rules. Without them, data accumulates indefinitely and costs grow without bound. See Object Lifecycle Management for how to configure them.
Public access prevention
Prevents objects in the bucket from being made publicly accessible, even if
an IAM policy tries to grant allUsers access. Enable this on
any bucket that should never be public: internal logs, backups, or private
user data especially.
Retention policies
A retention policy sets a minimum time that objects must be kept before they can be deleted. Once set and locked, not even a project owner can delete objects before the retention period expires. This is useful for audit logs or regulatory compliance requirements. Locking a retention policy is irreversible.
Labels
Buckets support key-value labels for cost attribution. Labels appear in
billing exports, so team=backend or env=prod lets
you break down storage costs by team and environment across a project.
When to use Cloud Storage buckets
Cloud Storage is a good fit for any workload where you store and retrieve whole files rather than querying fields within them:
User-uploaded files. Profile images, documents, and media files uploaded by your application’s users. Store the file in Cloud Storage and keep the reference URL in your database. Use signed URLs to give users time-limited access without changing IAM.
Static website assets. CSS, JavaScript, images, and pre-built HTML served to browsers. Pair with Cloud CDN for global performance.
Application backups. Database exports, Terraform state files, and configuration snapshots. Use a regional bucket close to your primary compute and apply lifecycle rules to expire old backups.
Logs and analytics exports. Cloud Logging export sinks, BigQuery export files, and raw event data for downstream processing pipelines.
Data exchange between services. One service writes a file; another reads it. Cloud Storage acts as a durable, decoupled staging area with no tight coupling between producer and consumer.
Machine learning datasets and model artefacts. Training data, model weights, and inference outputs are commonly stored as objects and referenced by Vertex AI and other ML services.
Large binary files. Videos, audio, archives, and any file too large or unstructured for a database.
When not to use a bucket
Cloud Storage stores and retrieves whole objects. It is not the right tool when you need to query, filter, or randomly access data within files:
Structured data you need to query. If you need to filter rows, join tables, or search by field value, use Cloud SQL or Firestore. You cannot run
SELECT * WHERE user_id = 123against objects in a bucket.Disk-like access patterns. If your application needs a POSIX filesystem — shared mounts, file locking, or random byte-range writes — use Filestore instead. Cloud Storage does not support true directory semantics or file locking. See Cloud Storage vs Filestore.
Large-scale SQL analytics. If you need to run SQL queries over petabytes of structured data, BigQuery is the right tool. Cloud Storage can act as a source for BigQuery external tables, but the querying happens in BigQuery, not in the bucket.
Low-latency key-value lookups. Cloud Storage has per-operation latency in the tens to hundreds of milliseconds range. For sub-millisecond key lookups, use Bigtable or Memorystore.
Not sure which service fits your workload? See Choosing the Right GCP Storage Service for a decision flow across Cloud Storage, Cloud SQL, Firestore, Bigtable, and Spanner.
Bucket vs object: the key distinction
These two terms are often confused. Here is the distinction:
| Bucket | Object | |
|---|---|---|
| What it is | The container | A file stored inside the container |
| Name scope | Globally unique across all of GCP | Unique within its bucket |
| Location | Set at creation, permanent | Inherits from the bucket |
| Storage class | Sets the default for new objects | Can override the bucket default at upload time |
| Access control | IAM applied at bucket level | Inherits bucket IAM (with uniform access enabled) |
| Example path | gs://my-app-prod-assets | gs://my-app-prod-assets/images/logo.png |
A single bucket can hold millions of objects. Object names can contain slashes, which makes them appear as folders in the console. In reality, there is no folder hierarchy. The object name including the slashes is a flat string key. The “folders” are a console convenience, not real resources.
How to create and configure a bucket
The fastest way to create a bucket is with the gcloud storage
command. Always specify location and access settings explicitly rather than
relying on defaults.
# Create a regional bucket with uniform bucket-level access enabled
gcloud storage buckets create gs://my-app-prod-assets \
--location=europe-west2 \
--uniform-bucket-level-access \
--default-storage-class=STANDARD
# Create a multi-region bucket for global static content
gcloud storage buckets create gs://my-app-global-content \
--location=EU \
--uniform-bucket-level-access \
--default-storage-class=STANDARD
# Add labels to an existing bucket
gcloud storage buckets update gs://my-app-prod-assets \
--update-labels=team=backend,env=prod
# Enable versioning on a bucket
gcloud storage buckets update gs://my-app-prod-assets \
--versioning
# View bucket metadata and configuration
gcloud storage buckets describe gs://my-app-prod-assets
# List all buckets in the current project
gcloud storage buckets listWithout this flag, Cloud Storage enables legacy ACLs alongside IAM, creating a dual-control model that is difficult to audit. It takes one flag at creation to avoid a category of security problem that is genuinely hard to untangle later.
After the bucket is created, see Uploading Files with gsutil for how to copy objects into it.
How access control works
With uniform bucket-level access enabled, all access is controlled through IAM bindings on the bucket. There are no per-object ACLs to manage. A principal gets access to all objects in the bucket based on their role.
Think of it like a building keycard system. You grant access at the door (the bucket), not object by object. Someone with a reader keycard can enter and look around. Someone with a writer keycard can bring things in. Someone with an admin keycard can also remove things and change the locks. You do not hand out individual keys for each item inside the room.
The most common roles for service accounts accessing Cloud Storage are:
roles/storage.objectViewer— read objects and their metadata; cannot list the bucket contents or modify anythingroles/storage.objectCreator— upload new objects; cannot read, list, or delete existing objectsroles/storage.objectAdmin— full control over objects: read, create, overwrite, and deleteroles/storage.admin— full control over the bucket itself and all objects, including IAM policy changes; typically reserved for infrastructure automation only
Use the most restrictive role that satisfies the use case. An API server
that reads images needs objectViewer. A service that generates
reports and writes them needs objectCreator. Grant
objectAdmin only when a service also needs to overwrite or
delete existing objects.
# Grant a service account read access to a specific bucket
gcloud storage buckets add-iam-policy-binding gs://my-app-prod-assets \
--member="serviceAccount:api-server@my-app-prod.iam.gserviceaccount.com" \
--role="roles/storage.objectViewer"
# Grant a service account write access to upload objects
gcloud storage buckets add-iam-policy-binding gs://my-app-prod-assets \
--member="serviceAccount:upload-worker@my-app-prod.iam.gserviceaccount.com" \
--role="roles/storage.objectCreator"For a detailed comparison of IAM and legacy ACLs, including how to migrate buckets created before uniform access was standard, see Cloud Storage IAM vs ACLs. For granting time-limited access to objects without changing IAM, see Signed URLs Explained.
Cloud Storage vs other storage options
Cloud Storage is the right tool for unstructured files and binary data. For other workloads, a different GCP service is usually a better fit:
Cloud Storage vs Filestore. Filestore provides a managed NFS file system that VMs can mount directly. Use Filestore when your application needs a POSIX filesystem — shared mounts, file locking, or random byte-range access. Cloud Storage does not support any of these. See Cloud Storage vs Filestore.
Cloud Storage vs Cloud SQL. Cloud SQL stores structured relational data you query with SQL. Use it for user records, orders, and anything with a schema. Use Cloud Storage for the files those records reference — profile images, invoice PDFs, export files.
Cloud Storage vs Firestore. Firestore is a document database with real-time sync and rich query support. Use it for structured document data. Use Cloud Storage for binary files and large blobs that Firestore cannot store efficiently.
Common beginner mistakes
Using generic bucket names that fail or conflict. Names like
my-bucket,app-storage, ortest-dataare almost certainly already taken. Creation will fail. Prefix with your project ID:{project-id}-{purpose}. This also makes ownership clear in billing exports and audit logs.Creating buckets in the wrong region. If you create a bucket in
us-central1and your compute runs ineurope-west2, every read and write crosses a continent. You cannot change the bucket location after creation. Think about access patterns before you create anything.Skipping uniform bucket-level access. Without it, legacy ACLs run alongside IAM. Objects can be accessible despite correct-looking IAM policies because an ACL grants access independently. Enable uniform bucket-level access on every bucket from day one. It becomes permanent after 90 days, which is intentional.
Enabling versioning without lifecycle rules. Versioning is valuable, but every overwrite and deletion creates a new stored version billed at full price. Without lifecycle rules to expire old versions, storage costs grow silently over time. Always configure noncurrent version expiry when you enable versioning.
Assuming you can rename or move a bucket later. You cannot. If you named a bucket poorly or put it in the wrong region, you must create a new bucket, copy all data, and update all references. Plan names and locations before you write a single byte of production data.
Forgetting to empty a bucket before deleting it. Scripts that clean up unused buckets will error unless you delete all objects first, including noncurrent versions if versioning is enabled. Build the cleanup in the correct order: objects and versions first, then the bucket itself.
Summary
- A bucket is the top-level container for objects in Cloud Storage; every object must live inside one
- Bucket name and location are permanent; choose carefully before creation because migration is the only way to change them
- Names must be globally unique across all of GCP; use
{project-id}-{purpose}as your naming pattern - Choose location type based on your redundancy, latency, and cost requirements: Region, Dual-region, or Multi-region
- Enable uniform bucket-level access on every new bucket; it becomes permanent after 90 days
- Key configuration: default storage class, versioning (always pair with lifecycle rules), lifecycle policies, public access prevention, and labels for billing attribution
- Common IAM roles:
objectViewer(read),objectCreator(write),objectAdmin(full object control) - Buckets cannot be renamed or moved; plan names and locations before writing production data
Frequently asked questions
What is a Cloud Storage bucket in GCP?
A Cloud Storage bucket is the top-level container for objects in Google Cloud Storage. You cannot store files directly in Cloud Storage without a bucket — every object must live inside one. When you create a bucket, you choose a name (globally unique), a location (region, dual-region, or multi-region), and a default storage class. These choices are permanent or difficult to reverse, so they matter more than they appear to at first.
Why must Cloud Storage bucket names be globally unique?
Bucket names form part of the public DNS namespace. A bucket named my-app is accessible at storage.googleapis.com/my-app. Because names are used as hostnames in URLs, they must be unique across every GCP project in the world. If you try to create a bucket with a name already taken by any other customer, creation will fail. This is different from most GCP resources, which only need to be unique within a project or region.
Can you rename or move a Cloud Storage bucket?
No. Bucket names and locations are permanent. You cannot rename a bucket or change its region after it is created. To move data, create a new bucket in the target location and copy objects using gcloud storage cp or Storage Transfer Service. Keep both buckets during the migration, then update your application references once the copy is verified and complete.
What is the difference between a bucket and an object in Cloud Storage?
A bucket is the container. An object is a file stored inside that container. The bucket has a name, a location, and configuration settings that apply to everything inside it. An object has a name (its key), binary content, content type, and metadata. You access an object using its full path: gs://bucket-name/path/to/file.ext. A single bucket can hold millions of objects.
What happens when you delete a non-empty bucket?
By default, you cannot delete a non-empty bucket. The gcloud CLI refuses the operation unless you use the --recursive flag, which deletes all objects first then removes the bucket. If versioning is enabled, you must also delete all noncurrent (historical) versions before the bucket can be removed.