Learnixo

Becoming a Tech Lead · Lesson 2 of 5

Making Technical Decisions — Frameworks and Trade-offs

What Makes a Technical Decision Hard

Easy decisions: clear best option, low stakes, easily reversed
  → Which logging library? Serilog. Done.

Hard decisions: significant trade-offs, high stakes, hard to reverse
  → Modular monolith vs microservices for the clinical platform?
  → SQL Server vs PostgreSQL for the prescription database?
  → Build a custom rules engine vs buy a third-party one?

Hard decisions require:
  → Explicit trade-off analysis (not just picking what you're familiar with)
  → Stakeholder input (the decision affects more than just you)
  → Documentation (future team members need to understand why)
  → Reversibility assessment (how bad is it if we're wrong?)

The cost of a wrong decision is not the cost of the decision —
it's the cost of undoing it and doing the right thing.
A reversible wrong decision is fine. An irreversible wrong decision is very expensive.

The Reversibility Framework

Before every significant technical decision, ask:
  → If this turns out to be wrong, how hard is it to change?
  → How long would it take? How disruptive?

Type 1 decisions (irreversible or very costly to reverse):
  → Choice of programming language / framework
  → Database type and schema design
  → API contracts exposed to external consumers
  → Data model decisions that require migration
  Approach: slow down, get more input, document extensively, pilot first

Type 2 decisions (reversible with reasonable effort):
  → Which logging library
  → Internal service API shape (internal consumers only)
  → Caching strategy
  → Build tool or CI configuration
  Approach: decide and move — don't over-deliberate. Record the choice.

Type 3 decisions (easily reversed — try it):
  → Code organisation within a module
  → Variable and method naming
  → Test structure
  Approach: just do it, refactor later if needed.

Most tech lead decisions are Type 2.
Reserve heavy deliberation for Type 1.
The mistake is treating all decisions as Type 1 — this creates analysis paralysis.

Decision Framework: Structured Trade-off Analysis

For Type 1 decisions — work through these five questions:

1. What is the problem we are solving?
   State it precisely. "The system is slow" is not a problem statement.
   "Prescription list queries take 8 seconds at 200 concurrent users" is.

2. What are the options?
   List 2–4 real options. Include "do nothing" if that's viable.
   Don't list 10 options — if there are 10, you haven't done enough analysis.

3. What are the evaluation criteria?
   Match them to the problem and context:
   - Clinical system: safety, auditability, data integrity are high priority
   - Startup: time-to-market may outweigh ideal architecture
   - NHS project: compliance with NHS Digital standards is mandatory

4. Assess each option against the criteria:
   Use a simple matrix — high/medium/low, or scores 1–5.
   Be explicit about assumptions. "PostgreSQL is faster" — under what conditions?

5. Recommendation + rationale:
   State which option you recommend and why.
   State what would change your recommendation (the conditions under which you'd pick differently).

Example for a clinical system: "Modular Monolith vs Microservices"
  Criteria: team size (3 engineers), deployment simplicity, data consistency requirements
  Assessment: microservices add distributed system complexity beyond the team's current capacity
  Recommendation: modular monolith now, with clear module boundaries to enable extraction later
  Condition that would change this: team grows to 10+, or modules need independent scaling

Writing an Architecture Decision Record

MARKDOWN
# ADR-012: Use Modular Monolith Architecture for Clinical Platform v1

**Status:** Accepted  
**Date:** 2026-03-15  
**Deciders:** Asma Hafeez Khan (Tech Lead), Dr. Sarah Chen (Product), James Wu (Engineering Manager)

## Context

We are building ClinicalRx v1 with a team of 4 engineers.
The system manages prescription workflows for 3 hospital wards (~180 patients).
Initial user base: 25 pharmacists and 12 ward nurses.

Microservices were considered based on prior team experience at larger organisations.

## Decision

We will implement a modular monolith with clearly bounded modules:
Prescriptions, Patients, Labs, Notifications, and AuditLog.

Each module owns its schema (separate SQL schema per module).
Cross-module communication uses module events via in-process pub/sub.
Modules can be extracted into services later without logic changes.

## Consequences

**Positive:**
- Single deployment unit  simpler CI/CD and operational overhead
- No distributed transaction complexity for prescription + audit log writes
- Team can refactor without cross-service coordination
- Easier debugging and tracing  single process

**Negative:**
- All modules must be deployed together  one bug can affect unrelated modules
- Cannot scale individual modules independently
- Shared database server  I/O from one module can affect others

## Revisit When

- Team size exceeds 8 engineers with clear ownership boundaries
- Labs module requires independent scaling (high-volume INR processing)
- Compliance requires physical data separation between modules

Presenting Decisions to Stakeholders

Clinical system stakeholders who need different things:

Clinical staff (nurses, pharmacists):
  → Care about: will this make my workflow faster or safer?
  → Don't care about: which database, which cloud provider
  → How to present: "The new search means you'll find patient prescriptions in 2 seconds
     instead of 8 seconds. It also means we can add drug interaction warnings without
     slowing down the page."

Engineering leadership:
  → Care about: risk, cost, timeline, team capability
  → How to present: use the ADR format. Lead with recommendation.
    "We recommend PostgreSQL over SQL Server for the following reasons:
     lower licensing cost at scale, better performance for our vector search use case,
     and team experience. The main risk is operational — the team has less SQL Server
     expertise in the team. We mitigate this by using Azure Database for PostgreSQL
     (managed service)."

Product manager:
  → Care about: delivery date impact, feature implications
  → How to present: "This decision adds 2 weeks to the first milestone because we need
     to set up a new database type. The benefit is it unblocks the AI search feature
     that's on the roadmap without additional licensing cost."

What to avoid:
  → Technical jargon without explanation
  → "Trust me, it's better" — always give a reason
  → Presenting a decision as already made when you need input
  → Glossing over the downsides — stakeholders will find them eventually

When to Escalate vs Decide

Escalate when:
  → The decision has significant budget implications (e.g., new cloud service contracts)
  → The decision will affect timelines stakeholders have committed to
  → You and another senior engineer have a genuine disagreement you can't resolve
  → The decision touches compliance or regulatory requirements (clinical systems)
  → You are 50/50 and would do a coin flip — that uncertainty is worth surfacing

Decide without escalating when:
  → It's within your delegated authority (code organisation, library choices)
  → You have enough information and experience
  → The cost of delay (waiting for approval) exceeds the cost of being wrong
  → The decision is reversible

The mistake most new tech leads make:
  Escalating too much — asking for permission on decisions within their authority.
  This signals uncertainty and slows the team.

The mistake confident tech leads sometimes make:
  Not escalating decisions that need stakeholder buy-in.
  Making a significant technical change without informing product/engineering
  leadership — creates trust problems even if the decision was correct.

Ask yourself: "If this turns out wrong, would my manager say
  'you should have told me about this before deciding'?"
  If yes — tell them first.

Production issue I've seen: A tech lead decided to switch the clinical platform's event store from SQL Server to PostgreSQL during a sprint — without writing an ADR, without informing the product manager or engineering lead, and without assessing the migration cost. The reasoning was sound (pgvector for future AI search). But the migration ran into licensing issues with the Azure region, required 3 weeks of unplanned work, delayed a regulatory submission, and created friction with the product team who had committed to a release date. The tech decision itself was probably correct — but the lack of process around it caused significant damage. Significant technical decisions need process: document, communicate, get input, then decide.


Key Takeaway

Technical decisions need to be proportionate to their reversibility — deliberate slowly on Type 1 decisions (hard to reverse), decide quickly on Type 2 (reversible with effort). Use a five-question trade-off framework for significant decisions and record them as ADRs. Present decisions differently to different stakeholders: clinical staff care about workflow impact, engineering leadership cares about risk and timeline, product cares about delivery dates. Escalate decisions with significant budget, compliance, or timeline implications — but don't escalate decisions that are within your delegated authority. Document your reasoning: future team members will need to understand why, not just what.