When would you reach for CDS to improve Spring Boot startup, and how does it fit alongside heavier options like AOT/native?
answer
- CDS = cheap, keeps full JVM dynamism + tooling
- moderate win, low risk, silent fallback
- native = biggest win, heaviest cost/config
- AOT + CDS stack (not either/or)
- ladder: JVM -> CDS -> AOT -> native
basics
~20 sUse 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 sCDS 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
Know CDS is the easy, low-risk way to speed startup on a normal JVM.
Contrast CDS (moderate win, full JVM) with native (bigger win, heavier cost) at a high level.
Articulate the cost/benefit ladder and CDS's preservation of reflection/tooling as the pragmatic default.
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.