I'm writing this blog as a participant in Cloud Run Hackathon by Google Cloud
For the past several years, Iβve been self-funding my startup ideas by participating in hackathons that help me bring those ideas to life.

That's me in the picture with a monitor(left) I won in a recent hackathon.
Keeping tabs on the hackathons all the time to find which one would be the right fit for my startup ideas has become bit tedious.
The Problem
Finding relevant hackathons on Devpost is tedious:
- Keyword search misses semantically similar opportunities
- No personalized recommendations
- Manual filtering through hundreds of listings
- No notifications for new matching hackathons
The Solution
I built Hackathon.fund, an AI-powered platform that helps startup founders discover relevant hackathons on Devpost using semantic search. The entire application runs on Google Cloud Run - 11 deployments handling everything from web serving to daily AI-powered scraping jobs.
In this post, I'll share how I leveraged Cloud Run's serverless architecture to build a production-ready AI application that:
- π Scales automatically from 0 to thousands of users
- π° Costs ~$0.023 per user/month - For 10K users (50-60% cheaper than VM-based alternatives)
- π€ Processes hackathons daily with zero manual intervention
- β‘ Delivers personalized recommendations in under 2 seconds
- π οΈ Requires zero infrastructure management
Tech Stack: React, FastAPI, Cloud Run, Vertex AI, Gemini API, Firestore
Traditional solution: Build a VM-based backend with Elasticsearch, cron jobs, and email servers. Complex, expensive, and requires constant maintenance.
My solution: Serverless-first architecture using Cloud Run for everything.
Architecture Overview: 11 Cloud Run Deployments
Click here for the higher resolution image.
βββββββββββββββββββββββββββββββββββββββββββ
β Cloud Run Ecosystem (11 deployments) β
βββββββββββββββββββββββββββββββββββββββββββ€
β Services (3): β
β 1. Frontend (React + Nginx) β
β 2. Backend API (FastAPI + RAG) β
β 3. Firebase Email Extension β
β β
β Jobs (8): β
β 4. Scraper (Daily 5:00 AM) β
β 5. Uploader (Daily 5:30 AM) β
β 6. Preprocessor (Daily 5:30 AM) β
β 7. Change Detector (Daily 6:00 AM) β
β 8. Notification Matcher (Daily 6:30) β
β 9. Email Sender Daily (7:00 AM) β
β 10. Email Sender Weekly (Mon 7:00 AM) β
β 11. Email Sender Monthly (1st 7:00 AM)β
βββββββββββββββββββββββββββββββββββββββββββ
Let me break down how each component works and why Cloud Run was perfect for this use case.
Part 1: Frontend & Backend (Cloud Run Services)
Click here for the higher resolution image.
Frontend: Static Site Meets Serverless
Frontend was developed using Google AI Studio's build tool and was deployed to Cloud Run using the applet.
Challenge: Serve a React SPA with automatic scaling and custom domain.
Solution: Cloud Run service with multi-stage Docker build.
Why Cloud Run wins here:
- β Auto-scaling from 0-3 instances - No idle costs during low traffic
- β
Custom domain mapping -
hackathon.fundwith auto-provisioned SSL - β No server management - Just push and deploy
- β Built-in CDN - Google's edge network for static assets
Result: Hosting costs ~$10/month for 100M requests.
Backend: FastAPI + RAG with SSE
Challenge: Build an AI-powered API that uses SSE for responses, validates JWTs, and integrates with Vertex AI.
Solution: FastAPI backend deployed as Cloud Run service.
Note: Even though the backend is capable of streaming response, frontend result is not streamed as hackathon.fund is not a chat application.
Why Cloud Run wins here:
- β SSE streaming support - 300s timeout for long-lived connections
- β Auto-scaling 0-20 instances - Handles traffic spikes automatically
- β Service account integration - Secure access to Vertex AI, Firestore, Secret Manager
- β Built-in load balancing - No need for separate load balancer
Result: API costs ~$30/month for 500M requests with RAG.
Part 2: Data Ingestion Pipeline (Cloud Run Jobs)
Click here for the higher resolution image.
Job 1: Scraper - Headless Chrome on Cloud Run
Challenge: Scrape Devpost daily with infinite scroll, generate embeddings, and store in Cloud Storage.
Why Cloud Run Jobs?
- Runs once per day (5:00 AM UTC)
- Needs 2GB RAM for Chromium
- Completes in ~10 minutes
- Don't want to pay for always-on VM
Solution: Cloud Run Job triggered by Cloud Scheduler.
Why Cloud Run Jobs win here:
- β Pay only for execution time - ~10 minutes/day = $0.17/month (vs $30/month for always-on VM)
- β Automatic retries - Configured for 2 retries on failure
- β No infrastructure - Just deploy and schedule
- β Built-in logging - Cloud Logging captures all output
Job 2: Uploader - Vertex AI Vector Search Updates
Challenge: Update Vertex AI index with fresh embeddings daily.
Part 3: Notification Pipeline (5 More Cloud Run Jobs)
Click here for the higher resolution image.
The Challenge: Daily Email Notifications
Users can subscribe to get notified when new hackathons match their startup idea. This requires:
- Change Detection - Identify NEW hackathons
- Matching - RAG search for each user's cached embedding
- Email Generation - Create HTML digests
- Delivery - Send via SMTP
Traditional approach: Background workers, Redis queues, cron jobs on VMs.
My approach: Chain of Cloud Run Jobs orchestrated by Cloud Scheduler.
Job 3: Change Detector (6:00 AM)
# Compares today's hackathons with yesterday's snapshot
# Stores NEW hackathon IDs in Firestore
Job 4: Notification Matcher (6:30 AM)
Key optimization: Cached embeddings save $7.20/year for 10K users!
Job 5-7: Email Senders (7:00 AM)
Three separate jobs for daily/weekly/monthly frequencies.
Bonus: Firebase Extension (Cloud Run Function)
The Firebase Trigger Email extension deploys as a Cloud Run function that monitors the mail collection in Firestore:
Extension: firestore-send-email
Cloud Run Function: ext-firestore-send-email-processqueue
Provider: Mandrill SMTP
How it works:
- Email sender job writes to
mailcollection - Extension detects new document (Firestore trigger)
- Cloud Run function sends email via Mandrill
- Updates
delivery.statefield (SUCCESS/ERROR) - Automatic retry on failure
Why this is brilliant:
- β Zero code - Just install extension, configure SMTP
- β Automatic retries - Handles transient failures
- β Delivery tracking - All in Firestore
- β Scales automatically - Cloud Run function handles bursts
GCP Services Integration
How all the GCP servies come together.
Click here for the higher resolution image.
The Complete Daily Pipeline
Here's how all 11 Cloud Run deployments work together:
Click here for the higher resolution image.
5:00 AM - Scraper Job
β
Scrapes hackathons from Devpost
Generates embeddings with Gemini
Uploads to Cloud Storage
β
5:30 AM - Uploader Job
β
Downloads embeddings from GCS
Upserts to Vertex AI Index
5:30 AM - Preprocessor Job (parallel)
β
Converts JSONL to individual JSON files
β
6:00 AM - Change Detector Job
β
Compares current vs previous snapshot
Identifies NEW hackathons
Stores in Firestore
β
6:30 AM - Notification Matcher Job
β
Loads user subscriptions
RAG search with cached embeddings
Filters for NEW hackathons only
Stores matches in Firestore
β
7:00 AM - Email Sender Jobs (3 jobs)
β
Groups notifications by user
Generates HTML digest emails
Writes to Firestore mail collection
β
Firebase Extension (Cloud Run Function)
β
Sends emails via Mandrill SMTP
β
π§ Users receive: "π― 3 New Matching Hackathons Found!"
Total pipeline time: ~12 minutes
Total cost per day: ~$0.50
Why Cloud Run Was Perfect for This Project
1. Cost Efficiency
Monthly costs (10,000 active users):
Cloud Run Services (Frontend + Backend): $40
Cloud Run Jobs (7 jobs): $5
Cloud Run Function (Firebase Extension): $0 (included in extension)
Vertex AI Vector Search: $80
Firestore: $45
Gemini API: $50
Cloud Storage: $1
Cloud Logging: $5
ββββββββββββββββββββββββββββββββββββββββββββ
TOTAL: ~$0.023 per user/month - For 10K users
2. Developer Velocity
No YAML, no Kubernetes manifests, no Helm charts!
3. Zero Infrastructure Management
What I DON'T manage:
- β Kubernetes clusters
- β VM patching/updates
- β Load balancers
- β SSL certificates
- β Auto-scaling policies
- β Health checks
- β Service mesh
- β Cron servers
What Cloud Run manages:
- β Container orchestration
- β Traffic routing
- β SSL termination
- β Auto-scaling (0 to 1000)
- β Load balancing
- β Rolling deployments
- β Health monitoring
- β Logging & monitoring
4. Mixed Workload Support
Cloud Run handles both:
- Bursty user traffic (Frontend/Backend scale 0-3, 0-20)
- Scheduled batch jobs (Run once daily, pay only for execution time)
This is Cloud Run's superpower - one platform for everything.
5. Built-in Features
A. Traffic Splitting (Blue/Green):
gcloud run services update-traffic hackathon-fund-backend \
--to-revisions=backend-00006=10 \
--to-revisions=backend-00005=90
B. Secrets Integration:
gcloud run deploy ... \
--set-secrets=GEMINI_API_KEY=gemini-api-key:latest
C. Service Account Integration:
gcloud run deploy ... \
--service-account hackathon-backend@hackathon-fund.iam.gserviceaccount.com
D. Streaming Support:
- SSE with 300s timeout
- Perfect for AI streaming responses
Lessons Learned
1. Cloud Run Jobs vs Services
Use Cloud Run Services when:
- You need HTTP endpoints
- Traffic is unpredictable
- Response time matters
- Example: Frontend, Backend API
Use Cloud Run Jobs when:
- Task runs on schedule
- No HTTP needed
- Pay only for execution time
- Example: Scraper, Email sender
2. Secret Management Best Practices
Don't: Bake secrets into Docker images
Do: Use build args for frontend (Vite env vars):
docker build --build-arg VITE_BACKEND_URL="${BACKEND_URL}" ...
Do: Use Secret Manager for backend:
from google.cloud import secretmanager
client = secretmanager.SecretManagerServiceClient()
secret = client.access_secret_version(name="projects/.../secrets/gemini-api-key/versions/latest")
api_key = secret.payload.data.decode("UTF-8")
3. Cost Optimization
A. Embedding Caching
- Cache user idea embeddings in Firestore
- Saves $7.20/year for 10K users
- No API call needed for daily matching
B. Scale to Zero
- Frontend: 0-3 instances
- Backend: 0-20 instances
- Jobs: Only run when scheduled
- Savings: ~$200/month (70% reduction)
C. GCS Lifecycle Policies
- Auto-delete embeddings older than 30 days
- Saves: ~$5/month
4. Monitoring & Debugging
Cloud Logging queries:
# Backend errors
resource.type="cloud_run_revision"
AND resource.labels.service_name="hackathon-fund-backend"
AND severity="ERROR"
# Scraper execution
resource.type="cloud_run_job"
AND resource.labels.job_name="hackathon-scraper-job"
AND timestamp>"2025-11-08T05:00:00Z"
Pro tip: Use structured logging (JSON) for better filtering.
5. RAG Architecture with Vertex AI
Why Vertex AI Vector Search?
- Managed service (no vector DB to maintain)
- Sub-100ms search times
- Streaming updates
- Native GCP integration
Embedding strategy:
- Scraper:
task_type="RETRIEVAL_DOCUMENT" - Backend:
task_type="RETRIEVAL_QUERY" - Model:
gemini-embedding-001(768 dimensions) - Metric:
DOT_PRODUCT_DISTANCE
Results
After deploying to production:
Performance:
- β‘ Search results in ~2 seconds
- π 99.9% uptime (Cloud Run SLA)
- π Auto-scales to handle traffic spikes
Cost:
- π° ~$0.023 per user/month - For 10K users
- π 60% cheaper than VM-based alternatives
Developer Experience:
- β±οΈ Deploy in 2-3 minutes
- π οΈ Zero infrastructure maintenance
- π Simple deployment scripts
Live Demo
Conclusion
Cloud Run transformed what would have been a complex, expensive infrastructure project into a simple, cost-effective serverless application. By leveraging Cloud Run for both services and jobs, I built a production-ready AI platform with:
- 11 Cloud Run deployments handling web, API, scraping, and notifications
- Zero server management - just code and deploy
- ~$0.023 per user/month for 10K users (60% cheaper than VMs)
- Complete automation - daily scraping and matching with zero manual intervention
If you're building an AI application with mixed workloads (real-time APIs + scheduled jobs), Cloud Run should be your first choice. It's the perfect sweet spot between simplicity and power.
Key takeaway: Serverless doesn't mean "functions only" - Cloud Run proves that serverless can handle complex, stateful applications with ease.






Top comments (0)