Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Specialized skill for building production-ready serverless applications on GCP. Covers Cloud Run services (containerized), Cloud Run Functions (event-driven), cold start optimization, and event-driven architecture with Pub/Sub.
.claude/skills/davila7-gcp-cloud-run/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 24% | 0% |
| case-20 | ✓→✗ | ▼ Worse | 72% | 0% |
| case-06 | ✓→✓ | = Same ✓ | 490% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 103% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 67% | 0% |
Containerized web service on Cloud Run
When to use: 'Web applications and APIs', 'Need any runtime or library', 'Complex services with multiple endpoints', 'Stateless containerized workloads']
javascript
FROM node:20-slim AS builder WORKDIR /app COPY package.json ./ RUN npm ci --only=production
FROM node:20-slim WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules COPY src ./src COPY package.json ./
ENV PORT=8080 EXPOSE 8080
USER node
CMD "node", "src/index.js"]
// src/index.js const express = require('express'); const app = express();
app.use(express.json());
// Health check endpoint app.get('/health', (req, res) => { res.status(200).send('OK'); });
// API routes app.get('/api/items/:id', async (req, res) => { try { const item = await getItem(req.params.id); res.json(item); } catch (error) { console.error('Error:', error); res.status(500).json({ error: 'Internal server error' }); } });
// Graceful shutdown process.on('SIGTERM', () => { console.log('SIGTERM received, shutting down gracefully'); server.close(() => { console.log('Server closed'); process.exit(0); }); });
const PORT = process.env.PORT || 8080; const server = app.listen(PORT, () => { console.log(Server listening on port ${PORT}); });
steps: # Build the container image
args: 'build', '-t', 'gcr.io/$PROJECT_ID/my-service:$COMMIT_SHA', '.']
# Push the container image
args: 'push', 'gcr.io/$PROJECT_ID/my-service:$COMMIT_SHA']
# Deploy to Cloud Run
entrypoint: gcloud args:
### Cloud Run Functions Pattern
Event-driven functions (formerly Cloud Functions)
**When to use**: ['Simple event handlers', 'Pub/Sub message processing', 'Cloud Storage triggers', 'HTTP webhooks']
javascript// HTTP Function // index.js const functions = require('@google-cloud/functions-framework'); functions.http('helloHttp', (req, res) => { const name = req.query.name || req.body.name || 'World'; res.send(`Hello, ${name}!`); });
javascript// Pub/Sub Function const functions = require('@google-cloud/functions-framework'); functions.cloudEvent('processPubSub', (cloudEvent) => { // Decode Pub/Sub message const message = cloudEvent.data.message; const data = message.data ? JSON.parse(Buffer.from(message.data, 'base64').toString()) : {}; console.log('Received message:', data); // Process message processMessage(data); });
javascript// Cloud Storage Function const functions = require('@google-cloud/functions-framework'); functions.cloudEvent('processStorageEvent', async (cloudEvent) => { const file = cloudEvent.data; console.log(`Event: ${cloudEvent.type}`); console.log(`Bucket: ${file.bucket}`); console.log(`File: ${file.name}`); if (cloudEvent.type === 'google.cloud.storage.object.v1.finalized') { await processUploadedFile(file.bucket, file.name); } });
bash# Deploy HTTP function gcloud functions deploy hello-http \ --gen2 \ --runtime nodejs20 \ --trigger-http \ --allow-unauthenticated \ --region us-central1 # Deploy Pub/Sub function gcloud functions deploy process-messages \ --gen2 \ --runtime nodejs20 \ --trigger-topic my-topic \ --region us-central1 # Deploy Cloud Storage function gcloud functions deploy process-uploads \ --gen2 \ --runtime nodejs20 \ --trigger-event-filters="type=google.cloud.storage.object.v1.finalized" \ --trigger-event-filters="bucket=my-bucket" \ --region us-central1
### Cold Start Optimization Pattern
Minimize cold start latency for Cloud Run
**When to use**: ['Latency-sensitive applications', 'User-facing APIs', 'High-traffic services']
bashgcloud run deploy my-service \ --cpu-boost \ --region us-central1
bashgcloud run deploy my-service \ --min-instances 1 \ --region us-central1
dockerfile# Use distroless for minimal image FROM node:20-slim AS builder WORKDIR /app COPY package*.json ./ RUN npm ci --only=production FROM gcr.io/distroless/nodejs20-debian12 WORKDIR /app COPY --from=builder /app/node_modules ./node_modules COPY src ./src CMD ["src/index.js"]
javascript// Lazy load heavy libraries let bigQueryClient = null; function getBigQueryClient() { if (!bigQueryClient) { const { BigQuery } = require('@google-cloud/bigquery'); bigQueryClient = new BigQuery(); } return bigQueryClient; } // Only initialize when needed app.get('/api/analytics', async (req, res) => { const client = getBigQueryClient(); const results = await client.query({...}); res.json(results); });
bash# Higher memory = more CPU during startup gcloud run deploy my-service \ --memory 1Gi \ --cpu 2 \ --region us-central1
## Anti-Patterns
### ❌ CPU-Intensive Work Without Concurrency=1
**Why bad**: CPU is shared across concurrent requests. CPU-bound work
will starve other requests, causing timeouts.
### ❌ Writing Large Files to /tmp
**Why bad**: /tmp is an in-memory filesystem. Large files consume
your memory allocation and can cause OOM errors.
### ❌ Long-Running Background Tasks
**Why bad**: Cloud Run throttles CPU to near-zero when not handling
requests. Background tasks will be extremely slow or stall.
## ⚠️ Sharp Edges
| Issue | Severity | Solution |
|-------|----------|----------|
| Issue | high | ## Calculate memory including /tmp usage |
| Issue | high | ## Set appropriate concurrency |
| Issue | high | ## Enable CPU always allocated |
| Issue | medium | ## Configure connection pool with keep-alive |
| Issue | high | ## Enable startup CPU boost |
| Issue | medium | ## Explicitly set execution environment |
| Issue | medium | ## Set consistent timeouts || Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-05 | fail→fail | 13,185 | 11,668 | -12% | 1 | 1 | 0% | 2,356 | 4,107 | +74% | 0 | 0 | — |
case-06 | pass→pass | 3,935 | 4,579 | +16% | 1 | 1 | 0% | 402 | 2,372 | +490% | 0 | 0 | — |
case-03 | pass→pass | 11,623 | 5,742 | -51% | 1 | 1 | 0% | 1,417 | 2,880 | +103% | 0 | 0 | — |
case-01 | fail→pass | 18,439 | 14,403 | -22% | 1 | 1 | 0% | 3,874 | 4,820 | +24% | 0 | 0 | — |
case-02 | pass→pass | 27,485 | 26,916 | -2% | 1 | 1 | 0% | 2,167 | 3,624 | +67% | 0 | 0 | — |
case-04 | pass→pass | 16,111 | 12,066 | -25% | 1 | 1 | 0% | 2,921 | 3,934 | +35% | 0 | 0 | — |
case-07 | pass→pass | 11,211 | 7,591 | -32% | 1 | 1 | 0% | 2,200 | 3,491 | +59% | 0 | 0 | — |
case-08 | pass→pass | 6,779 | 3,925 | -42% | 1 | 1 | 0% | 1,234 | 2,667 | +116% | 0 | 0 | — |
case-09 | pass→pass | 6,542 | 2,949 | -55% | 1 | 1 | 0% | 1,088 | 2,446 | +125% | 0 | 0 | — |
case-10 | pass→pass | 3,654 | 2,359 | -35% | 1 | 1 | 0% | 647 | 2,348 | +263% | 0 | 0 | — |
case-16 | pass→pass | 8,271 | 7,217 | -13% | 1 | 1 | 0% | 1,254 | 3,130 | +150% | 0 | 0 | — |
case-11 | pass→pass | 7,458 | 6,567 | -12% | 1 | 1 | 0% | 1,496 | 3,196 | +114% | 0 | 0 | — |
case-12 | pass→pass | 4,036 | 3,089 | -23% | 1 | 1 | 0% | 508 | 2,383 | +369% | 0 | 0 | — |
case-13 | pass→pass | 8,838 | 3,487 | -61% | 1 | 1 | 0% | 1,378 | 2,565 | +86% | 0 | 0 | — |
case-14 | pass→pass | 15,105 | 10,333 | -32% | 1 | 1 | 0% | 2,621 | 3,758 | +43% | 0 | 0 | — |
case-15 | pass→pass | 13,004 | 11,292 | -13% | 1 | 1 | 0% | 1,910 | 3,832 | +101% | 0 | 0 | — |
case-17 | pass→pass | 11,672 | 11,376 | -3% | 1 | 1 | 0% | 1,810 | 3,744 | +107% | 0 | 0 | — |
case-18 | pass→pass | 9,916 | 8,688 | -12% | 1 | 1 | 0% | 1,531 | 3,412 | +123% | 0 | 0 | — |
case-19 | pass→pass | 9,447 | 6,684 | -29% | 1 | 1 | 0% | 1,560 | 3,077 | +97% | 0 | 0 | — |
case-20 | pass→fail | 10,373 | 6,337 | -39% | 1 | 1 | 0% | 1,744 | 2,997 | +72% | 0 | 0 | — |
case-21 | pass→pass | 11,010 | 7,425 | -33% | 1 | 1 | 0% | 2,047 | 3,457 | +69% | 0 | 0 | — |
case-22 | pass→pass | 6,992 | 7,346 | +5% | 1 | 1 | 0% | 1,334 | 3,396 | +155% | 0 | 0 | — |
case-23 | pass→pass | 10,445 | 8,657 | -17% | 1 | 1 | 0% | 1,827 | 3,522 | +93% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of 0 percentage points is the difference between those two pass rates over the 23 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.