skip to content

When would you reach for CDS to improve Spring Boot startup, and how does it fit alongside heavier options like AOT/native?

level: principalimportance: should knowfreq 18%

answer

  1. CDS = cheap, keeps full JVM dynamism + tooling
  2. moderate win, low risk, silent fallback
  3. native = biggest win, heaviest cost/config
  4. AOT + CDS stack (not either/or)
  5. ladder: JVM -> CDS -> AOT -> native

basics

~20 s

Use CDS when you want cheaper, faster startup while keeping an ordinary JVM (full reflection, easy debugging, no special build). It gives a moderate startup cut with almost no risk and stacks with AOT; native images give bigger gains but cost far more build/complexity.

solid answer

~50 s

CDS is the low-cost, low-risk startup lever. It keeps a **normal JVM** — full reflection, dynamic proxies, standard debugging/observability, no separate build toolchain — and just memory-maps pre-parsed classes for a moderate startup reduction (~20-40%). The only real cost is a training run and treating the archive as a build artifact that must be regenerated on dependency/JDK changes. I reach for it whenever startup matters (autoscaling, frequent redeploys, CI, cost-sensitive instances) but I don't want to pay the price of GraalVM native images. Native gives much larger startup/footprint wins but demands a heavy build, reachability/reflection configuration, and loses easy runtime dynamism and standard JVM tooling. Crucially they're **complementary**, not either/or: Spring Boot AOT processing and CDS stack, so a common high-value combination is AOT + CDS on the JVM to approach native-like startup while staying on HotSpot. I'd default to CDS first, add AOT, and only go native when the workload truly justifies it.

go deeper

for a junior

Know CDS is the easy, low-risk way to speed startup on a normal JVM.

for a middle

Contrast CDS (moderate win, full JVM) with native (bigger win, heavier cost) at a high level.

for a senior

Articulate the cost/benefit ladder and CDS's preservation of reflection/tooling as the pragmatic default.

for a principal

Drive the platform decision: escalate JVM -> CDS -> AOT -> native by workload constraints, exploit that AOT+CDS stack, and account for the archive's build-artifact lifecycle.

## The decision frame Startup optimization is a spectrum of **cost vs benefit**: 1. **Plain JVM** — baseline; easiest; slowest startup. 2. **CDS** — small effort (a training run + an archive artifact), moderate startup win, **keeps everything about the ordinary JVM**. 3. **AOT processing** (Spring's ahead-of-time transformations on the JVM) — more build involvement, further startup gains; still HotSpot. (Owned by the sibling AOT/native topic — mentioned here only for positioning.) 4. **GraalVM native image** — largest startup and memory-footprint wins, but the highest cost: long native builds, reachability/reflection/resource configuration, and loss of some runtime dynamism and standard JVM tooling. ## Why CDS is the pragmatic default - **No behavioral change.** Reflection, classpath scanning, dynamic proxies, agents, and JMX all keep working exactly as on a normal JVM. There's nothing to reconfigure for dynamic features. - **Standard tooling stays.** Profilers, debuggers, heap dumps, JFR — all unchanged. - **Low risk.** If the archive is invalid the JVM just falls back to normal loading; worst case you lose the speedup, you don't break the app. - **Cheap to adopt.** The training run is quick, and buildpacks (`BP_JVM_CDS_ENABLED=true`) can automate it into the image. The trade-off is that CDS's win is **moderate** (it only removes class-parse/verify cost, not JIT warmup or framework wiring cost) and the archive is **coupled to classpath + JDK**, so it's a build artifact you must regenerate on changes. ## Why not always go native? Native images deliver dramatically faster startup and lower memory, which is compelling for serverless/scale-to-zero. But you pay with: slow, resource-heavy builds; the need to declare reflection/proxy/resource usage (hints); reduced runtime dynamism; and a divergence from standard JVM debugging/observability. For many server workloads that live for hours and autoscale on the order of seconds, CDS (optionally + AOT) captures most of the practical benefit at a fraction of the operational cost. ## They compose A key principal-level point: **CDS and Spring's AOT are not mutually exclusive** — they stack. AOT shifts framework/bean setup work to build time; CDS removes class-loading cost. Running **AOT + CDS on the JVM** is a sweet spot that approaches native-like startup while retaining HotSpot's dynamism and tooling. So the escalation ladder is usually: plain JVM -> add CDS -> add AOT -> only then consider native if the workload's startup/footprint constraints genuinely demand it. ## When CDS specifically shines - **Autoscaling / rapid redeploys** where each cold start's seconds matter but you still want a normal JVM. - **Cost-sensitive fleets** where shared read-only mapped class metadata across many instances trims footprint. - **CI/test pipelines** that repeatedly boot the app. - Teams that want a **quick, reversible win** without committing to the native-image build/operational model. ## When CDS isn't enough If you need **sub-100ms starts and minimal RSS** (scale-to-zero serverless, huge fan-out of short-lived instances), CDS alone won't get you there — that's the case for going native, accepting its build and configuration cost.

  • You need faster startup but the team relies heavily on runtime reflection and standard debuggers — CDS or native?
    CDS. It preserves full reflection, dynamic proxies, and standard JVM tooling while still cutting startup. Native would force reflection/reachability configuration and give up easy debugging — a poor fit for that constraint.
  • Can CDS and Spring's AOT be used together, and why would you?
    Yes — they're complementary. AOT moves framework/bean setup to build time; CDS removes class-loading cost. Combining them on the JVM yields near-native startup while keeping HotSpot's dynamism and tooling.
  • What ongoing operational cost does choosing CDS introduce?
    The .jsa archive is coupled to the classpath and JDK, so it's a build artifact you must regenerate (and ideally verify with -Xshare:on) whenever dependencies or the JDK change — best automated in the build/buildpack pipeline.

saying these in an interview costs you the question

  • Framing CDS and AOT/native as mutually exclusive — they compose.
  • Claiming CDS matches native-image startup and memory footprint — it doesn't; it's a moderate, cheaper win.
  • Recommending native by default without acknowledging its build/reflection/tooling costs.
  • Ignoring that CDS keeps full runtime dynamism, which is often the deciding factor.

context