Skip to content
Learni
View all tutorials
Google Cloud Platform

How to Deploy Cloud Functions Gen2 on GCP in 2026

Lire en français

Introduction

2nd Generation Cloud Functions (Gen2) on Google Cloud Platform (GCP) represent the cutting edge of serverless computing in 2026, powered by a Cloud Run runtime for infinite scalability, 40% faster cold starts, and seamless integration with GCP services like Firestore, Pub/Sub, and Secret Manager. Unlike Gen1, Gen2 offers native VPC support, up to 1000 concurrent requests per instance, and timeouts up to 60 minutes—perfect for critical microservices or complex ETL jobs.

This expert tutorial walks you step-by-step through deploying production-ready TypeScript functions: from a basic HTTP API to secure event-driven triggers. You'll learn to optimize costs with pay-per-request billing, implement granular IAM, and sidestep common pitfalls like excessive cold starts. By the end, you'll have zero-downtime, repeatable deployments ready for any cloud architect. Ready to scale without managing infrastructure?

Prerequisites

  • GCP account with billing enabled and increased Cloud Functions quotas (via console).
  • gcloud CLI v450+ installed (gcloud version).
  • Node.js 20.10+ and npm 10+.
  • TypeScript 5.4+ with advanced knowledge of async/await, GCP IAM, and VPC.
  • Existing or new GCP project (gcloud projects create my-project).

Initialize the local project

terminal
mkdir cloud-functions-gen2 && cd cloud-functions-gen2
npm init -y
npm install typescript @types/node firebase-admin @google-cloud/pubsub @google-cloud/firestore
npm install -D ts-node @types/firebase-admin
npx tsc --init --target es2022 --module commonjs --outDir dist --rootDir src --strict true --esModuleInterop true
mkdir src

This script sets up a structured Node.js/TypeScript project with essential GCP libraries (Firestore, PubSub). The strict tsconfig.json enables advanced type checks to prevent runtime errors. Note the 'dist' outDir for Cloud Run-compatible builds.

Project structure ready

Your workspace is now set up: src/ for source code, dist/ for builds. Dependencies include Firebase Admin SDK for Firestore (official GCP SDK) and PubSub. Next, we'll code an HTTP function that queries Firestore, simulating a scalable users API.

HTTP function with Firestore

src/httpFunction.ts
import { onRequest } from 'firebase-functions/v2/https';
import { initializeApp } from 'firebase-admin/app';
import { getFirestore, Firestore } from 'firebase-admin/firestore';

initializeApp();
const db: Firestore = getFirestore();

export const getUsers = onRequest(
  { memory: '256MiB', maxInstances: 10 },
  async (req, res) => {
    res.set('Access-Control-Allow-Origin', '*');
    if (req.method === 'OPTIONS') {
      res.status(204).send('');
      return;
    }
    try {
      const snapshot = await db.collection('users').limit(10).get();
      const users = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
      res.json({ users, count: users.length });
    } catch (error) {
      console.error('Erreur Firestore:', error);
      res.status(500).json({ error: 'Interne serveur' });
    }
  }
);

This Gen2 function uses firebase-functions/v2/https for an async HTTP handler. It initializes Firestore once, queries 10 users with native pagination, and handles CORS/OPTIONS. The memory and maxInstances flags optimize cold starts and concurrency (up to 100 req/s).

Complete package.json

package.json
{
  "name": "cloud-functions-gen2",
  "version": "1.0.0",
  "main": "dist/index.js",
  "scripts": {
    "build": "tsc",
    "serve": "ts-node src"
  },
  "dependencies": {
    "firebase-admin": "^12.5.0",
    "firebase-functions": "^5.1.1",
    "@google-cloud/pubsub": "^4.0.2",
    "@google-cloud/firestore": "^8.3.1"
  },
  "devDependencies": {
    "@types/node": "^22.7.4",
    "typescript": "^5.6.3",
    "ts-node": "^10.9.2"
  },
  "engines": {
    "node": "20"
  }
}

This package.json pins 2026-compatible versions, sets engines to enforce Node 20 on GCP, and includes build/deploy scripts. Firebase-functions v5+ is required for Gen2; avoid breaking upgrades without testing.

Deploy the HTTP function

terminal
gcloud config set project my-project
npm run build
gcloud functions deploy getUsers \
  --gen2 \
  --runtime=nodejs20 \
  --region=europe-west1 \
  --source=. \
  --entry-point=getUsers \
  --trigger-http \
  --allow-unauthenticated \
  --memory=256MB \
  --max-instances=10 \
  --timeout=30s

This Gen2 deployment activates the underlying Cloud Run with --gen2. --allow-unauthenticated is for testing; use IAM in production. The europe-west1 region minimizes EU latency. Output URL: https://...-ew1.a.run.app/getUsers.

Test and observe scaling

Test with curl $(gcloud functions describe getUsers --format='value(serviceConfig.uri)'). Monitor logs via gcloud functions logs read getUsers --limit=50. Gen2 auto-scales to 0 idle instances, with cold starts under 200ms at 256MB memory.

Pub/Sub trigger function

src/pubsubFunction.ts
import { onMessagePublished } from 'firebase-functions/v2/pubsub';
import { initializeApp } from 'firebase-admin/app';
import { getFirestore } from 'firebase-admin/firestore';

initializeApp();
const db = getFirestore();

export const processUserEvent = onMessagePublished(
  { topic: 'user-events' },
  async (event) => {
    const message = event.data.message.data
      ? Buffer.from(event.data.message.data, 'base64').toString()
      : '';
    try {
      const userData = JSON.parse(message);
      await db.collection('processed-users').add({
        ...userData,
        processedAt: new Date(),
        eventId: event.data.message.messageId
      });
      console.log('User processed:', userData.id);
    } catch (error) {
      console.error('PubSub error:', error);
      throw error;
    }
  }
);

Gen2 Pub/Sub trigger for ETL: parses base64 message, stores in Firestore with idempotency via messageId. No HTTP response; errors trigger auto-retries (exponential backoff). Create topic first: gcloud pubsub topics create user-events.

Deploy Pub/Sub and create topic

terminal
gcloud pubsub topics create user-events
gcloud functions deploy processUserEvent \
  --gen2 \
  --runtime=nodejs20 \
  --region=europe-west1 \
  --source=. \
  --entry-point=processUserEvent \
  --trigger-topic=user-events \
  --memory=512MB \
  --max-instances=20 \
  --timeout=60s \
  --ingress=internal-only

Event-driven deployment with --trigger-topic and --ingress=internal-only for security (GCP-internal only). Higher memory for heavy ETL; 60s timeout leverages Gen2 maximum.

Integrate Secret Manager and VPC

terminal
gcloud secrets create db-password --data-file=/path/to/secret.txt
gcloud functions deploy getUsersSecure \
  --gen2 \
  --runtime=nodejs20 \
  --region=europe-west1 \
  --source=. \
  --entry-point=getUsersSecure \
  --trigger-http \
  --allow-unauthenticated=false \
  --set-secrets=db-password=projects/my-project/secrets/db-password:latest \
  --vpc-connector=my-vpc-connector \
  --egress-settings=all-traffic

Secures with Secret Manager (--set-secrets) and VPC Connector for private DB access. Create connector first: gcloud vpc-connectors create my-vpc-connector --region=europe-west1 --subnet=my-subnet. IAM auto-mounts secrets as env vars.

Best practices

  • Optimize cold starts: Set --min-instances=1 for steady workloads, use --cpu=2 for bursts.
  • IAM security: gcloud functions add-iam-policy-binding getUsers --member='allUsers' --role='roles/cloudfunctions.invoker' for granular access.
  • Structured logging: Use functions.logger.log(data, { severity: 'INFO' }) for Cloud Logging queries.
  • Costs: Set --concurrency=80 per instance for maximum throughput.
  • CI/CD: Integrate Cloud Build with cloudbuild.yaml for zero-downtime (--update-on-redeploy).

Common errors to avoid

  • Forgetting --gen2: Deploys to obsolete Gen1 (no VPC, limited scaling).
  • No gcloud auth: Run gcloud auth application-default login before deploy.
  • Mis-mounted secrets: Access via process.env.DB_PASSWORD in code; rotate with gcloud secrets versions.
  • Firestore timeouts: Use db.batch() for >500 write ops.

Next steps

Dive deeper with Learni's GCP Serverless training. Official docs: Cloud Functions Gen2. Explore Eventarc for 100+ triggers or Artifact Registry for custom images.