Skip to content
ArchitectureFoundationsRequirementsTrade OffsDecision Making

Requirements, Constraints, Trade-offs & Compromise

Level:All levels — SA, EA, TS
Duration:1-day workshop
Deliverable:Trade-off framework + constraint register template + requirements classification guide

Quick Navigation


Before we start — the one thing to hold onto

Architecture isn't the art of the perfect design. It's the art of the best possible decision given three realities: what's required, what's constrained, and what must be sacrificed. I've seen architects seek the "best" solution without understanding the constraints — and deliver late, or deliver something the organisation can't use.

Architecture is fundamentally the discipline of informed compromise — making defensible choices, not perfect ones.

Every architect who seeks the "best" solution without understanding the constraints will either deliver late or deliver something the organisation can't use.

Keep it in mind.


1. What architecture really is — Requirements, constraints, and the art of compromise

Not all requirements are the same. Treating them the same leads to wrong priorities and missed expectations.

There are two fundamentally different types of requirements, and architects must separate them clearly.

Functional requirements define what the system must do: "The system must process orders." "Users must be able to search products." "Invoices must be generated monthly."

Non-functional requirements define how well the system must do it: "Orders must be processed within 2 seconds." "The system must handle 10,000 concurrent users." "Data must be encrypted in transit and at rest."

flowchart LR
    REQ["Requirements"] --> F["Functional\nWhat the system does"]
    REQ --> NF["Non-Functional\nHow well it does it"]

    F --> F_EX["Process orders\nSearch products\nGenerate invoices"]
    NF --> NF_EX["Performance\nScalability\nSecurity\nAvailability"]

The critical insight: Functional requirements determine features. Non-functional requirements determine architecture.

Requirements classification — separating what from how well — is the first architecture skill.

The problem with unclassified requirements: Unclassified requirements lead to mixed priorities — functional and non-functional treated equally. Non-functional requirements get missed in design. They're discovered late — in testing or production. Expensive to fix — architecture rework, delayed delivery.

How to classify requirements: Ask two questions for every requirement. Does it describe what the system does? → Functional. Does it describe how well it does it? → Non-functional. If the answer to both is no, it may be a constraint or assumption.

Functional = what. Non-functional = how well. Architecture is driven by the second.


Try it yourself — The classification test

Take five requirements from your current project. Classify each one:

Requirement Functional, non-functional, or constraint?

If you can't classify them, you can't prioritise them.


2. Constraints — Fixed limits that shape every decision

Not everything is negotiable. Some things are fixed — and architects who ignore constraints design solutions that can't be built.

Constraints are the boundaries within which architecture must operate. They're not preferences — they're limits.

Common constraints: Budget — how much money is available. Timeline — when it must be delivered. Existing systems — what already exists and can't be replaced. Regulations — what the law requires. Team skills — what the team can build and maintain. Technology — what platforms or vendors are mandated.

flowchart TD
    C1["Budget\nHow much?"] --> SPACE["Solution Space"]
    C2["Timeline\nWhen?"] --> SPACE
    C3["Existing Systems\nWhat stays?"] --> SPACE
    C4["Regulations\nWhat is required?"] --> SPACE
    C5["Team Skills\nWho builds it?"] --> SPACE
    C6["Technology\nWhat is mandated?"] --> SPACE

    SPACE --> ARCH["Architecture\nMust fit within\nthese boundaries"]

Constraint categories: Organisational — "We must use Azure." Negotiable, but slowly. Regulatory — "Data must stay in EU." Not negotiable. Technical — "Must integrate with legacy ERP." Negotiable with cost. Resource — "Team of 5 engineers." Negotiable, but not quickly. Temporal — "Must launch before Q4." Negotiable with consequences. Financial — "Annual budget is £500k." Negotiable with business case.

The architect's rule on constraints: Identify all constraints early — surprises late are expensive. Classify them — which are truly fixed, which are negotiable? Challenge assumptions — some "constraints" are just habits. Design within constraints — don't fight what you can't change. Negotiate what you can — with a business case, not just a preference.

Constraints define the solution space. Architecture must work within them — or negotiate to change them.


Try it yourself — The constraint register

What constraints are shaping your current architecture?

Constraint Category Fixed or negotiable? Impact on options

If you haven't identified your constraints, you're designing in a space that doesn't exist.


3. Competing priorities — When requirements conflict

Requirements conflict with each other. Speed conflicts with quality. Security conflicts with usability. Cost conflicts with performance.

When requirements conflict, someone must choose. If the architect doesn't make the choice explicit, the choice gets made implicitly — usually by whoever is loudest or most senior.

Common conflicts: Speed vs quality — ship fast or ship right? Security vs usability — secure systems are often harder to use. Performance vs cost — faster systems cost more. Flexibility vs simplicity — flexible systems are more complex. Innovation vs stability — new technology is risky.

flowchart LR
    SPEED["Speed to Market"] <-.->|"conflict"| QUALITY["Quality"]
    SECURITY["Security"] <-.->|"conflict"| USABILITY["Usability"]
    PERFORMANCE["Performance"] <-.->|"conflict"| COST["Cost"]
    FLEXIBILITY["Flexibility"] <-.->|"conflict"| SIMPLICITY["Simplicity"]

The conflict matrix:

Speed Quality Security Cost Usability
Speed — Tension Tension Aligned Aligned
Quality Tension — Aligned Tension Aligned
Security Tension Aligned — Tension Tension
Cost Aligned Tension Tension — Aligned
Usability Aligned Aligned Tension Aligned —

Resolution approach: Surface the conflict — make it explicit, not hidden. Identify stakeholders — who cares about each side? Prioritise — which requirement matters more here? Design the trade-off — optimise for the priority, accept the cost. Document the decision — why this trade-off was chosen.

Conflicts that aren't surfaced become surprises in production. Prioritisation requires stakeholders — the architect facilitates, the business decides. Documenting the trade-off (in an ADR) means future teams understand the decision was deliberate, not accidental. Some conflicts can be designed around — e.g., security AND usability through good UX design — but not all.

When requirements conflict, the architect's job is to surface the conflict and make the trade-off explicit. Conflicts are normal — the architect's job is to surface them, not hide them.


Try it yourself — The conflict surface

What requirements are in conflict in your current project?

Requirement 1 Requirement 2 Who cares about each? How are you resolving it?

If you haven't surfaced the conflicts, they're being resolved implicitly — and you're not in control.


4. Trade-off thinking — Why there's no perfect architecture

Teams search for the "best" architecture. There is no best. There is only the best for this context.

Trade-off thinking means accepting that every decision has a cost — and choosing the cost you're willing to pay.

The CAP theorem as an example: Consistency — every read gets the latest write. Availability — every request gets a response. Partition tolerance — the system works despite network failures. You can only pick two. There's no option that gives you all three.

flowchart TD
    CAP["CAP Theorem"] --> C["Consistency"]
    CAP --> A["Availability"]
    CAP --> P["Partition Tolerance"]

    C ---|"Pick 2"| A
    A ---|"Pick 2"| P
    P ---|"Pick 2"| C

The trade-off decision framework: Decision point → Option A (pros and cons), Option B (pros and cons), Option C (pros and cons) → Compare against: business goals, constraints, risk tolerance, future flexibility → Select: the option whose trade-offs best match the context → Document: the choice, the sacrifice, and the rationale.

Common architecture trade-offs:

Decision Option A Option B Trade-off
Data consistency Strong consistency Eventual consistency Latency vs accuracy
Deployment Monolith Microservices Simplicity vs independence
Integration Synchronous Asynchronous Simplicity vs resilience
Database SQL NoSQL Structure vs flexibility
Cloud Single cloud Multi-cloud Simplicity vs risk mitigation
API style REST GraphQL Standardisation vs query flexibility
Build vs buy Build Buy Control vs speed

Trade-offs are context-dependent — the right choice for a startup is different from the right choice for a bank. The CAP theorem is one example of a fundamental trade-off — many architecture decisions have similar irreducible tensions. Documenting trade-offs in ADRs means future teams understand what was sacrificed and why. Trade-off analysis is what separates architecture from technology selection.

Trade-offs aren't failures of design. They're the substance of architecture. There's no perfect architecture — only the right trade-offs for this context.


Try it yourself — The trade-off analysis

Take your next architecture decision. What are the options? What does each cost?

Option What you gain What you sacrifice Is the cost acceptable?

If you can't name the sacrifice, you haven't done a trade-off analysis. You've picked a favourite.


5. The art of compromise — Defensible choice, not popular choice

After identifying requirements, constraints, conflicts, and trade-offs — you must still decide. And the decision won't satisfy everyone.

Compromise isn't about making everyone happy. It's about making the best decision for the whole — and explaining why.

Principles of good compromise: Defensible — you can explain why, with evidence. Documented — future teams understand the decision. Revisitable — the decision can be revisited when context changes. Communicated — affected stakeholders understand the trade-offs. Proportional — the effort of deciding matches the significance of the decision.

flowchart LR
    ALL["All Requirements"] -->|"cannot all be met"| CONFLICT["Conflict"]
    CONFLICT --> DECIDE["Architect decides"]
    DECIDE --> COMPROMISE["Compromise\nBest option for the whole,\nnot perfect for anyone"]

    COMPROMISE --> DEFENSIBLE["Defensible\nWith evidence"]
    COMPROMISE --> DOCUMENTED["Documented\nADRs"]
    COMPROMISE --> COMMUNICATED["Communicated\nTo affected stakeholders"]

What makes a good compromise: Defensible — supported by evidence, not just opinion. "We chose eventual consistency because our availability SLA requires 99.99% uptime." Documented — recorded for future reference. ADR with context, options, decision, consequences. Proportional — effort matches significance. Don't write a 10-page document for a reversible decision. Revisitable — can be changed when context changes. Include conditions for revisiting in the ADR. Communicated — stakeholders understand the trade-off. Not just "we decided X" but "we decided X, sacrificing Y, because Z."

The architect's compromise checklist: Have I identified all the conflicting requirements? Have I classified constraints correctly? Have I evaluated trade-offs explicitly? Is my decision defensible with evidence? Have I documented the rationale? Have I communicated the trade-off to affected stakeholders?

Compromise is the output of the entire requirements → constraints → trade-offs pipeline. ADRs are the mechanism for documenting compromise. Good compromise requires stakeholder alignment — understanding who cares about each side. Compromise isn't weakness — it's the architect's core skill.

Compromise = defensible choice, not popular choice.


Try it yourself — The compromise check

Take your last architecture decision. Run it through the checklist:

Question Your answer
Is it defensible with evidence?
Is it documented?
Is it proportional to the significance?
Is it revisitable when context changes?
Have affected stakeholders understood the trade-off?

If any answer is "no," your compromise isn't complete.


6. Documenting decisions — So compromises are understood, not forgotten

Decisions that aren't documented become tribal knowledge — debated again six months later by people who weren't in the room.

Documenting decisions means capturing the context, options, choice, and consequences — so that future teams understand not just what was decided, but why.

What documentation provides: Context — what was the situation when this was decided? Options — what alternatives were considered? Decision — what was chosen? Rationale — why was it chosen? Consequences — what does this decision enable and constrain? Revisit conditions — when should this decision be reconsidered?

The minimal decision document:

Field Purpose Example
Title What was decided "Use event-driven integration for order processing"
Status Current state Proposed / Accepted / Deprecated / Superseded
Context Why this decision was needed "Synchronous integration cannot handle peak load"
Options What was considered Option A: Async messaging. Option B: Polling. Option C: Batch.
Decision What was chosen "We will use Apache Kafka for event-driven integration"
Consequences What this enables and constrains "Enables: scalability. Constrains: team needs Kafka skills. Cost: infrastructure."
Revisit When to reconsider "Revisit if peak load exceeds 10x current or if Kafka licensing changes"

When to document: Decision made → Is it significant? No — trivial → don't document. Yes → document in ADR. Will it be questioned later? Yes → full ADR, all fields. Maybe → lightweight ADR, decision + rationale only.

Architecture documentation isn't bureaucracy — it's the memory of the system.

Document decisions so compromises are understood, not forgotten.


Try it yourself — The documentation test

Think of a decision your team made six months ago. Can you find the documentation?

Question Your answer
What was decided?
Why was it decided?
What alternatives were considered?
When should it be revisited?

If you can't answer these, the decision is tribal knowledge. It's already being re-debated.


Putting it all together

Here's the complete picture in one diagram. This is the mental model worth internalising.

flowchart TD
    F["Functional Requirements\nWhat the system does"] --> PIPELINE["Architecture Decision Pipeline"]
    NF["Non-Functional Requirements\nHow well it does it"] --> PIPELINE
    C["Constraints\nWhat cannot change"] --> PIPELINE

    PIPELINE --> CONFLICT["Conflict Analysis\nWhat contradicts?"]
    CONFLICT --> TRADE["Trade-off Analysis\nWhat does each option cost?"]
    TRADE --> PRIORITISE["Prioritisation\nWhat matters most?"]
    PRIORITISE --> COMPROMISE["Compromise\nBest decision for the context"]
    COMPROMISE --> DOCUMENT["Document\nADRs, rationale, consequences"]

The foundation:

Classify requirements — functional (what) vs non-functional (how well) vs constraints (what can't change); architecture is driven by the last two. Conflicts are normal — requirements contradict each other; the architect's job is to surface the conflict and make the trade-off explicit. Compromise is the craft — there's no perfect architecture; document the choice, the sacrifice, and the rationale. Architecture is the discipline of informed compromise — making defensible choices, not perfect ones.


Cheat Sheet — All the key terms

Concept One-Line Memory Key Action
Functional requirements What the system does Capture and clarify with stakeholders
Non-functional requirements How well it does it Specify measurably — these drive architecture
Constraints What cannot change Identify early, classify by negotiability
Competing priorities Requirements that conflict Surface conflicts, don't hide them
Trade-offs What each option sacrifices Evaluate explicitly — no hidden costs
Compromise Best decision for the context Make it defensible, document it, communicate it
Decision documentation Memory of the system ADRs with context, options, rationale, consequences

How to know if this landed

You'll know this has landed when someone stops treating all requirements equally and starts classifying them as functional, non-functional, or constraint. Can classify requirements as functional, non-functional, or constraint. Identifies conflicts between requirements before design begins. Evaluates trade-offs explicitly — not just picking a favourite. Documents decisions with rationale, not just outcomes. Communicates trade-offs to stakeholders — what is gained and what is sacrificed. And challenges assumptions about constraints — with evidence, not opinion.


What changes when the mental model clicks

I've run this session with a healthcare platform modernisation where regulatory constraints (HIPAA, GDPR) were treated as afterthoughts. Requirements were a single undifferentiated list — 200+ items with no classification. Teams designed for functional requirements and discovered non-functional gaps in testing. Decisions were made in meetings with no documentation — re-debated quarterly. The gap at the start is usually not about understanding trade-offs — it's about not classifying requirements and surfacing conflicts.

What changes after this session:

Teams stop treating all requirements equally and start classifying them. The conflict analysis exercise — "what requirements contradict each other?" — is always the moment things click. People stop hiding conflicts and start surfacing them. Their results get better. They stop discovering non-functional gaps in testing when the real problem was that they hadn't classified requirements.

The trade-off analysis exercise tends to immediately change how teams make decisions. They start naming the sacrifice for each option. Their decision quality goes up. They stop picking favourites when the real problem was that they hadn't evaluated the costs.


Book a Workshop

Ready to build requirements and trade-off skills in your teams?

→ Book a Training Session

or

→ Contact me directly

1-day workshop includes requirements classification exercise with real project requirements, constraint identification and negotiation workshop, conflict analysis and trade-off evaluation practice, compromise decision framework for your context, lightweight ADR creation for real decisions, and trade-off framework + constraint register template + requirements classification guide.

Related Trainings

What Architecture Is
All levels — SA, EA, TS3-4 hoursArchitecture definition canvas + what it is / what it isn't reference card

What software and enterprise architecture actually is — its structure, relationships, and decisions — and what it is not. No diagrams. No jargon. Just clarity.

Half-dayIntensive
FoundationFor all roles
How Architects Think
All levels — SA, EA, TS5-6 hoursSystems thinking toolkit + abstraction ladder + decision heuristics reference card

The cognitive toolkit of architecture — systems thinking, abstraction, balancing business and technical concerns, deciding under uncertainty, and trade-off thinking. Builds the mindset, not just the knowledge.

1 DayIntensive
MindsetNot just methods

Next Step

Run this with your team

Every programme is adapted to your context before delivery — your systems, your constraints, your decisions. A short call is enough to work out the right shape and scope.