Edmonds Commerce - Strangler Fig Pattern
Overview
Incremental modernisation strategy without risky complete rewrites. Gradually replace legacy functionality with modern code whilst old system continues running.
What Is the Strangler Fig Pattern?
Named after strangler fig plants that grow around trees and eventually replace them, the Strangler Fig pattern is an approach to incrementally modernise legacy systems without catastrophic rewrites.
How It Works
- New Code: Write new functionality in modern language/framework
- Parallel Running: Old and new systems run simultaneously
- Gradual Migration: Route traffic to new features progressively
- Legacy Deprecation: Gradually phase out old code as features migrate
- Complete Replacement: Eventually, old system is completely replaced
Key Benefits
Zero Downtime: System stays running throughout transition.
Reversible: Decisions are reversible if new approach doesn't work.
Team Productivity: Development continues during modernisation.
Risk Mitigation: Small, validated changes rather than risky rewrites.
Knowledge Preservation: Old system remains if undocumented behavior must be maintained.
Strangler Fig Strategy
Phase 1: Planning & Architecture
Understand legacy system and design new architecture.
Activities:
- Analyse legacy system
- Identify feature boundaries
- Design new architecture
- Plan feature extraction sequence
- Establish facade/API layer
Phase 2: Facade Layer
Create abstraction layer between old and new.
Implementation:
- API gateway (new entry point)
- Request routing logic
- Facade hiding implementation
- Allows seamless routing between old/new
- Clients see single, consistent interface
Phase 3: Extract Features
Incrementally implement features in modern code.
Sequence:
- Start with least-used or lowest-risk features
- Implement in modern framework/PHP
- Add comprehensive tests
- Validate with users
- Route requests to new implementation
- Monitor performance and errors
- Repeat for next feature
Phase 4: Legacy Fallback
Keep old code as fallback.
Safety Net:
- New feature fails: fallback to legacy
- Unforeseen issues: seamless rollback
- Reduced deployment risk
- Confidence to deploy frequently
Phase 5: Decommissioning
Remove legacy code once migration complete.
When Safe:
- All features migrated
- Fallback no longer needed
- Old code stable and no longer used
- Documentation complete
Strangler Fig vs. Complete Rewrite
Strangler Fig
- Timeline: 12-24 months (distributed effort)
- Risk: Low (small changes validated constantly)
- Cost: Medium (slower but safer)
- Team Impact: Productive (add features while modernising)
- Reversibility: High (decisions reversible)
- Success Rate: High (proven pattern)
Complete Rewrite
- Timeline: 12-36 months (concentrated effort)
- Risk: Very High (big bang deployment)
- Cost: Very High (all or nothing)
- Team Impact: Stalled (focus on rewrite)
- Reversibility: Low (no fallback to old system)
- Success Rate: Low (common failure pattern)
Implementation Example
Legacy System
E-commerce platform with monolithic PHP application.
Requests → Legacy App (PHP 5.x)
├── Product Catalog
├── Shopping Cart
├── Checkout
├── User Accounts
└── Admin Panel
After Strangler Fig
Requests → API Gateway
├── Product Catalog → Modern API (Laravel)
├── Shopping Cart → Legacy (fallback)
├── Checkout → Modern (Laravel)
├── User Accounts → Legacy (for now)
└── Admin Panel → Modern (Filament)
Feature Extraction Sequence
Priority 1 (Low Risk, High Value):
- Product catalog (read-heavy, independent)
- Admin panel (internal tool)
- Search functionality
Priority 2 (Medium Risk/Value):
- Checkout (critical but well-defined)
- User account management
Priority 3 (High Risk, Critical):
- Legacy inventory system
- Payment processing
- Reporting
Facade Layer Implementation
API Gateway Pattern
Single entry point routes requests appropriately.
class Gateway {
public function route($request) {
// New features
if ($request->path === '/api/products') {
return $this->newProductApi->handle($request);
}
// Fallback to legacy
return $this->legacyApp->handle($request);
}
}
Feature Flags
Control routing without code changes.
if ($this->featureFlag->isEnabled('new-checkout')) {
return $this->newCheckout->process($order);
} else {
return $this->legacyCheckout->process($order);
}
Testing Strategy
Legacy System Tests
Capture current behavior with characterisation tests.
// What does the legacy system actually do?
$result = $legacyCheckout->process($order);
$this->assertEquals($expectedResult, $result);
New Feature Tests
Comprehensive tests for modern implementation.
// Ensure new implementation works correctly
$result = $newCheckout->process($order);
$this->assertEquals($expectedResult, $result);
Parity Tests
Ensure old and new produce same results.
// Old and new should behave identically
$legacyResult = $legacyCheckout->process($order);
$newResult = $newCheckout->process($order);
$this->assertEquals($legacyResult, $newResult);
Migration Workflow
1. Feature Analysis
Understand what needs extracting.
- Define feature boundaries
- Document behavior
- Identify dependencies
- Plan extraction sequence
2. New Implementation
Build modern version.
- Use modern framework
- Write comprehensive tests
- Ensure feature parity
- Document API
3. Integration
Connect new code to system.
- Implement facade/gateway
- Add feature flags
- Route requests
- Add monitoring
4. Validation
Ensure new implementation works.
- Test with real data
- Monitor performance
- Track errors
- Gather user feedback
5. Gradual Rollout
Route traffic gradually.
- Start with low traffic (5-10%)
- Monitor error rates
- Gradually increase to 100%
- Keep fallback ready
6. Decommission
Remove legacy code once safe.
- Verify zero traffic to legacy
- Archive old code
- Update documentation
- Celebrate success!
Technology Stack
Modern Stack:
- Laravel or Symfony for new code
- PHP 8+ for type safety
- Modern testing framework
- API design patterns
Legacy Stack:
- Kept as-is
- Still supported during transition
- Eventually decommissioned
- Documented for reference
Deployment Strategy
Blue-Green Deployment
Two production environments.
- Blue: Current production
- Green: New features
- Seamless switch between them
- Instant rollback if needed
Canary Deployment
Gradually increase traffic.
- 5% to new code
- Monitor for 24 hours
- Increase to 25%, 50%, 100%
- Rollback if issues detected
Feature Flags
Control feature rollout without redeployment.
- Toggle features on/off
- A/B test different implementations
- Gradual user exposure
- Instant rollback capability
Monitoring & Observability
Metrics to Track
- Error rates (new vs. legacy)
- Response time
- Request volume per feature
- User complaints/feedback
- Performance trends
Alerting
Alert on anomalies.
- Error rate spike
- Response time degradation
- Feature fallback triggers
- Resource exhaustion
Timeline & Cost
Typical Project:
- 12-24 months total
- 2-6 developers
- Distributed effort (not all-consuming)
- Allows parallel feature development
Target Audiences
Large Systems: Complex systems too risky to rewrite.
Business-Critical Apps: Cannot afford downtime.
Mature Codebases: Deep institutional knowledge in legacy code.
Growing Teams: Need to continue shipping features during modernisation.
Common Challenges
Data Consistency: Keeping old and new data in sync.
Solution: Careful state management, dual-write strategies during transition.
Complexity: Managing two systems in parallel.
Solution: Excellent monitoring, feature flags, clear ownership.
Performance: Old system slower, users notice inconsistency.
Solution: Prioritise performance-critical features for modernisation first.
Success Metrics
- Zero downtime: No production outages during transition
- Deployment frequency: Weekly or more
- Feature velocity: Maintained or improved
- Defect rate: Reduced compared to legacy
- Team satisfaction: Developers prefer new code
Related Services
Modern Framework Development: Build new features in Laravel/Symfony.
API Development: Design APIs for facade layer.
Testing: Characterisation tests, parity tests, regression tests.
Infrastructure & DevOps: Deployment automation, monitoring, feature flags.
Contact
Based in the UK, serving global clients. Discuss your legacy modernisation strategy, strangler fig implementation, or gradual upgrade plan.