Back to Dispatch
Infrastructure By Elias Makinen 5 min read

Cold Start at the Edge: Numbers From Our Beta

We instrumented 60 days of beta traffic to see exactly where latency budgets go during container cold starts. The 14ms average hides a long tail worth understanding.

Cold Start at the Edge: Numbers From Our Beta

Across 60 days of instrumented beta traffic, the average container cold start was 14ms. That number is useful, but incomplete: the mean hides a long tail created by image access, runtime initialization, and the distance between a request and the PoP that can serve it.

I am Elias Makinen, Head of Infrastructure at Symbiosis. Our team is three engineers, and we built this analysis from the traces generated by early-access pilots on the platform. The goal was not to produce a single attractive benchmark. It was to understand where the latency budget goes when a workload is not already warm.

What the 14ms average contains

A cold start is not one operation. In our path, a request can trigger several phases:

  • Traffic admission at the selected PoP
  • Container scheduling and placement
  • Image access and unpacking
  • Runtime initialization
  • Application readiness and request handling

The average across the beta was 14ms from cold-start trigger to an instance able to handle the request. That result covers traffic across our 12 PoPs on five continents: Stockholm, London, Amsterdam, Frankfurt, Paris, New York, Chicago, Los Angeles, Sao Paulo, Singapore, Tokyo, and Sydney.

The average is low because most starts spend very little time in each phase. It is not low because every start follows the same path. A warm local image, a small runtime, and a predictable request pattern produce a different trace from a start that needs additional image work or initializes a larger dependency graph.

Our instrumentation records timestamps for each phase and sends metrics to Datadog. We also expose the operational view through the gsb CLI, including commands such as:

gsb deploy
gsb status

That combination matters for a small team. A developer can inspect deployment state without building a separate observability workflow, while we can examine the same event boundaries when a trace needs deeper analysis.

A representative long-tail trace

The following is a synthetic example based on the patterns we observed during the beta, not a report about a named customer. Consider a Node.js API deployed in Stockholm. The application is small, but its startup path loads several modules and performs a readiness check before accepting traffic.

Phase Representative time
Admission and scheduling 4ms
Image access and unpacking 11ms
Runtime initialization 8ms
Readiness and first request 6ms
Total 29ms

A 29ms start is not unusual in isolation. It is also more than twice the beta average. The difference comes from the phases that are invisible in a single aggregate number. If image access rises from 11ms to 40ms and the runtime takes another 20ms to become ready, the request can experience a substantially different tail even though scheduling remains fast.

We saw the same pattern across languages and deployment shapes. The scheduler was rarely the only variable. Application startup work, image composition, and readiness behavior often determined whether a start stayed near the average or moved into the tail.

This is why we avoid presenting 14ms as a promise that every request will see 14ms. It is an average measured across early-access pilots, not a universal upper bound. We are not saying average latency is wrong as a metric. We are saying it needs phase-level context before it can guide an engineering decision.

Why prediction changes the problem

Symbiosis uses AI traffic prediction to create approximately a 40-second head start on incoming traffic spikes. That window lets the platform prepare capacity before the first request in a burst arrives. The prediction does not remove application initialization costs, but it changes how often those costs sit directly on the request path.

When the predicted increase is accurate, more containers can be ready before demand reaches the PoP. When the workload remains below the predicted threshold, the platform does not receive the same benefit from prewarming. Prediction is therefore part of the latency strategy, not a replacement for measuring startup behavior.

This distinction is especially important for edge workloads. A request may be close to one PoP and farther from another, while the useful preparation window can vary by traffic pattern. Our 12-PoP footprint gives the system more placement options, but each option still has to satisfy the workload's image, runtime, and readiness requirements.

What we changed during the beta

We started treating cold-start traces as a budget rather than a single duration. For each deployment, we looked at:

  • Time spent before a container was assigned
  • Whether image access appeared in the critical path
  • Runtime initialization duration
  • Readiness checks that delayed the first request
  • Whether predicted capacity was available before the spike

That view changed the questions we asked during debugging. Instead of asking only why a start was slow, we asked which phase had exceeded its normal range and whether the phase was avoidable. A readiness probe that performs unnecessary work is an application concern. A delayed placement decision is an infrastructure concern. Both appear as cold-start latency to the caller.

For users, the operational interface remains deliberately small. Deploy with gsb deploy, inspect state with gsb status, and use the metrics integration when a deeper trace is needed. No SRE is required is a core product promise, but that does not mean the system should hide its mechanics from engineers who want to inspect them.

Where this approach does not work yet

Prediction is less useful for traffic that is genuinely irregular, has no stable lead time, or arrives in a pattern the model has not seen. A sudden one-off request can still encounter a cold path. The 40-second head start is approximately measured, not a guarantee that every spike will be identified in time.

We also have not eliminated application-level startup costs. A container can be scheduled quickly and still spend time loading libraries, compiling code, opening connections, or waiting for readiness logic. Moving that work closer to the user does not make the work disappear.

There is a further tradeoff between keeping capacity warm and minimizing idle resource use. The right setting depends on traffic shape and workload behavior. A small API with regular bursts has different requirements from a service with long quiet periods and unpredictable requests.

The beta gave us a clear engineering result: 14ms is a meaningful average, but the long tail is where deployment decisions become visible. Instrumenting each phase lets us distinguish platform delay from application startup work, and the distinction is more actionable than a single headline number. Our next measurements will continue to focus on that boundary, because reducing the average without understanding the tail would leave the hardest cold starts untouched.