Google Cloud Storage is GCP's object storage service. How buckets, locations and storage classes work, how access control and signed URLs fit in, and how a backend gets a GCS bucket from code.
Google Cloud Storage (GCS) is the object storage service on Google Cloud. It holds files of any size as objects inside buckets, and it is where GCP backends put user uploads, exports, media and backups, much as AWS backends use S3.
Creating a bucket takes a minute in the console, and the decisions that matter for a backend are the location, the storage class, how access is granted to services and browsers, and how buckets are kept consistent across development, staging and production. This guide covers those decisions and shows how Encore (infrastructure from code) provisions GCS buckets from application code.
A bucket has a location chosen at creation: a single region such as europe-west1, a dual-region pair, or a multi-region such as EU. Dual- and multi-region buckets replicate data across regions for availability, and the GCS overview describes how location affects latency and pricing. GCS provides strong global consistency for object reads after writes and for list operations, as documented in the consistency guide, so a file is readable as soon as its upload succeeds.
Storage classes trade storage price for retrieval price. Standard suits data the application reads regularly. Nearline, Coldline and Archive have minimum storage durations of 30, 90 and 365 days and charge per gigabyte read, and they suit backups and archives. All four have the same access latency, so a colder class never makes a read slow, only more expensive. Lifecycle rules move objects between classes or delete them based on age, and object versioning keeps older generations when objects are overwritten or deleted.
Google recommends uniform bucket-level access, which disables per-object ACLs and makes IAM on the bucket the only access mechanism. A backend running on Cloud Run or GKE reads and writes through its service account, which needs a role such as Storage Object User on the bucket.
Browsers should not get service account credentials, so uploads and private downloads go through signed URLs: the backend signs a URL for one object with an expiry, and the browser uploads or downloads directly against GCS, which keeps large files off the API servers. Public assets can be served from a public bucket, usually behind Cloud CDN.
A typical GCS setup for a backend has a bucket per environment with a unique name, IAM bindings for each service account, CORS configuration for browser uploads, lifecycle rules, an environment variable carrying the bucket name into the application, and credentials for local development, either a shared dev bucket or an emulator. In Terraform that is several resources per bucket, and every new bucket repeats them.
Encore is infrastructure from code for TypeScript and Go, with a platform that provisions and deploys into your own AWS or GCP account. On GCP, each bucket declared in code becomes a Cloud Storage bucket with a unique name in the environment's dedicated project, the service that uses it gets its own service account, and public buckets are served through Cloud CDN, as documented in the GCP infrastructure docs.

Run in your terminal to get started locally.
A service that lets the browser upload directly to a private bucket and then hands out download links:
// uploads/encore.service.ts
import { Service } from "encore.dev/service";
export default new Service("uploads");
// uploads/uploads.ts
import { api } from "encore.dev/api";
import { Bucket } from "encore.dev/storage/objects";
// A Cloud Storage bucket on GCP, a local bucket under encore run.
export const files = new Bucket("user-files", { versioned: false });
export const uploadUrl = api(
{ expose: true, method: "POST", path: "/files/:name/upload-url" },
async ({ name }: { name: string }): Promise<{ url: string }> => {
const { url } = await files.signedUploadUrl(`uploads/${name}`, { ttl: 600 });
return { url };
},
);
export const downloadUrl = api(
{ expose: true, method: "GET", path: "/files/:name/download-url" },
async ({ name }: { name: string }): Promise<{ url: string }> => {
const { url } = await files.signedDownloadUrl(`uploads/${name}`, { ttl: 600 });
return { url };
},
);
encore run serves both endpoints against a local bucket, so the upload flow works on a laptop without a GCP project. On deploy, Encore creates the bucket and the service reaches it through its service account, so no service account key file sits in the repo or in CI. The bucket API, including public buckets and listing, is in the TypeScript object storage docs and the Go object storage docs, and an existing bucket can be attached with import a GCS bucket.
An AI coding agent can add a second bucket or a new upload endpoint in the same file and test it with encore run, and the bucket and its access arrive with the deploy.
Best fit: TypeScript and Go teams on GCP who want Cloud Storage buckets for each environment created from the code that uses them.
PUT from your frontend's origin.Google Cloud Storage stores files as objects in buckets. Backends use it for user uploads, generated reports, media, backups, data lake files and static assets, and serve them through signed URLs, public URLs or Cloud CDN.
GCS has four storage classes: Standard for frequently accessed data, Nearline with a 30-day minimum storage duration, Coldline with 90 days and Archive with 365 days. Colder classes cost less to store and more to read, and all of them have the same millisecond access latency.
They solve the same problem with similar models of buckets and objects. GCS uses Google Cloud IAM and its own JSON API, offers dual-region and multi-region bucket locations, and provides an XML API that is largely compatible with S3 tools.
With Encore, declare the bucket with new Bucket() from encore.dev/storage/objects and return a URL from bucket.signedUploadUrl() in an API endpoint, which the browser uses to PUT the file directly. encore run uses a local bucket, and on GCP Encore creates the Cloud Storage bucket and gives the service its own service account.
Deploy to your cloud on AWS and Google Cloud
without managing infrastructure
Encore lets developers and agents define application infrastructure directly in code, then automatically provisions it from local development to production in your AWS or GCP account.