Guides · Cloud Run & Google Cloud · Published 2026-09-13 · 3 min read

Cold Starts on Cloud Run for an Express App — What Happens in the First Second, How to Measure It, What Actually Shortens It, and When to Pay for a Minimum Instance

A scale-to-zero service pays for its first request after idle with a cold start. Where the time goes for a typical Node and Express app, how to measure it honestly, the changes that help (and the ones that do not), and the arithmetic for min-instances.

With no minimum instances, a Cloud Run service has no container running while it is idle. The first request after a quiet period has to wait for a container to be pulled, started, and for your app to be ready to listen. For a small Express site the wait is usually well under two seconds, sometimes more, and it is the one place where a cheap deployment feels slow. Here is where the time goes and what to do about it.

Where a cold start's time goes

Phase What happens What you control
Scheduling and image pull Cloud Run picks a machine and fetches the container image layers Image size; smaller base images and fewer layers pull faster
Container start The runtime starts and runs your entry command Little
Node startup and module loading Node boots, require walks your dependency tree Number and size of dependencies; lazy-requiring heavy modules
App initialisation Config loading, reading content from disk, connecting to databases Do only what is needed to listen; defer the rest
First request Your handler runs, often populating caches Cache warm-up strategy

The app itself is often the largest part. A content site that reads and parses every Markdown file at startup, or opens a database connection before listening, is choosing a long cold start.

Measuring honestly

Cloud Run logs the container startup latency for each new instance, visible in the logs as a startup line, and the request log records the total latency. Measure from outside as well: after the service has been idle long enough to scale to zero, time a request with curl -w "%{time_starttransfer}" and compare it with a second request a moment later. The difference is your cold start as a user sees it. Measure several times; the first pull after a new deployment is slower than later cold starts, because the image is cached on the machines afterwards.

Changes that help

Changes that do not help much

Increasing memory rarely shortens a cold start unless the app was memory-starved. Concurrency settings affect how many requests share an instance, not how fast the first one starts. Health checks do not keep an instance warm; the platform decides when to scale to zero.

The min-instances arithmetic

Setting minimum instances to one removes cold starts for the price of an instance idling around the clock. For a site with a handful of visitors an hour the idle cost is most of the bill; for a site with steady traffic through the day, the instance is busy anyway and the minimum costs little extra. Decide by looking at the request log: if there are long gaps between requests, you are paying for idle time to save a second for the first visitor after each gap. The billing detail is in what a small Cloud Run site really costs. A middle path is to accept cold starts on the content site but set a minimum on anything latency-sensitive, such as a redirect service in front of paid links, described in a tiny redirect service on Cloud Run.

Common mistakes

Summary

Cold starts are mostly your own startup code. Listen before you load, keep dependencies and the image small, defer heavy modules, and measure from outside after real idle time. Pay for a minimum instance only where the request log shows visitors who would notice.

Related guides