Why Your Microservices Keep Breaking: A Deep Dive into Dependency Management
You've adopted microservices for agility and scalability—but somehow, a "simple" change in one service cascades into failures across your entire system. Sound familiar? The culprit is almost always hidden dependencies.
While tools for maintaining monolithic architectures are well-established, there's a notable gap in methodologies for analyzing and managing changes within decentralized microservice systems. This research—published at CLOSER 2024 and extended in a Springer volume—investigates how dependencies impact maintainability and provides concrete strategies for managing them effectively.
The Hidden Problem: Explicit vs. Implicit Dependencies
When developers assess the impact of changes, they typically focus on explicit dependencies—the visible inter-service calls that are immediately recognizable. But there's a whole category of implicit dependencies that escape attention during change assessment.
Explicit dependencies include direct inter-service calls via REST APIs or gRPC—the pathways developers immediately recognize.
Implicit dependencies are far more insidious:
- Event-driven invocations: Messages triggered through Kafka, RabbitMQ, or other messaging systems
- Cross-cutting policies: GDPR compliance, RBAC rules, or security policies that must be applied across services
- Shared data entities: Services unknowingly sharing data schemas or DTOs from monolithic origins
The GDPR Example
Regulations like GDPR or access control rules can't be modularized without breaching cloud-native principles. Policies must be individually applied to each microservice, dispersing the concern across components. When policies need updating, each modification must be tracked and implemented across all distributed elements.
Four Problem Areas Where Dependencies Strike
Our analysis identified four key areas where dependencies manifest and cause issues:
Architectural Misalignment
Cascading failures, communication complexity, and functional bottlenecks caused by high coupling and over-reliance on single endpoints.
Resource Management Issues
Large resource consumption, service conflicts, and QoS violations from differentiated dependencies and deployment challenges.
Performance Degradation
Dynamic, time-varying dependencies that complicate performance monitoring and resource allocation.
Operational Complexities
Service conflicts, uneven communication delays, and uncoordinated transmissions from non-integrative scaling practices.
Four Strategies to Detect Architectural Degradation
To counteract architectural degradation effectively, we identified four principal strategies that form a robust framework:
1. Metrics-Based Detection
Metrics provide critical insights into software quality by analyzing source code and assessing architectural stability. Key metrics include:
- Instability indicators: Code churn rate signals potential architectural concerns
- Modularity metrics: ANMCC (Average Number of Modified Components per Commit), IPCI, IPGF
- Cyclomatic Complexity: Measures codebase complexity and maintenance challenges
- Code duplication: Reveals modularity issues that complicate updates
Key Insight
Traditional metrics may not adequately reflect dynamics in cloud-native systems where codebases are decentralized. Remote procedure calls as dependency indicators miss non-obvious, implicit dependencies that span across microservices.
2. Smell Detection Strategies
Tools like SonarQube help identify anti-patterns, but traditional smell detection is optimized for monolithic repositories. In microservices, anti-patterns can extend across various components.
The key insight: Smells often only signal symptoms of deeper problems. Dependencies provide a foundational view of system interrelations without requiring pre-defined rules. Comparing system versions makes the impact of changes more quantifiable than merely relying on anti-pattern catalogs.
3. Architecture Reconstruction Strategies
Architecture reconstruction maps services and their interactions while delving into underlying dependencies and architectural logic. Recent advances enable automation of extracting and analyzing both static and dynamic aspects of codebases.
Challenge: Focus on explicit dependencies and control flows often overlooks subtler, implicit connections between components. Enriching reconstructed models with comprehensive dependency mapping enables more robust analysis.
4. Architectural Rule Violation Detection
Rules dictate that service layers communicate solely through specified interfaces, avoiding unauthorized access patterns. Effectiveness hinges on comprehensive cataloging of all dependencies—missed dependencies diminish rule effectiveness.
A Practical Example: Fraud Detection System
Consider a fraud detection system monitoring transactions for fraudulent activities:
In this system:
- Service A (Transaction Monitoring) monitors all transactions and controls the workflow
- Service B (Account Service) provides account information for fraud evaluation
- Service C (Alert Service) notifies customers and security teams
- Service D (Audit Service) logs transaction details for auditing
Multiple dependency types are at play:
- Data Dependencies: Services A, C, and D all rely on account and transaction information
- Control Dependencies: Service A controls the workflow by initiating actions in dependent services
- Communication Dependencies: API calls between all services
- Resource Dependencies: Shared CPU and memory for fraud detection algorithms
The Four Dependency Types and Their Tools
| Dependency Type | Description | Tools |
|---|---|---|
| Data Dependencies | Services share or access the same data entities | EDM, DDM |
| Control Dependencies | Execution depends on control flow or state of another service | TraceNet, GDC-DVF |
| Communication Dependencies | Service interactions via API calls and message passing | ChainsFormer, GSMART |
| Resource Dependencies | Shared computational resources (CPU, memory, storage) | DeepScaler, SYMBIOTE |
Data Dependencies & Solutions
Data dependencies arise when microservices share or access the same data entities. Changes in data schemas must be coordinated across services.
Mitigation patterns:
- Tolerant Reader: Design services to handle unknown or extra data gracefully
- Request Mapper: Transform incoming requests to decouple internal logic from external data formats
Control Dependencies & Solutions
Control dependencies arise when one service's execution depends on the control flow or state of another.
Tools:
- TraceNet: Analyzes tracing data to pinpoint root causes of problems
- GDC-DVF: Maps invocation relationships and extracts dependencies for monolith-to-microservice transitions
Communication Dependencies & Solutions
Communication dependencies involve service interactions through synchronous or asynchronous mechanisms.
Tools:
- ChainsFormer: Analyzes communication patterns to identify critical paths for resource provisioning
- GSMART: Creates service dependency graphs (SDGs) for tracing relationships and regression testing
Resource Dependencies & Solutions
Resource dependencies cause contention and performance degradation when services share computational resources.
Tools:
- DeepScaler: Uses affinity matrices to scale microservices dynamically based on usage patterns
- SYMBIOTE: Monitors coupling metrics to detect architectural degradation and optimize allocation
Maintainability: The Five Quality Attributes
Dependencies directly impact the five ISO 25010 maintainability attributes:
Modularity
While microservices aim for modularity, the interconnected nature and widespread distribution of global policies (like RBAC) complicate modular design. RBAC can enforce interdependence by requiring shared security protocols, introducing tight coupling based on access controls.
Strategy: Centralize shared logic in importable libraries while preserving service independence, aligned with the Twelve-Factor App methodology.
Reusability
Traditional reusability aims to save development time—but in microservices, excessive reusability leads to increased dependencies. Microservices advocate a "share-as-little-as-possible" approach to minimize coupling.
Strategy: Consider serverless computing models that execute backend services on-demand without server management overhead.
Analysability
Tracing and logging enhance analysability but depend on consistent developer practices. Static analysis tools often fall short in distributed microservice environments.
Strategy: Develop sophisticated tracing mechanisms and encourage consistent logging practices across teams.
Modifiability
Effective dependency management enables comprehensive change impact analysis, which helps mitigate negative effects of improper design.
Strategy: Thoroughly analyze the system to map all dependencies before implementing changes.
Testability
Proper dependency management streamlines testing by pinpointing which specific tests are affected by system changes.
Strategy: Implement dependency-aware testing strategies to optimize test maintenance and resource use.
The Tree Metaphor: Understanding Architectural Degradation
In this visual metaphor:
- Roots = System dependencies (the foundation)
- Trunk = System architecture (structural integrity)
- Leaves = Maintainability (health indicators)
- Barren branches = Unmaintained system (neglected dependencies)
The key insight: The health of your system's architecture relies heavily on careful management of its dependencies. Neglecting the underlying dependencies results in deterioration of structural integrity.
Practical Recommendations
For Architects
- Map dependencies early — Track both explicit and implicit dependencies during design
- Adopt the four-strategy framework — Use metrics, smell detection, architecture reconstruction, and rule enforcement together
- Address implicit dependencies — Don't ignore events, policies, and shared data
For Developers
- Use Tolerant Reader and Request Mapper patterns — Handle data changes gracefully
- Implement comprehensive tracing — Enable dependency analysis at runtime
- Avoid shared databases — Expose data through dedicated services
For DevOps Teams
- Deploy dependency monitoring tools — Use TraceNet, GSMART, or SYMBIOTE
- Integrate dependency checks into CI/CD — Catch issues before deployment
- Monitor resource dependencies — Use DeepScaler for dynamic scaling based on service affinities
Future Directions
The research identifies several open challenges:
- Scalable dependency management strategies for rapidly evolving microservices
- Tools for implicit dependency detection across polyglot environments
- Integration of dependency analysis with continuous delivery pipelines
- Automated change impact analysis based on comprehensive dependency mapping
Citation
If you find this work useful, please cite:
@incollection{cerny2026dependencies,
title={On Dependencies in Microservices: Dependency Management and Maintainability},
author={Cerny, Tomas and Chy, Md Showkat Hossain and Uddin, Md Arfan
and Abdelfattah, Amr S. and Soldani, Jacopo and Bogner, Justus},
booktitle={Cloud Computing and Services Science},
series={Communications in Computer and Information Science},
volume={2851},
pages={29--52},
year={2026},
publisher={Springer},
doi={10.1007/978-3-032-17286-0_2}
}
About This Research
This research was conducted at the University of Arizona, in collaboration with the University of Pisa and Vrije Universiteit Amsterdam, with support from the National Science Foundation under Grant No. 2409933.
The paper expands on earlier findings presented at CLOSER 2024, providing detailed analysis of dependency types, detection strategies, and practical examples that underscore the complexity of managing interrelations within microservice architectures.
Feel free to reach out with questions or to discuss the research!