Architecture Documentation Best Practices
1. Introduction
In today's fast-paced software development world, architecture documentation often takes a backseat to coding and delivery. However, well-crafted architecture documentation remains a cornerstone of successful software projects—especially as systems grow in complexity and teams expand. This comprehensive guide explores best practices for creating, maintaining, and leveraging architecture documentation that adds genuine value to your development process.
2. Why Architecture Documentation Still Matters in Agile Teams
The Agile Manifesto prioritizes "working software over comprehensive documentation," but this doesn't mean documentation should be abandoned—just that it should be purposeful. Architecture documentation matters in Agile environments for several compelling reasons:
2.1 Alignment and Shared Understanding
Even with daily stand-ups and sprint reviews, teams need a consistent reference point for architectural decisions. Documentation creates alignment across team members with different backgrounds, experience levels, and joining dates. It establishes a shared mental model of the system, reducing misconceptions and enabling better collaboration.
2.2 Onboarding Acceleration
When new developers join an Agile team, architecture documentation drastically reduces their ramp-up time. Instead of piecing together the system's structure through conversations and code exploration alone, newcomers can quickly grasp the big picture and start contributing meaningfully sooner.
2.3 Decision Support
Architecture documentation captures the reasoning behind significant design decisions. This context is invaluable when teams need to adapt to changing requirements or troubleshoot complex issues. Without documented rationale, teams risk repeating past mistakes or unwittingly undoing intentional architectural choices.
2.4 Stakeholder Communication
Product owners, business analysts, and other non-technical stakeholders benefit tremendously from well-crafted architecture documentation. It helps them understand technical constraints, appreciate technical debt concerns, and make more informed business decisions.
2.5 Compliance and Governance
In regulated industries or enterprise environments, architecture documentation often serves as evidence for compliance reviews, security assessments, and governance processes. This reality exists regardless of development methodology.
The key to making architecture documentation work in Agile environments is keeping it lean, focused on what matters most, and treating it as a living artifact that evolves alongside your code.
3. What is Software Architecture Documentation? (And What It's Not)
3.1 The Essence of Architecture Documentation
Software architecture documentation is a structured collection of artifacts that communicates the significant design decisions shaping a software system. It articulates:
- System structure: How the software is organized into components, services, or modules
- Key interfaces: How these elements communicate with each other
- Quality attributes: How the architecture supports essential non-functional requirements
- Constraints and principles: The rules and patterns that guide implementation
- Technical context: How the system interacts with its environment
3.2 What Architecture Documentation Is Not
To use architecture documentation effectively, it's equally important to understand what it should not be:
- Not a substitute for code: The code remains the definitive implementation of the architecture
- Not a detailed design specification: It focuses on significant elements, not exhaustive details
- Not unchangeable: Architecture documentation evolves as the system evolves
- Not comprehensive API documentation: While it may reference key APIs, it doesn't replace detailed API docs
- Not a project plan: It describes the technical structure, not how or when it will be built
- Not a business requirements document: It shows how technical solutions fulfill requirements, not what those requirements are
3.3 Finding Purpose in Documentation
Effective architecture documentation answers specific questions for its audience. Before creating any architectural artifact, ask yourself:
- Who will use this documentation?
- What decisions will this documentation help them make?
- What level of detail is necessary to support those decisions?
This purpose-driven approach ensures you create documentation that adds value rather than bureaucratic overhead.
4. Lightweight vs. Comprehensive Architecture Docs: Finding the Balance
In practice, architecture documentation exists on a spectrum from lightweight to comprehensive. Finding the right balance depends on your specific context:
4.1 Factors Influencing Documentation Scope
- Team size and distribution: Larger, distributed teams typically benefit from more explicit documentation
- System complexity: More complex systems warrant more thorough documentation
- Regulatory requirements: Some domains mandate specific documentation standards
- Team experience: Less experienced teams often need more guidance
- Project lifespan: Long-lived systems benefit from more comprehensive documentation
- Rate of change: Rapidly evolving systems need more lightweight, adaptable documentation
4.2 Lightweight Documentation Approaches
For many modern teams, lightweight documentation strikes an optimal balance:
- Architecture decision records (ADRs): Brief documents capturing key decisions and their context
- Component diagrams: Simple visual representations of system structure
- README files: Strategic placement of documentation close to the code
- Wiki pages: Living documents that can evolve with the system
- Automated documentation: Tools that generate documentation from code annotations or metadata
4.3 When More Comprehensive Documentation Makes Sense
More detailed documentation becomes valuable in specific circumstances:
- Enterprise architecture: When a system must integrate with a complex organizational landscape
- Mission-critical systems: When reliability and maintainability are paramount
- Knowledge transfer: When preparing for significant team transitions
- Complex domains: When the problem space itself requires detailed explanation
4.4 Practical Balance
Most successful teams adopt a hybrid approach:
- Maintain a minimalist "core" architecture document that outlines the system's fundamental structure
- Supplement with just-in-time documentation for complex subsystems
- Use automated tools to keep diagrams and interface documentation current
- Implement lightweight governance to ensure documentation remains useful without becoming burdensome
The goal is not minimizing or maximizing documentation—it's optimizing documentation to support your team's needs while minimizing overhead.
5. How to Write Clear and Useful Architecture Documentation
Creating effective architecture documentation requires more than technical knowledge—it demands clear communication. Here are practices that make architecture documentation more accessible and valuable:
5.1 Know Your Audience
Different stakeholders need different information:
- Developers need enough detail to implement correctly
- New team members need orientation to understand the big picture
- Architects need rationales behind decisions
- Managers need implications for resources and timelines
- Operations teams need deployment and runtime considerations
Tailor your documentation to address each audience's primary concerns, possibly creating separate views for different stakeholders.
5.2 Use Visual Communication Effectively
Diagrams communicate structure and relationships far more efficiently than text:
- Use consistent notation (like UML or C4) that your audience understands
- Maintain a consistent level of abstraction within each diagram
- Include legends that explain symbols and colors
- Organize complex systems into hierarchical diagrams, from high-level to detailed views
- Consider interactive diagrams that allow exploration
5.3 Write Concisely and Precisely
Architectural writing should be both accessible and technically accurate:
- Define technical terms when first introduced
- Use consistent terminology throughout
- Write in active voice with clear subject-action relationships
- Break complex ideas into digestible sections
- Use bullet points and numbered lists for clarity
- Include concrete examples that illustrate abstract concepts
5.4 Provide Context and Rationale
Documentation becomes significantly more valuable when it explains the "why" alongside the "what":
- Describe the problem each architectural decision addresses
- Explain constraints that shaped the solution
- Acknowledge alternatives that were considered
- Document trade-offs explicitly
- Connect architectural decisions to business goals or quality attributes
5.5 Use Templates Judiciously
Templates can ensure consistency and completeness but should not force unnecessary documentation:
- Start with a minimal template and expand as needed
- Focus on sections that add value for your specific context
- Modify templates to fit your team's needs
- Consider using lightweight templates like arc42 or C4
By focusing on clear communication tailored to your audience, your architecture documentation will serve as a valuable resource rather than shelf-ware.
6. Key Components of an Effective Architecture Document
While architecture documentation should be tailored to your specific needs, certain components typically provide significant value across contexts:
6.1 System Context and Scope
This foundational section defines the boundaries of your system and its relationship with external entities:
- Context diagram: Shows the system as a black box interacting with users, other systems, and external resources
- Business context: Explains the business problem the system solves
- Technical context: Outlines the technical environment in which the system operates
- Stakeholder concerns: Identifies key stakeholders and their primary interests in the system
6.2 Architectural Principles and Constraints
This section establishes the guardrails within which architectural decisions are made:
- Design principles: Fundamental approaches that guide solution design (e.g., "API-first design")
- Technical constraints: Limitations that must be accommodated (e.g., "Must run on existing hardware")
- Business constraints: Requirements derived from business needs (e.g., "Must support 10,000 concurrent users")
- Conventions: Agreed-upon standards for implementation (e.g., "RESTful API design")
6.3 System-Level Structure
This core component explains how the system is organized:
- High-level components: Major building blocks and their responsibilities
- Component interactions: How information flows between components
- Data model: Key entities and their relationships
- Deployment view: How the system maps to infrastructure
- Cross-cutting concerns: How aspects like security, logging, and error handling are addressed
6.4 Critical Architectural Decisions
This section documents significant choices that shape the system:
- Decision records: Structured documentation of key decisions (using ADRs or similar format)
- Pattern usage: Architectural patterns applied and their implementation
- Technology selections: Major technology choices and their rationales
- Quality attribute strategies: How the architecture supports non-functional requirements
6.5 Risk and Technical Debt
Transparent acknowledgment of architectural challenges:
- Known risks: Areas of technical uncertainty or concern
- Technical debt: Compromises made with awareness
- Mitigation strategies: Plans for addressing identified risks
- Evolution path: How the architecture is expected to change over time
6.6 Reference Information
Supporting information that helps readers understand and use the architecture:
- Glossary: Definitions of domain-specific and technical terms
- External references: Links to related documentation
- Team information: Ownership and contact information
- Version history: Major changes to the architecture and documentation
While not every architecture document needs all these components, consciously deciding which elements to include or exclude based on your specific context ensures that your documentation provides maximum value with minimum overhead.
7. Using C4 Model to Document Software Architecture Visually
The C4 model, developed by Simon Brown, offers a hierarchical approach to visualizing software architecture that is both straightforward and powerful. It consists of four layers of increasing detail:
7.1 Context Level: The Big Picture
The Context diagram shows your system as a single box in relation to its users and the other systems it interacts with. This highest-level view:
- Establishes system boundaries
- Identifies key users and external dependencies
- Provides a starting point for understanding the system's purpose and scope
Best practices:
- Keep this diagram simple—aim for no more than 10-15 elements
- Include all significant user types and external systems
- Label relationships with the nature of the interaction
- Avoid implementation details at this level
7.2 Container Level: The System's Shape
The Container diagram breaks down your system into containers—high-level components like web applications, mobile apps, databases, or microservices. This view:
- Shows the major technical building blocks
- Illustrates how responsibilities are distributed
- Highlights communication patterns between containers
Best practices:
- Make technology choices explicit (e.g., "Spring Boot API" rather than just "API")
- Indicate protocols used for communication
- Keep containers relatively high-level (a single deployable unit)
- Include all significant data stores
7.3 Component Level: Inside the Containers
The Component diagram zooms into individual containers to show their key structural elements. This level:
- Identifies major components and their responsibilities
- Shows how components collaborate to fulfill container functions
- Bridges the gap between high-level architecture and code
Best practices:
- Focus on business-significant components
- Define clear component boundaries that map to your codebase
- Don't try to show every class or module—keep it architectural
- Consider creating separate component diagrams for complex containers
7.4 Code Level: Implementation Details
The Code level maps to your actual codebase structure, showing classes, interfaces, and their relationships. This lowest level:
- Connects architecture directly to implementation
- Can often be generated from the code itself
- May be necessary only for the most complex or critical components
Best practices:
- Use this level sparingly, focusing on areas that need detailed explanation
- Consider using automated tools to generate and maintain these diagrams
- Keep diagrams focused on a specific concern or functionality
7.5 Implementing C4 in Practice
To effectively use C4 in your architecture documentation:
- Start top-down: Begin with Context and Container diagrams for the entire system
- Drill down selectively: Create Component diagrams only for the most important or complex containers
- Use consistent notation: Maintain visual consistency across all levels
- Add supplementary diagrams: Complement C4 with cross-cutting views like deployment or data flow diagrams
- Consider tooling: Use tools like Structurizr, PlantUML, or draw.io with C4 templates
- Maintain living diagrams: Update diagrams as the architecture evolves
The C4 model's strength lies in its simplicity and scalability. By providing a clear hierarchy of views, it helps stakeholders zoom to the appropriate level of detail for their needs while maintaining a consistent visual language throughout.
8. How to Document Microservices Architecture the Right Way
Microservices architectures present unique documentation challenges due to their distributed nature, service autonomy, and evolutionary design. Effective documentation strategies for microservices balance service independence with system-level understanding:
8.1 System-Level Documentation
While microservices are independently developed, they still form a cohesive system:
- Service landscape map: A visual overview of all microservices and their business domains
- Communication patterns: How services interact (synchronous, asynchronous, event-driven)
- Cross-cutting concerns: System-wide approaches to monitoring, security, resilience, and deployment
- Data consistency model: How data integrity is maintained across services
- API gateway configuration: Routing and access control at the system boundary
8.2 Service-Level Documentation
For individual microservices, documentation should enable both independence and integration:
- Service purpose: Clear statement of service responsibilities and domain boundaries
- API contract: Detailed interface definition using standards like OpenAPI/Swagger
- Event schema: Definitions of events produced or consumed by the service
- Data model: Entity definitions and relationships managed by the service
- Dependencies: External services, libraries, or resources required by the service
- Operational characteristics: Resource requirements, scaling behavior, and failure modes
8.3 Ownership and Discoverability
Clear ownership information facilitates collaboration across team boundaries:
- Team responsibility: Which team owns each service
- Contact information: How to reach service owners
- Repository location: Where to find the source code
- Support process: How to report issues or request changes
- Service catalog: Centralized registry of all services with metadata
8.4 Evolution Documentation
Capturing change in a microservices landscape is critical:
- Version history: Significant changes to each service
- Deprecation policies: How and when API changes are communicated
- Migration guides: How consumers should adapt to breaking changes
- Feature flags: Documentation of runtime toggles that modify service behavior
- Architectural decision records: Significant decisions that shaped service design
8.5 Documentation as Code Approach
For microservices, integrating documentation with code is particularly valuable:
- README files: Maintain core documentation in the service repository
- API specifications: Define APIs in machine-readable formats like OpenAPI
- Infrastructure as code: Document deployment configurations through IaC tools
- Automated diagrams: Generate service visualizations from code or configuration
- Documentation pipelines: Validate and publish documentation during CI/CD
8.6 Practical Strategies for Microservices Documentation
To implement effective microservices documentation:
- Start with templates: Provide standard templates for service documentation
- Enforce API documentation: Make API contract definition mandatory before service deployment
- Implement service discovery: Use tools that combine runtime discovery with documentation
- Visualize the ecosystem: Maintain dynamic visualizations of the service landscape
- Document between services: Focus on interaction points between services
- Treat documentation as a product: Assign clear ownership for system-level documentation
By balancing standardization with autonomy, microservices documentation can support both independent service development and cohesive system understanding.
9. Architecture Decision Records (ADRs): What, Why, and How
Architecture Decision Records (ADRs) have emerged as one of the most valuable and lightweight approaches to architecture documentation. They capture the essence of significant architectural decisions in a concise, structured format.
9.1 What are ADRs?
ADRs are short documents that capture important architectural decisions along with their context and consequences:
- Focused: Each ADR addresses a single significant decision
- Concise: Typically 1-2 pages per decision
- Structured: Follows a consistent format for easy reference
- Immutable: Once approved, an ADR is not changed (though it can be superseded)
- Chronological: ADRs form a historical record of the architecture's evolution
9.2 Why Use ADRs?
ADRs provide numerous benefits with relatively low overhead:
- Preserve context: Capture not just what was decided, but why
- Foster deliberate design: Encourage thoughtful consideration of alternatives
- Reduce repeated discussions: Provide a reference point for decisions already made
- Support onboarding: Help new team members understand the reasoning behind the current architecture
- Enable auditability: Create a traceable history of architectural evolution
- Distribute decision-making: Allow teams to make and document decisions within their domains
9.3 Core Components of an ADR
A typical ADR includes these elements:
- Title: A descriptive name, often prefixed with a sequential number
- Status: Current state (proposed, accepted, rejected, superseded, deprecated)
- Context: The problem being addressed and relevant constraints
- Decision: The chosen approach, stated clearly
- Consequences: Both positive and negative implications of the decision
- Alternatives: Other options considered and why they weren't chosen
- Related decisions: Links to other ADRs that influenced or are affected by this decision
9.4 Implementing an ADR Process
To establish an effective ADR practice:
- Define your template: Adapt existing templates to your team's needs
- Start simple: Begin with major decisions; don't try to document everything
- Store with code: Keep ADRs in your version control system, close to the code they affect
- Define workflow: Establish a clear process for proposing, reviewing, and accepting ADRs
- Link to artifacts: Connect ADRs to related requirements, issues, or documentation
- Make discoverable: Ensure ADRs are easy to find and browse
9.5 Example ADR Template
# ADR-001: Use PostgreSQL for Primary Database
## Status
Accepted (2023-04-15)
## Context
Our application needs a reliable, scalable database solution with strong transactional capabilities. We anticipate complex queries and need strong data consistency. Our team has varied database experience levels.
## Decision
We will use PostgreSQL as our primary application database.
## Consequences
Positive:
- Strong ACID compliance supports our transactional requirements
- Advanced query capabilities support complex reporting needs
- Open-source with strong community and commercial support options
- Good ORM support across multiple languages
Negative:
- Requires more operational expertise than managed NoSQL alternatives
- Some team members will need training
- Horizontal scaling is more complex than with some NoSQL options
## Alternatives Considered
1. MongoDB: Rejected due to weaker transactional guarantees and less fit for our relational data
2. MySQL: Viable alternative, but PostgreSQL offers superior JSON support and extensibility
3. Cloud-specific managed SQL: Avoided to prevent vendor lock-in
## Related Decisions
- ADR-002: Database Migration Strategy
9.6 Using ADRs Effectively
To get the most value from ADRs:
- Be selective: Document significant decisions with long-term impact
- Keep it brief: Aim for clarity and conciseness
- Review collectively: Use ADRs as a tool for collaborative decision-making
- Reference externally: Point to detailed resources rather than including them
- Evolve your practice: Refine your ADR process based on what works for your team
ADRs represent one of the highest-value, lowest-overhead documentation practices available to architecture teams. By focusing on capturing the essential context and reasoning behind key decisions, they preserve critical knowledge without generating excessive documentation.
10. Documenting APIs and Interfaces in Large Systems
In complex systems, interfaces between components are critical points that require clear documentation. Well-documented APIs enable independent development, facilitate integration, and support system evolution.
10.1 API Documentation Fundamentals
Regardless of specific technologies, effective API documentation includes:
- Purpose and scope: What the API is for and what it's not for
- Authentication and authorization: How to securely access the API
- Request/response formats: The structure of data exchanged
- Error handling: How errors are communicated and should be interpreted
- Rate limits and performance: Usage constraints and expected behavior
- Versioning policy: How the API evolves and maintains compatibility
- Examples: Concrete illustrations of API usage
10.2 Technology-Specific Approaches
Different interface technologies require different documentation approaches:
RESTful APIs
- Use OpenAPI/Swagger specification for machine-readable documentation
- Document resource models and their relationships
- Clearly explain HTTP verbs, status codes, and headers
- Provide pagination, filtering, and sorting conventions
- Include sample requests and responses for typical scenarios
GraphQL APIs
- Document schema using GraphQL's introspection capabilities
- Explain object types, queries, mutations, and subscriptions
- Provide guidance on query optimization and depth limitations
- Document directives and their effects
- Include sample queries that demonstrate best practices
Event-Driven Interfaces
- Document event schemas and payload structures
- Clarify event ordering guarantees and delivery semantics
- Explain subscription/consumption patterns
- Document error handling and dead-letter strategies
- Provide schema evolution guidelines
Internal Component APIs
- Document method signatures and parameter constraints
- Clarify threading and concurrency expectations
- Explain state management and side effects
- Document performance characteristics and resource usage
- Provide initialization and cleanup requirements
10.3 Documentation as Code for APIs
Integrating API documentation with development processes ensures accuracy:
- Generated documentation: Use tools to create docs from code annotations
- Contract testing: Verify that documentation matches implementation
- Automated examples: Generate example requests and responses through tests
- Documentation versioning: Align documentation versions with API versions
- Interactive exploration: Provide sandbox environments for trying APIs
10.4 Beyond Functional Documentation
Comprehensive API documentation addresses non-functional aspects:
- SLAs and performance expectations: What consumers can expect
- Security considerations: Authentication, authorization, and data protection
- Monitoring and observability: Available metrics and logs
- Resilience patterns: Circuit breakers, fallbacks, and failure modes
- Compliance requirements: Regulatory considerations when using the API
10.5 Managing Interface Documentation at Scale
For large systems with many interfaces:
- Consistency: Establish organization-wide standards for API documentation
- Discoverability: Implement a central API catalog or portal
- Governance: Define review processes for interface changes
- Audience-specific views: Provide different documentation views for different roles
- Feedback mechanisms: Gather and incorporate consumer input
10.6 Practical Tips for Interface Documentation
To create more effective interface documentation:
- Document from the consumer perspective: Focus on what API users need to know
- Use visual representations: Include sequence diagrams for complex interactions
- Distinguish between public and internal interfaces: Apply appropriate documentation levels
- Link to implementation: Connect documentation to the actual code
- Update documentation in the same PR as code changes: Keep docs and implementation synchronized
Well-documented interfaces are essential for system maintainability and evolution. By treating interface documentation as a first-class concern, teams can reduce integration friction and support the independent development of system components.
11. Keeping Architecture Docs Up-to-Date Without Pain
Maintaining documentation currency is perhaps the greatest challenge in architectural documentation. Out-of-date documentation is worse than no documentation, as it misleads rather than informs. Here are effective strategies to keep architecture documentation current with minimal effort:
11.1 Minimizing Documentation Debt
The first step to maintainable documentation is creating only what's truly needed:
- Document just enough: Focus on high-value, difficult-to-infer aspects
- Single source of truth: Avoid duplication across documentation artifacts
- Automate where possible: Generate documentation from code, configuration, or other authoritative sources
- Reference external resources: Link to external documentation rather than copying information
11.2 Documentation as Code
Treating documentation like code brings software engineering discipline to documentation maintenance:
- Version control: Store documentation in the same repository as the code it describes
- Code reviews: Include documentation updates in pull request reviews
- CI/CD integration: Automate documentation building, testing, and publishing
- Linting and validation: Check documentation for consistency and completeness
- Branches and releases: Align documentation versions with software versions
11.3 Living Documentation Approaches
Some documentation can be generated or updated automatically:
- API documentation from code: Generate interface documentation from annotated code
- Architecture diagrams from configuration: Create deployment diagrams from infrastructure-as-code
- Dependency documentation: Generate component relationship diagrams from actual dependencies
- Runtime documentation: Document actual system behavior through monitoring and observability tools
- Database schema documentation: Generate data model documentation from database schemas
11.4 Documentation Ownership and Processes
Clear responsibilities and lightweight processes support documentation maintenance:
- Documentation owners: Assign clear ownership for different documentation areas
- Documentation reviews: Include documentation updates in architectural reviews
- Doc days: Schedule periodic team sessions focused on documentation updates
- Definition of Done: Include documentation updates in task completion criteria
- Feedback channels: Make it easy to report documentation issues
11.5 Just-in-Time Documentation
Some documentation is better created when needed rather than maintained continuously:
- On-demand diagrams: Create diagrams for specific discussions or reviews
- Recorded presentations: Capture architectural explanations as videos
- Architectural decision records: Document decisions as they're made
- Wiki pages: Allow collaborative, evolving documentation for rapidly changing areas
- Chat transcripts: Preserve important architectural discussions from chat tools
11.6 Deprecation and Archiving
Not all documentation needs to be maintained forever:
- Clear lifecycle: Define when documentation should be updated, archived, or deleted
- Visible status: Mark documentation with its current status (current, outdated, archived)
- Version indicators: Show clearly which system version the documentation describes
- Expiration dates: Consider adding "review by" dates to documentation
- Automated warnings: Flag potentially outdated documentation based on last update date
11.7 Practical Implementation Strategies
To implement these approaches in your team:
- Start with process: Integrate documentation updates into existing development workflows
- Invest in tools: Select documentation tools that support automation and collaboration
- Focus on key artifacts: Identify the most critical documentation to maintain
- Begin simply: Start with basic practices and evolve as team capability grows
- Measure usage: Track which documentation is actually used to focus maintenance efforts
The most successful teams view documentation maintenance not as a separate activity but as an integral part of software development. By applying software engineering principles to documentation and focusing efforts on high-value assets, teams can maintain current architecture documentation without excessive overhead.
Conclusion
Effective architecture documentation strikes a delicate balance—providing sufficient information to guide development without becoming a maintenance burden. The practices outlined in this guide help you create documentation that truly serves your team:
- Document with purpose, focusing on the needs of specific audiences
- Favor lightweight approaches like ADRs and C4 modeling
- Integrate documentation with code to keep it current
- Use visualization to communicate complex relationships
- Adapt documentation practices to your specific context
- Establish clear ownership and maintenance processes
Remember that the ultimate measure of documentation quality is not its comprehensiveness but its effectiveness in supporting the team's work. Documentation that isn't read or trusted fails regardless of its detail or accuracy.
By applying these best practices, you can create architecture documentation that serves as a valuable asset throughout your system's lifecycle—providing guidance, preserving knowledge, and supporting evolution without becoming an unsustainable burden.