November 10, 2023
Cloud Functions 1st Gen vs 2nd Gen: What Actually Changes
article.mdx
Why this matters
If you are maintaining Firebase or GCP serverless workloads, understanding the gap between 1st gen and 2nd gen functions helps you avoid scaling surprises and pick the right trigger model.
1st gen in one sentence
Cloud Functions 1st gen is the older runtime model: simple to start, but with tighter limits, fewer trigger options, and less control over scaling behavior.
Typical triggers you still see in 1st gen code:
onWriteonUpdateonDeleteonCreate
2nd gen in one sentence
Cloud Functions 2nd gen is built on top of newer Google serverless primitives (including Eventarc and Cloud Run infrastructure), giving better scalability, concurrency controls, and a more flexible event model.
"Does a 2nd gen function become Cloud Run?"
Short answer: under the hood, yes, it runs on Cloud Run infrastructure.
More precise answer:
- You still develop and deploy it as a function.
- GCP packages it as a containerized workload.
- Execution runs on Cloud Run-managed infrastructure.
- Events are routed through newer eventing components (commonly Eventarc).
So in practice, thinking of 2nd gen functions as "functions powered by Cloud Run" is correct.
Trigger differences (practical view)
In many codebases, 1st gen uses familiar Firestore triggers such as:
onWrite: runs for create, update, and deleteonUpdate: runs only when a document changesonDelete: runs when a document is removed
In 2nd gen, you usually model these with explicit event handlers (for example Firestore document create/update/delete handlers), with clearer separation and easier scaling tuning.
Migration mindset
When migrating from 1st gen to 2nd gen:
- Split broad
onWritehandlers into specific handlers where possible. - Make handlers idempotent (retries can happen).
- Review timeouts, memory, and concurrency instead of keeping old defaults blindly.
- Add observability before migration (structured logs + error counters).
Real-world tradeoffs
2nd gen usually wins when you need:
- Better cold-start profile under load
- Higher throughput
- More predictable scaling controls
- Better integration with modern GCP eventing
1st gen can still be acceptable for:
- Small legacy workloads
- Simple triggers with low traffic
- Projects where migration budget is temporarily limited
Final takeaway
If your project is active and growing, 2nd gen should be the default direction. Keep 1st gen only as a short-term compatibility bridge, not as the long-term architecture.