Performance

The Cold Start Optimization Playbook

Techniques I used to shave 25% off cold-start times across 15+ production apps. Covers App Startup library, lazy initialization patterns, background thread strategies, and measuring what actually matters.

2025 8 min read

What Cold Start Actually Means

Cold start is the time between the user tapping your app icon and seeing the first meaningful frame. It includes process creation, Application class initialization, Activity creation, layout inflation, and the first draw pass. Every ContentProvider, every eager singleton, every synchronous SDK initialization adds to this number.

On a mid-range device — the kind most of your users actually have — a poorly optimized cold start can easily exceed 3 seconds. That is long enough for users to question whether the app is broken.

Step 1: Measure Before You Optimize

The first mistake teams make is optimizing without a baseline. I use three measurement approaches:

Step 2: Audit Your Application Class

The Application class is the single biggest contributor to cold start time. Every line of code in onCreate() runs before the user sees anything. I categorize initializations into three buckets:

Move everything in the second bucket to a background coroutine launched after the first frame renders. Move everything in the third bucket to lazy initialization triggered by first use.

Step 3: App Startup Library

Android's App Startup library replaces the ContentProvider-based initialization pattern. Instead of each library declaring its own ContentProvider (each adding ~2ms to startup), you declare a single provider and order your initializations explicitly. This alone saved 80-120ms across our apps.

Step 4: Baseline Profiles

Baseline Profiles are the highest-impact, lowest-effort optimization available. By generating a profile of your app's critical code paths, you instruct the ART runtime to pre-compile those methods during installation. The result: methods that would normally be interpreted on first run are already compiled to native code.

In our testing, Baseline Profiles improved cold-start time by 15-20% with zero code changes. The only effort is writing a Macrobenchmark test that exercises your critical user journeys.

Step 5: Layout Optimization

The first layout inflation is part of cold start. Deep view hierarchies, nested ConstraintLayouts, and complex data binding expressions all contribute. I follow these rules:

The Results

Applying these techniques systematically across 15+ apps yielded a consistent 25% reduction in cold-start time. The median startup improved from 1.8s to 1.35s. On low-end devices, the improvement was even more dramatic — from 3.2s to 2.1s.

Startup TracesLazy InitBaseline ProfilesMacrobenchmarkApp StartupCoroutines