majorstaff2025

Meta (Facebook/Instagram)

The Weekly Update Penalty

Facebook and Instagram ship thousands of commits a week. Every update silently wiped all compiled code. Two billion users paid the JIT tax on every install.

The Incident

Facebook and Instagram each update their Android apps thousands of times per week from internal commits. Each update triggers a fresh install on user devices. Each install discards all AOT-compiled bytecode. The Android runtime must re-profile and re-compile hot paths from scratch — and at the velocity these apps ship, the device's cloud-compiled profiles can never keep up. The result: startup, scroll, and navigation were consistently slower than they could be across 2+ billion devices.

Evidence from the Scene

  • Startup, feed scroll, and navigation latency regressed after every weekly app update
  • Performance improved noticeably 3–4 days after a release, then dropped again on next update
  • Standard Macrobenchmark-generated profiles covered only a fraction of real user hot paths
  • Facebook loads 20,000+ classes on cold start — standard profiling missed most of them
  • The cloud-compiled profile mechanism couldn't generate profiles fast enough before the next update shipped
  • Performance gaps were consistent across all device tiers — not hardware-dependent

The Suspects

2 of these are the real root causes. The others are plausible-sounding distractors.

Every app update discarding all AOT-compiled bytecode, resetting users to JIT interpretation

Standard Macrobenchmark profiles too narrow to cover 20,000+ classes loaded at Facebook's scale

Loading 20,000+ classes at cold start with no lazy initialization

Shipping all feature code in one monolithic DEX file instead of dynamic feature modules

Unoptimized binary with dead code from hundreds of A/B experiment variants

The Verdict

Real Root Causes

  • Every app update discarding all AOT-compiled bytecode, resetting users to JIT interpretation

    Android discards all compiled code on every app update. For apps that update multiple times per week, the device's profiling system can never accumulate enough data to re-compile hot paths before the next update arrives — leaving users permanently on slower JIT-interpreted code.

  • Standard Macrobenchmark profiles too narrow to cover 20,000+ classes loaded at Facebook's scale

    A standard Macrobenchmark test covers the engineer's test scenario — not the full breadth of 2 billion users' real usage patterns. At Facebook's scale, many hot-path classes were simply not in the benchmark-generated profiles and remained JIT-compiled.

Plausible But Wrong

  • Loading 20,000+ classes at cold start with no lazy initialization

    Loading many classes contributes to startup time — but the 'regresses after every update, improves after a few days' pattern is the JIT warmup signature, not a class loading architecture problem.

  • Shipping all feature code in one monolithic DEX file instead of dynamic feature modules

    Dynamic feature modules reduce initial install size but do not address the AOT compilation reset that occurs after every update. The pattern here is specifically the update-wipe-recompile cycle.

  • Unoptimized binary with dead code from hundreds of A/B experiment variants

    Dead code from A/B experiments increases binary size and JIT workload — a real issue — but the primary signal here is the 'weekly update wiping performance' pattern, which points to AOT compilation reset as the mechanism.

Summary

Meta solved the weekly update penalty by building a production telemetry system: a custom ClassLoader that samples class loads from real users at low frequency, aggregates the data, and generates Baseline Profiles that include every class or method appearing in ≥20% of cold-start user traces — tens of thousands of entries per app, far beyond what any benchmark can cover. These profiles ship with every release build and guarantee AOT compilation at install time. The result: 3–40% improvements to startup, scroll performance, and navigation latency across Facebook, Instagram, and Threads. Published by Engineering at Meta, October 2025.

The Real Decision That Caused This

Shipping at high velocity without a mechanism to maintain AOT compilation across updates, and relying on benchmark-generated profiles that covered only a tiny fraction of real user hot paths.

Lesson Hint

Chapter 7 (Platform & Performance) covers Baseline Profiles, Macrobenchmark, and startup optimization at scale. Chapter 1 (Foundations) covers scale estimation and the difference between representative benchmarks and real production traffic.

Want to test yourself before reading the verdict?

Open Interactive Case in Autopsy Lab