Back to Blog
Performance11 min read2026-07-10

How to Reduce Cold Start Times in Containerized Apps

Cold starts hurt latency on scale-to-zero and autoscaling workloads. Learn what makes them slow — image size, runtime init, dependency loading — and concrete ways to shrink each phase.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

# How to Reduce Cold Start Times in Containerized Apps

Cold starts are the tax you pay for elastic, cost-efficient infrastructure. When a scaled-to-zero service wakes up, or an autoscaler adds a fresh instance under load, the first request waits while the container boots. This article breaks a cold start into its phases and shows how to attack each one.

Anatomy of a cold start

A cold start isn't one thing — it's a sequence, and you optimize it by knowing where the time goes.

PhaseWhat happensBiggest lever
SchedulingPod placed on a nodeResource requests, node availability
Image pullContainer image fetched to the nodeImage size, layer caching
Container startRuntime/process bootsBase image, runtime choice
App initializationFramework, DB pools, caches warm upLazy loading, lean startup
First requestCode paths run for the first timeJIT warmup, precomputation

Measure before optimizing. If 80% of your cold start is image pull, shaving startup code won't help much.

Lever 1: Shrink your image

Image pull is often the single largest contributor, and it scales directly with image size. Every technique from our Dockerfile and multi-stage guides pays off here:

  • Use a slim or distroless base instead of a full OS image.
  • Use multi-stage builds so the runtime image contains only what's needed.
  • Remove dev dependencies, build caches, and unused files.
# Multi-stage: ship only the artifact on a tiny base
FROM golang:1.22 AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o /app/server ./cmd/server

FROM gcr.io/distroless/static-debian12
COPY --from=build /app/server /server
ENTRYPOINT ["/server"]

Going from a ~1GB image to ~50MB can cut seconds off every cold start.

Lever 2: Speed up application initialization

Many apps do expensive work at startup that delays readiness: eager-loading huge modules, opening every connection pool, pre-warming caches, running heavy framework bootstrapping. Two strategies:

Lazy-load what you can. Defer initializing rarely-used components until first use, not at boot.

// Eager: blocks startup even if rarely used
const heavyClient = createExpensiveClient();

// Lazy: initialize on first use
let _client;
function getClient() {
 if (!_client) _client = createExpensiveClient();
 return _client;
}

Make readiness honest but minimal. Your readiness probe should pass as soon as the app can serve traffic — don't gate it on warming up optional caches that can fill lazily.

Lever 3: Choose a fast-starting runtime

Runtimes differ enormously in startup cost. A compiled Go or Rust binary starts in milliseconds. A JVM app with a large classpath can take seconds to warm up. Interpreted runtimes sit in between. You don't have to rewrite your app, but if cold start is critical and you're choosing a stack, this matters. For existing JVM apps, technologies like ahead-of-time compilation (GraalVM native image) can dramatically reduce startup.

Lever 4: Right-size resources

Under-provisioned CPU slows initialization — many runtimes do CPU-heavy work at boot (parsing, JIT compilation). Giving a container slightly more CPU during startup can shorten the cold start even if steady-state needs are modest. Conversely, requesting huge resources can slow *scheduling* because the scheduler needs to find a node with room. Tune to the sweet spot.

Lever 5: Keep something warm (when it matters)

The most reliable way to avoid a cold start is to not be cold. If a workload is latency-critical, keep a minimum number of warm instances instead of scaling fully to zero.

# Don't scale below one warm instance for latency-critical paths
minReplicas: 1
maxReplicas: 20

This trades the zero-cost idle state for consistent latency. It's the right call for user-facing production paths; scale-to-zero remains great for dev, internal, and bursty workloads. (Our scale-to-zero article covers this trade-off in depth.)

Lever 6: Cache the image on the node

If an image is already cached on a node, the pull phase nearly disappears. Pre-pulling popular images, or keeping warm nodes that already have your image, removes a big chunk of cold-start time. This is more of a platform-level concern, but it's worth knowing it exists.

A prioritized plan

  1. 1Measure where your cold-start time actually goes.
  2. 2Shrink the image — usually the biggest, easiest win.
  3. 3Trim startup work — lazy-load, minimal readiness.
  4. 4Right-size CPU for the startup burst.
  5. 5Keep warm capacity for anything latency-critical.

Cold starts on PandaStack

Cold starts are directly relevant on PandaStack because free-tier apps use KEDA scale-to-zero on preemptible nodes — that's exactly the cost/latency trade-off that makes a free tier viable, with the honest caveat that those apps cold-start after idle. The levers above apply cleanly: PandaStack builds with rootless BuildKit and pushes to Artifact Registry, so smaller multi-stage images pull faster on wake. Lean application startup and honest readiness checks shorten the init phase.

When a workload can't tolerate cold starts — a latency-sensitive production path — the answer is to run it on a paid tier with warm capacity rather than scale-to-zero, and to pick a compute tier (up through the C2/memory-optimized range) that gives startup enough CPU. In short: use scale-to-zero where idle savings matter, optimize the image and startup everywhere, and keep warm what your users feel.

References

  • [AWS: Operating Lambda — performance optimization (cold starts)](https://aws.amazon.com/blogs/compute/operating-lambda-performance-optimization-part-1/)
  • [Knative: Configuring autoscaling and scale-to-zero](https://knative.dev/docs/serving/autoscaling/)
  • [Google: Distroless images](https://github.com/GoogleContainerTools/distroless)
  • [GraalVM Native Image](https://www.graalvm.org/latest/reference-manual/native-image/)

Deploy lean, fast-starting apps on PandaStack — with scale-to-zero free-tier apps and warm paid tiers when you need them. Start at [dashboard.pandastack.io](https://dashboard.pandastack.io).

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Performance

Browse all Performance articles →

See also