n4nAI

Google Cloud Functions gen 2 timeout limits for LLM requests

Practical guide to configuring Cloud Functions Gen2 timeouts for LLM APIs: set limits, stream responses, use async patterns, and avoid provider stalls.

n4n Team4 min read849 words

Audio narration

Coming soon — every post will get a voice note here.

Cloud Functions Gen2 gives you up to 60 minutes of execution time, but that doesn’t mean your cloud functions gen 2 timeout llm integration should block anywhere near that long. LLM inference calls can hang on provider degradation, large context windows, or slow token streams, and a misconfigured timeout turns a retryable error into a cold-start penalty. This guide lays out an ordered path to make serverless LLM calls predictable.

1. Map the real timeout boundaries

Gen2 functions expose a --timeout flag (1–3600 seconds) that sets the maximum instance lifetime for a single invocation. Under the hood this is a Cloud Run revision timeout. The HTTP trigger enforces the same deadline: if your handler runs longer, the platform kills the instance and returns a 504.

LLM providers add their own constraints. An OpenAI-compatible chat completion call without streaming can sit idle while the model processes a 100k-token prompt. If you set your function timeout to 300s but the provider takes 320s, you eat the failure after already paying for cold start and compute.

Common pitfall: leaving the default 60s timeout. For any non-trivial RAG pipeline or agentic loop, 60s is too tight. But setting 3600s for a user-facing endpoint is worse—your client will give up first, and you’ll bill for an orphaned process.

2. Set explicit function and request deadlines

Deploy with a deliberate timeout that matches the percentile you can tolerate:

gcloud functions deploy llm-proxy \
  --gen2 \
  --runtime python311 \
  --trigger-http \
  --timeout 300 \
  --region us-central1

Inside the function, never call an LLM without a client-side timeout shorter than the function’s. In Python:

import requests

def call_llm(payload):
    # function timeout is 300s, but we cap the HTTP call at 30s
    resp = requests.post(
        "https://api.example.com/v1/chat/completions",
        json=payload,
        timeout=(3.05, 30)  # connect, read
    )
    resp.raise_for_status()
    return resp.json()

The tuple timeout separates connect from read. LLM endpoints that stream will send bytes continuously, so the read timeout only fires on stall, not on slow generation.

3. Stream tokens to keep the connection alive

Cloud Functions Gen2 supports response streaming if you return a generator and use the functions framework’s streaming mode. This flips the timeout dynamic: instead of one long silent wait, the client sees tokens every few hundred milliseconds. The platform keeps the request open as long as bytes flow.

import json
import openai

def stream_handler(request):
    body = request.get_json()
    def generate():
        for chunk in openai.chat.completions.create(
            model=body["model"],
            messages=body["messages"],
            stream=True
        ):
            if chunk.choices[0].delta.content:
                yield chunk.choices[0].delta.content
    return generate(), 200, {"Content-Type": "text/plain"}

Tradeoff: streaming complicates error handling. If the provider dies mid-stream, you’ve already sent a 200 status. Push a sentinel string or use a structured SSE protocol so the client can detect truncation.

4. Use client-side deadlines and retries

Your function should treat the LLM call as a bounded RPC. Wrap it with a retry that backs off on timeouts but respects an overall budget:

from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
import requests.exceptions

@retry(
    stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=1, max=10),
    retry=retry_if_exception_type(requests.exceptions.Timeout)
)
def bounded_llm_call(payload):
    return call_llm(payload)

Keep the total retry time under the function timeout. With a 30s read timeout and 3 attempts, budget ~90s plus backoff. Set the function timeout to 120s to leave headroom for cold start.

5. Push long generations off the request path

If your cloud functions gen 2 timeout llm design regularly needs more than two minutes, don’t fight the sync model. Trigger a Pub/Sub-backed function, return a job ID immediately, and let the worker function poll or push completion.

from google.cloud import pubsub_v1

def http_entry(request):
    publisher = pubsub_v1.PublisherClient()
    topic = "projects/my-proj/topics/llm-jobs"
    publisher.publish(topic, request.get_data())
    return {"job_id": "abc123"}, 202

The worker function can run up to the 60-minute limit, writing results to Firestore. The original caller polls via a separate lightweight endpoint. This trades latency for reliability and is the only sane pattern for batch summarization or multi-step agents.

6. Route through a gateway with fallback

Provider outages are the silent killer of serverless LLM calls. When a model host rate-limits or degrades, your read timeout fires only after the full wait. A gateway that fails over automatically removes that tail latency from your cloud functions gen 2 timeout llm budget.

n4n.ai exposes a single OpenAI-compatible endpoint covering 240+ models and applies automatic fallback when a provider is rate-limited or degraded. Point your SDK at it and forward cache-control hints to cut repeat-prompt costs:

import openai

client = openai.OpenAI(
    base_url="https://api.n4n.ai/v1",
    api_key="YOUR_KEY"
)
# client routing directive passes through; provider cache hints honored
resp = client.chat.completions.create(
    model="anthropic/claude-3.5-sonnet",
    messages=[{"role": "user", "content": "Summarize: " + long_text}],
    extra_headers={"x-n4n-route": "cost-optimized"}
)

Because the gateway shifts load before your function’s read timeout, you can keep aggressive client timeouts (10–15s) and still succeed on retry.

7. Measure timeout rates, not just errors

Cloud Monitoring emits function_execution_times and function_errors per Gen2 function. Create a alert on the ratio of 504 responses to total invocations. A rising timeout rate usually signals a provider slowdown, not your code.

gcloud monitoring policies create \
  --notification-channels=channels.json \
  --condition="ratio(function_errors, function_invocations) > 0.05"

Pair this with client-side logs that record which model and provider the call used. Without that dimension, you’ll waste time tuning function memory when the real issue is a specific model host.

Common pitfalls and tradeoffs

  • Cold start + timeout: A 2GB function takes 5–10s to spin up. If you set client timeout to 5s, the first call always fails. Set minimum instances or accept a warmup ping.
  • Streaming status codes: Once you write the first byte, HTTP status is committed. Validate auth and input before yielding.
  • Memory vs timeout: Gen2 scales CPU with memory. A 256MB function gets 0.33 vCPU and may tokenize slowly; bump to 1GB if preprocessing dominates.
  • Per-token metering: If you use a gateway with per-token usage metering, log the usage field to reconcile cost with timeout retries—retries double spend.

The cloud functions gen 2 timeout llm problem is rarely about the 3600s ceiling. It’s about picking a deadline that matches the provider’s tail behavior, streaming to avoid dead air, and moving genuinely long work to async triggers. Do that and your serverless LLM layer stays both cheap and alive.

Tagsgoogle-cloud-functionstimeoutsserverlessllm-api

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All google cloud functions & cloud run llm integration posts →