All projects
Serverless / Experimental

FuncWarm

Serverless Warmup Control Plane.

Working prototypeGo / GCP Cloud Run / HTTP / Observability
The problem

A quiet service still needs a fast first response.

A Cloud Run service can scale to zero between bursts. The next request then pays for container startup and initialization — precisely when a user is waiting.

What I built

A separate Go control plane for warmup traffic.

I built FuncWarm to schedule HTTP requests to configured targets and record their outcomes. Warmup policy stays outside business services, so I can tune intervals and observe the request path independently.

Interactive architecture

funcwarm / architecture labArchitecture demo

Warmup request lifecycle.

active / committedretryfailure / cancellation
Step 1 / 6Ready

A target becomes due

The scheduler selects a due endpoint. Real deployments should avoid synchronized bursts and unbounded overlapping work.

Request
not sent
Instance ownership
Cloud Run platform
Measurement
awaiting response
Inspect / Scheduler

Selects a due target. A production schedule needs bounded concurrency, jitter and a clear policy for overlapping runs.

Read every step as text

Schedule a target, send the request, receive its response and record the outcome.

  1. The scheduler selects a due endpoint. Real deployments should avoid synchronized bursts and unbounded overlapping work.

  2. The Go controller attaches a deadline and cancellation context before starting HTTP work.

  3. An HTTP request reaches the target. Instance startup or reuse belongs to the platform, not the controller.

  4. The controller receives the response, checks its status and measures elapsed time.

  5. Record status and elapsed time for the target and attempt. Errors remain visible alongside successful responses.

  6. The controller reports status and duration for each attempt. I use those observations alongside workload and infrastructure cost to choose a warmup policy.

FuncWarm / experiment

20 requests. Every one completed.

I scheduled warmup requests to Cloud Run and recorded the outcome and response time of each attempt.

Requests
20One experiment
Success rate
100%20 out of 20
Average latency
103 msAcross 20 requests
Maximum latency
283 msLargest observed value
Successful requests
2020 attempts in total
Observed cold starts
0In this sample
20/20Requests completed100%

Each mark represents one successful request. The sample describes this experiment; instance retention still depends on Cloud Run.

Cloud Run / cost model

Three strategies. One clear cost model.

Compare scheduled requests with continuously idle capacity. Change the workload, billing and controller costs to find the trade-off for your service.

Scenario inputs

Resources & workload

Model scenario: the controller uses existing infrastructure, with $0 additional capacity cost. Enter its monthly overhead for your deployment.

Modelled monthly USD30 days / 1 vCPU / 0.5 GiB
A / min=0

Scale to zero

$0.00

Business traffic only; no warmup overhead

Lowest modelled spend
B / min=0

FuncWarm

$0.13

43,200 warmup requests

C / min=1

Minimum instances

$9.72

Continuously retained minimum capacity

FuncWarm vs minimum instances$9.59 lower / month
Calculation breakdown
Resources and charges for each alternative
ComponentScale to zeroFuncWarmMinimum instances
vCPU-seconds04,3202,592,000
GiB-seconds02,1601,296,000
Requests043,2000
CPU$0.00$0.10$6.48
Memory$0.00$0.0054$3.24
Request charges$0.00$0.02$0.00
Free-tier credit$0.00$0.00$0.00
Controller + other costs$0.00$0.00$0.00
Pricing, assumptions & scope

USD list prices for supported Tier 1 regions, checked 2 Nov 2026. Request mode rounds execution up to 100 ms; one request uses the selected CPU/memory, without concurrent resource sharing. Minimum capacity idle time excludes active work. Instance mode uses the entered aggregate lifetime (at least active work and one minute). The monthly free-tier toggle assumes its entire billing-account allowance is unused elsewhere, applied as resource spending credits.

This is a scoped infrastructure estimate, not a complete hosting bill. Egress, logging, builds/storage, tax and committed-use discounts are excluded unless entered as other costs. Warmup requests do not reserve an instance. The measured 103/283 ms values do not change when cost assumptions change.

My contribution

I designed and implemented periodic request scheduling and monitoring for the prototype.

Decisions & trade-offs

  • Separate the warmup controller from the target service so each can be observed independently.
  • Record status and duration for each HTTP attempt, independently of the business service.
The trade-off

Periodic requests trade idle capacity for scheduled work and controller overhead. I compare their incremental cost with minimum instances; Cloud Run still owns the target lifecycle.

Separate policy from the service.

I kept scheduling in a separate control plane. Target configuration identifies the HTTP endpoint and interval; the business service does not need its own timer or a dependency on the scheduler.

Schedule → execute → observe.

The scheduler selects a due target, the Go controller sends the HTTP request, and monitoring records the outcome and elapsed time. Context and deadline bound the operation; cancellation prevents abandoned requests from accumulating.

For multiple targets, bounded concurrency, staggered schedules and jitter keep warmup traffic from becoming a synchronized burst. A missed run should be visible in monitoring instead of silently creating an unbounded catch-up queue.

Bound failures as carefully as successful requests.

DNS failures, connection errors, HTTP errors and deadline expiry need distinct outcomes. Retry limits prevent a failing target from absorbing the controller’s capacity. Shutdown must cancel in-flight work and release resources.

Pay for traffic or reserve capacity.

For a service with sparse traffic, a short periodic request can have lower overhead than continuously retained minimum capacity. The comparison depends on request billing, target resource allocation and the controller’s operating cost.

Minimum instances is the platform setting for keeping idle capacity available. FuncWarm exercises the real HTTP path but does not reserve an instance; Cloud Run still controls retention, restarts and scaling. When predictable first-request latency is a firm requirement, that distinction matters.

Validate deadlines, cancellation and overlap.

My validation checklist covers a slow endpoint, a missed schedule, overlapping runs, cancellation during HTTP execution and shutdown with active requests. The assertions should check bounded in-flight work, released resources and a recorded outcome for each attempt.

Observe the controller and its targets.

Schedule lag, active requests, outcome counts and elapsed time show whether the control plane is doing useful work. Target logs and traces help distinguish a slow network path from container initialization. Cost review includes warmup traffic, controller hosting and telemetry.

Results & next steps

In my 20-request experiment, every request succeeded. Average latency was 103 ms, maximum latency was 283 ms, and no cold attempts were observed.

The takeaway

A separate Go control plane centralizes warmup policy and makes request outcomes observable. I evaluate its operating cost alongside the first-response latency the service needs.

Keep exploringEventForge