Cloud Functions is designed for immutable deployments, meaning you don’t "roll back" in the traditional sense of reverting to a previous state of the same function. Instead, you deploy a new version of the function that points to an older revision of your code.

Let’s see this in action. Imagine you have a helloWorld function deployed.

// index.js
exports.helloWorld = (req, res) => {
  res.status(200).send('Hello World!');
};

You deploy it:

gcloud functions deploy helloWorld --runtime nodejs18 --trigger-http --allow-unauthenticated

This creates revision 1. Then you make a change, maybe to add some logging:

// index.js
exports.helloWorld = (req, res) => {
  console.log('New logging enabled!'); // Added log
  res.status(200).send('Hello World!');
};

And deploy again:

gcloud functions deploy helloWorld --runtime nodejs18 --trigger-http --allow-unauthenticated

This creates revision 2. Now, you realize the logging is causing unexpected latency or you just want to go back to the simpler version. You don’t "undo" revision 2. You tell Cloud Functions to use revision 1 for the helloWorld entry point.

The core problem Cloud Functions solves is enabling rapid, reliable iteration on small, event-driven services. The "deployment" process isn’t about modifying a running instance; it’s about associating a named function entry point with a specific, immutable revision of your code. Each deployment creates a new revision. When you want to "rollback," you’re simply changing which revision the function’s entry point (the name you call, like helloWorld) points to.

The levers you control are:

  • Function Name: The name you use to invoke the function (e.g., helloWorld).
  • Revision: An immutable snapshot of your code and configuration at a specific deployment time. Revisions are numbered sequentially (1, 2, 3…).
  • Traffic Allocation: You can direct 100% of traffic to a specific revision, or split traffic between multiple revisions for gradual rollouts or A/B testing.

To "rollback" to a previous version, you essentially re-deploy the function, explicitly telling it to use the code from an older revision.

Here’s how you do it using gcloud:

First, list the available revisions for your function:

gcloud functions revisions list --region=us-central1 --format="table(name,creationTimestamp,distGenNumber)" --filter="name~'helloWorld'"

This might output something like:

NAME                                       CREATION_TIMESTAMP                  DIST_GEN_NUMBER
projects/my-project/locations/us-central1/functions/helloWorld/revisions/1   2023-10-27T10:00:00Z   1
projects/my-project/locations/us-central1/functions/helloWorld/revisions/2   2023-10-27T10:05:00Z   2

Let’s say you want to go back to revision 1. You’ll use the gcloud functions deploy command again, but this time, you specify the --revision flag pointing to the desired older revision.

gcloud functions deploy helloWorld \
  --region=us-central1 \
  --runtime=nodejs18 \
  --trigger-http \
  --allow-unauthenticated \
  --revision=1

This command doesn’t modify revision 1. Instead, it creates a new deployment (which will be revision 3 in our example) that is configured to use the code and configuration from revision 1. The helloWorld function entry point will now direct all traffic to the code that was active during revision 1.

A common misconception is that you can directly "activate" an old revision without a new deployment. While the Cloud Console’s "Revisions" tab looks like it lets you pick and choose, clicking "Deploy new revision from" or similar actions ultimately triggers a deployment operation behind the scenes. The --revision flag in gcloud is the explicit way to achieve this. You’re not reverting code; you’re creating a new function configuration that references old code.

The next concept you’ll likely encounter is managing traffic splitting between multiple revisions to perform canary deployments or A/B tests.

Want structured learning?

Take the full Cloud-functions course →