Date: January 2025
Current Bundle Size (Windows x64): 577 MB on disk, 204 MB compressed
| Component | Size | #1 Bloat Source | Top Recommendation | Potential Savings |
|---|---|---|---|---|
| DCP | 286 MB | 5 large Go binaries (50-65 MB each) | UPX compression | 80-140 MB |
| .NET Runtime | 200 MB | Full SDK extraction | Already optimized (runtime only) | - |
| Dashboard | 43 MB | FluentUI Icons (21 MB) | Manual icon subsetting | 18-20 MB |
| CLI | 22 MB | Native AOT binary | Already optimized | - |
| AppHost Server | 21 MB | KubernetesClient.dll (9.3 MB) | Remove XML docs | 1.3 MB |
Total Potential Savings: 100-160 MB (17-28% reduction)
Current State:
| Binary | Size | Purpose |
|---|---|---|
| dcp.exe | 64 MB | Main orchestrator |
| dcpctrl.exe | 61 MB | Controller host |
| dcptun_c | 56 MB | Tunnel client (Linux, for containers) |
| dcptun.exe | 52 MB | Tunnel server |
| dcpproc.exe | 52 MB | Process monitor |
Build Configuration Analysis:
β
CONFIRMED: Binaries ARE properly stripped. The Azure DevOps pipeline (common-build.yml) uses make release which includes:
release: BUILD_ARGS := $(BUILD_ARGS) -buildmode=pie -ldflags "-bindnow -s -w $(version_values)"The -s -w flags strip debug symbols and DWARF info. The 50-65 MB sizes are expected given:
- Kubernetes API Server dependency - Each binary imports
k8s.io/apiserverwhich is a heavy dependency - Full Go runtime - Each binary includes the complete Go runtime (~5-10 MB base)
- gRPC/Protobuf libraries - Required for communication between components
- Five separate binaries - Code duplication across binaries (shared libraries compiled into each)
Root Causes (Architecture, not build settings):
- Code duplication - Each binary includes full Go runtime + shared K8s client libraries
- Heavy K8s dependencies - The Kubernetes API machinery is inherently large
- Cross-platform binary -
dcptun_c(Linux) is included in Windows bundle for container support
Recommendations:
| Priority | Action | Savings | Effort | Notes |
|---|---|---|---|---|
| π‘ Medium | Apply UPX compression | 80-140 MB | Low | |
| π‘ Medium | Lazy-download dcptun_c |
56 MB on-disk | Medium | Only for Windows bundles |
| π’ Low | Consolidate binaries | 30-50 MB | High | Major refactor |
UPX Compression Trade-offs:
UPX can compress Go binaries by 50-70%, but consider:
| Pro | Con |
|---|---|
| Significant disk space reduction | Adds 100-200ms startup latency per execution |
| Reduces download size | May trigger antivirus false positives |
| Simple to implement | Breaks code signing (must sign after UPX) |
| macOS notarization may fail | |
| Decompresses to full size in memory |
Recommendation: Test UPX thoroughly before adopting. Consider it primarily for reducing download/distribution size, not memory footprint.
Size Breakdown:
| Category | Size | % |
|---|---|---|
| FluentUI Icon DLLs | 21.2 MB | 50% |
| AI packages (OpenAI, MCP, etc.) | 7.4 MB | 17% |
| Dashboard + other DLLs | 9.5 MB | 22% |
| JavaScript (Plotly, etc.) | 2.1 MB | 5% |
| Source maps, docs, other | 2.5 MB | 6% |
Top Files:
| File | Size |
|---|---|
| Icons.Regular.dll | 9.6 MB |
| Icons.Filled.dll | 8.1 MB |
| OpenAI.dll | 4.2 MB |
| Aspire.Dashboard.dll | 3.5 MB |
| Icons.Color.dll | 3.3 MB |
Root Causes:
- FluentUI ships ALL 11,000+ icons - Dashboard uses ~15-20 icons
- AI dependencies always included - OpenAI, MCP even when AI features disabled
- Debug artifacts in production - Source maps (1.3 MB), XML docs (0.6 MB)
Recommendations:
| Priority | Action | Savings | Effort | Notes |
|---|---|---|---|---|
| π΄ High | Manual FluentUI icon subsetting | 18-20 MB | Medium | No automated solution exists |
| π‘ Medium | Make AI features opt-in/lazy-loaded | 7 MB | High | Architecture change |
| π’ Low | Remove source maps + XML docs | 1.9 MB | Low | Quick win |
FluentUI Icon Subsetting (Manual Process):
- Create custom icon package - Fork/copy only the ~20 icons Dashboard uses
- Inline SVGs directly - Replace icon components with embedded SVG markup
- Wait for upstream solution - Microsoft is aware of this issue (see GitHub #619)
// Instead of:
<FluentIcon Value="@(new Icons.Regular.Size16.Copy())" />
// Consider inlining the SVG:
<svg>...</svg>Size Breakdown:
| Category | Size |
|---|---|
| KubernetesClient.dll | 9.3 MB (45%) |
| Aspire.Hosting.dll | 2.0 MB |
| XML documentation | 1.3 MB |
| Other DLLs | 8.1 MB |
Root Causes:
- Full K8s client required - Used for DCP communication (not optional)
- XML docs shipped - Not needed at runtime
- Dual JSON libraries - Both Newtonsoft.Json and System.Text.Json
Recommendations:
| Priority | Action | Savings | Effort | Notes |
|---|---|---|---|---|
| π’ Low | Remove XML documentation | 1.3 MB | Low | Quick win |
| Enable IL trimming | 2-3 MB | Medium | May break reflection-heavy code |
Note on KubernetesClient.dll: This is required for DCP communication - it cannot be removed or made optional.
<!-- Add to Dashboard and AppHost Server csproj -->
<PropertyGroup>
<PublishDocumentationFile>false</PublishDocumentationFile>
</PropertyGroup>Ensure production builds exclude .map files.
- Remove XML docs from Dashboard/AppHost publish
- Remove source maps from Dashboard publish
- Create custom FluentUI icon package with only used icons
- Evaluate UPX compression for DCP (with thorough testing)
- Lazy-download
dcptun_cfor Windows
- Make AI features opt-in for Dashboard
- Consider DCP binary consolidation (major refactor)
| Scenario | Current | Target (Phase 1+2) | Reduction |
|---|---|---|---|
| On Disk | 577 MB | 470-520 MB | 10-18% |
| Compressed | 204 MB | 165-185 MB | 9-19% |
The DCP binaries ARE properly built with release flags. After analyzing the Azure DevOps pipeline:
- Pipeline location:
.azure/pipelines/common-build.yml - Build step (line 259):
make release - Makefile target (line 316):
release: BUILD_ARGS := $(BUILD_ARGS) -buildmode=pie -ldflags "-bindnow -s -w $(version_values)"
The -s flag strips the symbol table, and -w omits DWARF debug information. The large binary sizes (50-65 MB each) are inherent to Go binaries with heavy Kubernetes dependencies.
The bundle is already reasonably optimized. The main opportunities are:
- FluentUI icons (18-20 MB) - Requires manual effort to subset
- UPX for DCP (80-140 MB) - Has trade-offs, needs evaluation
- Debug artifacts (3 MB) - Easy quick win
The architecture decisions (5 separate Go binaries, full K8s client, full icon libraries) are the root causes. Significant reductions would require architectural changes.