ADR-006: Performance-First Before Architecture
Status: Proposed
Date: 2026-01-20
Context: Modernization Priority
Decision
We prioritize Performance Fixes (Low-Hanging Fruit) before undertaking major architectural refactoring.
Context
The WepNG platform exhibits performance issues:
- Sync-over-Async:
.Resultand.Wait()calls causing thread pool starvation. - N+1 Queries: Loops triggering individual DB queries instead of batch operations.
- Swallowed Exceptions: Empty catch blocks hiding failures and retry storms.
- Loop of Death: Transactional operations inside iteration loops.
Architectural refactoring (e.g., extracting microservices) will not fix these issues—they will migrate with the code.
Rationale
"Make it work. Make it right. Make it fast."
— Kent Beck
However, in a legacy system with performance debt, we invert this:
"Make it not slow first. Then make it right."
Fixing performance issues:
- Improves User Experience immediately.
- Reduces Infrastructure Cost (fewer servers needed).
- Simplifies Refactoring (async code is easier to extract).
Consequences
-
Immediate Actions:
- Convert
.Result/.Wait()to properawaitin identified hotspots. - Add
StringBuilderfor string concatenation in loops. - Implement batching for import operations.
- Convert
-
Profiling First: Install MiniProfiler before big changes to measure impact.
-
Deferred Architecture: Microservice extraction, Bounded Context splitting, etc. happen AFTER performance stabilization.