Build performance, CI, and interview scenarios
Optimize the builds developers actually run
Measure separately:
- configuration/sync;
- clean build;
- no-change build;
- implementation-only Kotlin edit;
- public ABI edit;
- resource/manifest edit;
- annotation/KSP generation;
- minified release;
- local versus remote-cache CI.
Common causes
| Symptom | Investigate |
|---|---|
| Every small edit rebuilds many modules | api exposure, ABI changes, task inputs, processors |
| Configuration always slow | eager project/task/configuration resolution, plugin count |
| Cache misses across CI | machine paths, timestamps, environment, non-relocatable outputs |
| KSP/kapt dominates | processor incrementality, generated scope, dependency versions |
| Release suddenly slower | R8 rules, dependency growth, resource graph, profile generation |
Practical improvement loop
- Capture baseline with representative scenario.
- Identify critical path/task and cause.
- Make one architectural/configuration change.
- Compare distributions, not one lucky run.
- Verify correctness/cache reproducibility.
- Add budget/regression monitoring.
❌ Avoid “enable parallel and hope”
Parallelism can increase memory pressure/contention and hide incorrectly shared task state.
✅ Prefer bottleneck-driven tuning
Fix serialization/eager work/invalidations, then tune workers/heap/parallelism on representative developer and CI hardware.
CI pipeline shape
format/static checks
↓
compile + unit tests (representative variants)
↓
lint/security/dependency checks
↓
instrumented/Compose tests (sharded)
↓
signed minified candidate
↓
smoke/generated split install + macrobench/profile
↓
publish immutable artifact + evidence
Parallelize independent stages and fail fast, but do not rebuild a different artifact at promotion time. Promote the already-tested immutable candidate.
Quick answers
What is a Gradle task graph?
A directed acyclic graph of selected tasks and dependencies constructed during configuration and executed in dependency order.
api versus implementation?
api exposes dependency types as part of a library consumer’s compile contract; implementation keeps an implementation detail internal. Public signatures determine the correct choice.
Why can release crash when debug works?
R8/resource shrinking, signing identity, variant configuration, manifest/resource merging, and split delivery differ. Test the exact minified signed candidate and retrace with its mapping.
AAB versus APK?
APK is installable; AAB is a publishing format used to generate optimized device APKs. Generated delivery must be tested.
Scenario 1: broad keep rule fixed crash
It restored reflection by retaining an entire package.
Follow-up: identify exact reflective contract, prefer generated adapter, narrow the rule, add minified test, compare optimization score/size, retain mapping.
Scenario 2: cached build contains wrong environment
Custom task read undeclared SERVER_URL.
Fix: explicit Provider task input and output, or remove build-time environment coupling; add cache correctness test.
Scenario 3: 96 variants
Four brands × four markets × three environments × two build types.
Analysis: identify real compile-time products, move runtime/server flags out, eliminate invalid combinations, create CI tiers, establish ownership and release evidence.
Architect exercise: enterprise build platform
Design for 150 modules, 20 teams, two brands, weekly release:
- convention plugin ownership/versioning;
- dependency catalog/BOM/verification;
- module API boundaries and ABI monitoring;
- configuration/build cache and remote security;
- test/variant sharding;
- signing/secrets/provenance;
- R8 mapping/symbol pipeline;
- build budgets and incident rollback;
- AGP/Gradle/Kotlin migration cadence.
Mastery checklist
- I explain build lifecycle/task DAG and lazy Providers.
- I model variants without uncontrolled explosion.
- I choose dependency configurations from public ABI.
- I diagnose minified release failures narrowly.
- I distinguish upload and app-signing keys.
- I test generated APK delivery from AAB.
- I measure clean/incremental/configuration/cache scenarios.
- I promote immutable tested artifacts with evidence.
Build architecture controls developer throughput and release trust. A fast build that produces an untraceable or untested artifact is failure; a secure release pipeline that takes hours for every edit is also unsustainable. Measure both feedback time and artifact integrity.