Software Architecture
A Practical Software Architecture Review Checklist
A useful architecture review tests whether important promises survive real load, failure, change and operation. It examines evidence and trade-offs-not whether a diagram contains fashionable components.

Review the decisions, not the diagram
An architecture review is not a tribunal held shortly before launch. Its purpose is to expose expensive assumptions while there is still time to change them. The output should be decisions, risks, experiments and owners-not a generic approval stamp.
A tidy component diagram can hide the issues that determine production success: ambiguous data ownership, cross-tenant caches, a slow dependency inside a transaction, unrehearsed recovery or one person holding deployment access. Conversely, an unfashionably simple design may be exactly right for a narrow workload and small team.
Begin by identifying consequential choices and the constraints behind them. If reviewers do not know the required availability, data sensitivity, team capability, workload shape and cost boundary, they can only review personal preferences.
Establish the business promises first
Ask which user journeys matter, what failure costs, which obligations are non-negotiable and how success is measured. “The platform must be scalable and secure” contains no reviewable promise. “Process 95% of submissions within two minutes, preserve evidence for seven years and recover within four hours” does.
Separate service objectives from aspirations. Identify recovery time and recovery point needs, data residency, accessibility, audit and privacy constraints. Name the expected lifetime and change rate: a three-month internal tool and a ten-year regulated platform should not carry the same machinery.
Check that the architecture covers exception journeys as well as the happy path. Cancellation, correction, duplicate submission, supplier outage and permission change often reveal the real domain.
Trace one important journey end to end
Follow identity, tenant context, data and failure through browser, API, storage, queues and external services. Mark trust boundaries and transaction boundaries. Ask what the user sees at every uncertain state and how support later reconstructs it.
Repeat the exercise for timeout after a remote write, duplicate delivery, stale cache, deployment overlap and restoration from backup. This is not generic ceremony: concrete failure paths expose assumptions that boxes and arrows omit.
Architecture reviews become useful when claims turn into evidence. A load test supports a capacity assumption; a threat model supports security priorities; a restore rehearsal supports recovery. “The cloud handles it” supports nothing.

Boundaries should reduce change, not imitate an organisation chart
For each module or service, ask what responsibility it owns, which data it controls and why it changes independently. Boundaries that repeatedly require coordinated deployments are probably not buying autonomy. Boundaries drawn around shared database tables are not ownership boundaries.
Distribution creates network failure, versioning, identity propagation, observability and deployment cost. Require a specific benefit such as independent scaling, isolation or team ownership before accepting it. A modular application is often the stronger starting point because it preserves conceptual boundaries without paying every distributed-systems tax.
Check dependency direction. Domain policy should not depend on transport DTOs or a supplier SDK. External systems belong behind adapters that translate their optionality and terminology into internal meaning.
Data ownership is more important than database choice
Identify the authoritative source for each important fact and who may change it. Shared writes across services destroy autonomy even when each service has its own schema. Replicated data needs freshness, reconciliation and deletion rules.
Review invariants and transaction boundaries. If an operation must update several stores, understand the states visible during partial completion. “Eventually consistent” is not a recovery plan; define how divergence is detected, presented and repaired.
Examine lifecycle: classification, minimisation, retention, export, deletion, backup and restore. Data often survives the interface and team that created it. Schema choices should preserve meaning, provenance and historical interpretation rather than only current display needs.
Identity is not authorisation
Review how interactive users, services, devices and background jobs establish identity. Then separately trace how each action is authorised against resource, tenant and context. A valid token or an “Admin” role is not proof of access to every record.
Look for tenant identifiers accepted from untrusted clients, permission checks only in the interface, support bypasses and caches missing security scope. Privileged operations should be narrow, attributable and reviewed. Secrets need managed storage, rotation and a plan for compromise-not values copied into deployment variables forever.
Threat-model abuse as well as intrusion: enumeration, bulk export, automated signup, oversized uploads and expensive queries. Rate limiting is a business and fairness control, not only denial-of-service protection.
APIs are contracts even when called “internal”
Review resource semantics, validation, idempotency, error contracts, pagination and compatibility. An internal API used by two independently released components already has consumers. Generated clients make calling easier; they do not decide how evolution remains safe.
Do not expose database entities directly. Separate transport contracts from persistence and domain models so each can evolve for its own reason. Validate successful responses from external providers as rigorously as incoming requests.
For asynchronous contracts, version messages and design consumers for at-least-once delivery. Event names should describe facts that happened, not commands disguised in the past tense. Keep enough metadata to trace the logical operation without copying sensitive payloads everywhere.
Performance reviews need a workload model
Ask for request rate, concurrency, data volume, object size, burst pattern and growth assumptions. Average response time and average traffic hide the tails that exhaust resources. Specify percentile targets for complete journeys under stated load.
Find serialized bottlenecks, unbounded queries, chatty remote calls and large in-memory materialisation. Caching can reduce latency and cost but introduces staleness, invalidation and tenant-isolation risk. Every cache needs a correctness policy, not just an expiry.
Capacity testing should include dependency slowdown and realistic data distributions. A test with empty tables and zero network latency validates very little. Define which signals trigger scaling and which resource will become the next bottleneck.
Resilience controls must preserve business correctness
Timeouts bound waiting but can leave remote write outcomes unknown. Retries help only transient faults and safe operations. Circuit breakers protect capacity but do not complete customer work. Queues absorb bursts but require idempotency, backpressure and poison-message operations.
Review total deadlines across layers so nested retries cannot exceed the user's patience or duplicate load exponentially. Define degraded behaviour by capability: stale reference data may be acceptable; stale permission or account decisions may not.
Require reconciliation for cross-system state. Unknown payments, bookings or submissions need stable operation identifiers and a repair process. Manual repair should be authorised and audited rather than performed through ad hoc database edits.
Deployment safety is part of the design
Ask how the system changes while traffic and background work continue. Database migrations should tolerate old and new application versions during rollout. Queued messages can outlive the deployment that produced them. Feature flags need owners and removal conditions.
Prefer small reversible releases, health checks that test readiness rather than mere process life, and progressive exposure where risk warrants it. Rollback may be impossible after an irreversible data change, so distinguish application rollback from business-state recovery.
Review configuration and infrastructure as versioned artefacts. Manual production differences make incidents harder to reproduce and recovery dependent on memory. Verify that secrets are not embedded in those artefacts.
Availability claims require recovery evidence
Redundancy is not recovery. Replication can faithfully copy corruption and accidental deletion. Define failure domains, backup isolation, restore sequence and the credentials required during an incident.
Run restore exercises that validate recovery time, data integrity and application compatibility. Test what happens to queued work, external callbacks and tenant data created around the restore point. A successful database restore may still leave the business inconsistent.
Clarify ownership during incidents: who declares severity, communicates with users, makes risky recovery decisions and records follow-up actions? Architecture without operating authority is incomplete.
Observability should answer operational questions
Logs, metrics and traces should reveal a user's journey across boundaries with correlation and tenant context. Avoid sensitive payloads and uncontrolled high-cardinality labels. More telemetry is not automatically more insight.
Measure business progression as well as infrastructure: queue age, submissions awaiting reconciliation, failed document processing and permissions changed. A green CPU graph can coexist with stopped customer work.
Alerts should be actionable, owned and tied to impact or exhausted recovery capacity. Ask for runbooks and safe administrative tools. If ordinary diagnosis requires production database access by the original developer, operability has not been designed.
Cost and team capability constrain the architecture
Review unit economics: cost per transaction, tenant, stored document or analysed page. Autoscaling protects throughput but can accelerate an inefficient workload's spend. Set budgets, quotas and attribution before a noisy customer becomes a financial incident.
Also count cognitive load. Every datastore, messaging system and deployment unit requires knowledge, upgrades and on-call support. Architecture must fit the team expected to operate it, not the team imagined on a future organisation chart.
Build-versus-buy decisions should include exit and concentration risk. Managed services remove undifferentiated operation but create contracts, cost curves and migration considerations. Record why the trade is acceptable.
Turn findings into owned decisions
Classify findings by impact and evidence, not reviewer seniority. Distinguish launch blockers, accepted risks, experiments and later improvements. Give each an owner and date. An unowned recommendation is meeting output, not risk control.
Record major decisions with context, alternatives and consequences. The aim is not to prove the architecture eternally correct; it is to let future maintainers see which assumption justified it and what evidence should trigger review.
Schedule reviews around change: after discovery reduces uncertainty, before irreversible commitments, ahead of critical migration and when workload or regulation changes materially. A single gateway review encourages teams to hide uncertainty until passing the gate.
The concise review checklist
- Are business promises and failure costs measurable?
- Do boundaries have clear responsibility and data ownership?
- Are invariants and partial states explicit?
- Is authorisation enforced against resource and tenant context?
- Can contracts evolve across deployment overlap?
- Does the performance model include tails and realistic data?
- Are retries, queues and fallbacks safe for each operation?
- Can releases and data changes be reversed or recovered?
- Have backups been restored and reconciled?
- Can operators diagnose business journeys safely?
- Are unit cost and team cognitive load sustainable?
- Does every significant finding have an owner?
The strongest architecture review does not ask whether the system resembles an ideal reference diagram. It asks whether the design's promises remain true when reality supplies concurrency, failure, organisational change and the next five years of maintenance.