11 Oct 2026

Software Architecture and Technical Debt: Making Maintainable Decisions

Review application boundaries, tenant isolation, rendering choices, decision records, technical debt and documentation before committing to a design.

Software Architecture and Technical Debt: Making Maintainable Decisions

Software architecture is the arrangement of responsibilities, data and dependencies in an application. A useful architecture supports the business tasks and the team's ability to operate and change the system. A fashionable pattern is a poor substitute for understanding those requirements.

This guide helps business owners discuss structure, technical debt and decision records with a development team. It focuses on the consequences of a choice rather than treating a particular technology as an automatic improvement.

Draw the responsibilities before choosing a pattern

Identify the main functions, their data owners and the connections between them. For a booking application, availability, customer details, payment state and notifications may have different responsibilities even when they run within one application. Establish which component can change each important record.

Include external services and manual work. A diagram that ends at an API acknowledgement may omit the staff process needed when a request fails. Draw the exception route and the support owner alongside the normal flow, so the business can assess the whole service.

Compare a single application with separate services

A monolithic application packages substantial functionality together. It can still have clear internal modules and well-defined boundaries. Separate services can be deployed and operated independently, but they introduce network calls, distributed failures and additional operational work.

Compare the need for independent changes and scaling with the team's monitoring, deployment and incident-response capability. A small business may benefit from a carefully organised single application. A more complex service arrangement needs a reason grounded in actual dependencies and delivery needs.

Define tenant boundaries explicitly

In a shared business application, a tenant often represents an organisation or customer group, rather than an individual user. Define that meaning for your system. A person belonging to more than one organisation may require separate permissions and an explicit choice of context.

Isolation choices affect cost, access, performance and recovery. Separate databases, shared tables and separate infrastructure have different consequences. Test that records cannot cross the agreed tenant boundary, including reports, exports, background jobs and support tools. A filtered list alone does not establish isolation.

Choose how pages and data are produced

Some pages are produced ahead of a request, while others are assembled when a visitor requests them. Consider how frequently the information changes, whether it is personal and how publication is triggered. A brochure page and a live account balance have different freshness requirements.

Document caching and invalidation alongside the rendering choice. An application can return a technically successful response containing stale information. Identify which changes must appear immediately, which can wait and how the team will verify that the intended version reaches visitors.

Record significant decisions and their consequences

An architecture decision record captures the problem, options considered, decision, status and consequences. Include disadvantages and unresolved risks. For example, choosing a shared database might simplify initial operations while making independent tenant recovery harder.

Name the owner and the people who reviewed the decision. Preserve accepted records as history; when circumstances change, create a replacement decision and identify the earlier one it supersedes. This prevents a later team from mistaking an old choice for an unexplained rule that can never be reconsidered.

Make technical debt specific

Technical debt describes internal weaknesses that make later changes harder. Record observable examples, such as duplicated validation rules or an untested integration that requires manual checking after every release. Do not use the label for every disliked feature or postponed business request.

Assess the affected work, risk and likely improvement, acknowledging uncertainty in estimates. Prioritise recurring friction in areas the team changes frequently. A stable component with little effect on delivery may be less urgent than a small problem that disrupts every customer-facing change.

Separate refactoring from changed behaviour

Refactoring improves internal structure while preserving intended observable behaviour. Adding a new approval rule is a behaviour change, even if the same work also tidies code. State which outcome is expected and maintain checks that can show whether it has been preserved.

Use proportionate increments with reviewable results. Agree what usable and verified means for the project rather than borrowing a process label as evidence of completion. A demonstration should show the relevant business task, exceptions and remaining operational limitations.

Maintain documentation people can use

  • Provide a current overview of responsibilities and dependencies.
  • Keep practical operating instructions separate from conceptual explanations.
  • Record reference details such as configuration and interface contracts.
  • Assign owners and review dates to important documents.
  • Retire or clearly supersede instructions that no longer apply.

Review the architecture when business requirements or operating conditions change. Our software requirements guide helps define those inputs. Giraffe Digital's digital strategy service can connect architectural choices with a realistic roadmap and the organisation's capacity to maintain the result.

Technology