Making software architecture decisions long before scaling became needed 'yesterday'
A case study from Aijutsu — the founder-led, coaching-informed, AI-leveraged technology practice serving Singapore founders and SMEs. We led this work in a Head-level appointment at the client, whose identity is withheld under confidentiality. Companion studies describe the platform build, the multi-region expansion, and how deployment was made routine.
- Client
- A Singapore-headquartered B2B technology company with a strong security culture (identity and industry withheld under confidentiality)
- Starting point
- Pre-seed, 3 people, architecture designed alongside the first lines of production code
- State today
- Series A, 70+ people; the original architecture remains in production across five regions (SG, US, EU, AU, HK)
- Structural rewrites required
- None to date
- Known future requirements at design time
- Enterprise customers, security audits, multi-jurisdiction operation
The architecture aged well because its early decisions were made to preserve options — separating the management layer from data processing, decoupling heavy workloads, and selecting mature components — under explicit acknowledgment of which requirements were certain and which were speculative.
The challenge: designing for a company that does not exist yet
Architecture at the earliest stage is decided under maximal uncertainty about the product and the market, and the conventional advice follows from this: defer structural decisions, optimise for iteration speed, and accept a rewrite later as the cost of learning. The advice is sound where the future is genuinely unknown.
In this case, part of the future was known. Whatever form the product took, three requirements were fixed by the commercial strategy: the customers would be security-conscious enterprises whose due diligence would examine the system's design; certifications (ISO 27001, SOC 2 Type 2) would eventually be required; and operation across multiple jurisdictions, with data residency commitments, was part of the plan. A fourth requirement was fixed by circumstance: the team would grow quickly, so the architecture had to remain learnable by engineers who were not present when it was designed.
The design problem was therefore one of classification: distinguishing the requirements that were certain — where early structural investment was justified — from those that were speculative, where deferral remained correct. Structural investment in speculative requirements is premature optimisation; deferral of certain requirements is deferred cost at compound interest.
The approach: invest in the certain, defer the speculative
1. Separate the control plane from the data plane
The foundational decision divided the system into a management layer — identity and access management, tenant configuration, administration, and the deployment tooling common to every region — and the planes where customer data was processed and stored. The multi-jurisdiction requirement was certain, and this separation is the structural property that requirement ultimately depends on: it is what later allowed data planes to be replicated per region while a single control plane served all of them (detailed in the multi-region companion study).
At design time this cost little more than a modest amount of additional structure — the discipline of keeping customer data and its processing out of the management layer. The alternative — extracting a control plane from an entangled system after customers exist — is among the most expensive refactorings in commercial software.
2. Decouple heavy workloads through queues
The platform's computationally heavy, bursty asynchronous workloads — along with its routine background jobs — were decoupled from the serving tier through queues from the outset. Managed queues (AWS SQS) sat between the request path and the worker pools that drained them, so processing could be operated entirely separately from serving. The consequences compounded over time: compute for heavy processing could be scaled, scheduled, and — later — regionally placed independently of the request path; failures in processing degraded throughput without taking down the product; and the queue boundary formed a natural seam along which the system could be divided as the team grew.
3. Select mature components; budget novelty explicitly
Component choices favoured widely operated, well-understood technology. AWS was chosen over GCP and Azure for its ecosystem and prevalence; Microsoft Entra over identity tools such as JumpCloud, because compliance was built into its services; and cloud-managed databases over self-hosted ones, so that upsizing was a single-line change and backups came by default. Novelty was treated as a budget to be spent where it purchased product advantage, and withheld from the substrate. A three-person team operating production systems cannot also serve as the discoverer of a component's failure modes; by Series A, the same property meant that most new engineers arrived already familiar with most of the stack.
4. Make the design auditable, because audits were certain
Since due diligence and certification were fixed requirements, the architecture was kept explainable and evidenceable. Trust boundaries were clear, the data flows could be drawn accurately on a single page, and logging and access control were placed at exactly the boundaries examiners ask about. When enterprise due diligence and later audits arrived, the system description given to examiners was the system as built. The companion compliance study describes the effect on certification cost.
5. Defer everything else, and record the deferrals
Decisions with no certain requirement behind them were deferred deliberately: service decomposition beyond the natural queue and plane seams, caching layers, generalisations of the data model beyond known use, and standing up a second region's infrastructure before one was needed — the design stayed region-agnostic, but only one region was built. Deferrals and decisions alike were recorded — as architecture decision records and RFCs kept in the searchable company wiki — with their reasoning and the conditions under which they should be revisited. The record served the growing team as much as the system: an engineer joining at employee 50 could read why the system had its shape, in place of inferring it.
The execution: how the architecture evolved
Initial design — at inception, alongside the first production code. The plane separation, queue boundaries, and component selections above were designed alongside the first lines of production code. The first version deliberately omitted a great deal: it ran as a small number of deployables rather than decomposed services, in a single region — region-agnostic by design, but only one built — with no caching layer and a data model scoped to known use. Each omission sat on a seam it could be split along later.
Under load and audit — as the first enterprise customers and the first audit cycle arrived. The architecture was designed with ISO 27001 and SOC 2 Type 2 in mind from the start, so examination confirmed it rather than correcting it: the system description given to due-diligence teams and auditors was the system as built, and no structural change was required to pass. The audit cycle was an exercise in documenting existing practice, not in remediating design — the effect on certification cost is covered in the companion compliance study.
Under regional expansion — as data-residency commitments turned into deals. The data planes were replicated into the US, EU, Australia, and Hong Kong against the shared control plane. Structural change required: none — the expansion was absorbed through configuration and data-layer parameterisation only, exactly as the plane separation was designed to allow (detailed in the companion multi-region study).
Under team growth — as headcount grew toward Series A. As headcount grew toward 70+, the queue and plane boundaries served as ownership seams along which teams formed. The division was along services, grouped by whether a service was frontend — the customer-facing apps and services on the serving tier — or backend — the internal processes and workflows behind the queues, such as data scraping. That segregation proved sufficient to scale, and no boundary had to be moved.
What did not go smoothly
A cloud-provider policy change forced rework. A change in how the cloud provider resolved certain resources arrived unexpectedly and forced a re-architecture of how those resources were managed in code, extending the duration of a regional expansion. It was resolved by reworking the resource definitions, after which the pattern held for subsequent regions.
A mature component still surprised at scale. A deliberately-boring managed component nonetheless hit a service limit at scale, despite having been chosen for its predictability. It was resolved with a documented workaround and explicit capacity planning, and the limit was recorded in the operational runbook so it would not surprise anyone again.
The results
- The original architecture remains in production from pre-seed through Series A, across five regions, through 20x team growth
- Regional expansion required no structural rework — the plane separation absorbed it at the configuration and data layer (see companion study)
- Enterprise due diligence and certification examined the design as built, with the architecture description serving as audit evidence
- The design absorbed growth without structural change — 20x team growth, expansion to five regions, and rising enterprise load, none of which required a rewrite or a re-placement of the core boundaries
What this means if you're running a startup or SME
Stated as a rule: early architecture is a classification problem — invest structurally in the requirements that are certain, defer the rest, and write down which is which.
The failure modes on either side are common. Teams over-build against imagined scale and pay for structure no requirement demanded; teams under-build against requirements that were foreseeable — enterprise customers, audits, a second jurisdiction — and pay for the deferral at the worst time, mid-deal or mid-audit. The judgment in between requires having seen how these decisions age, which is precisely what most early teams lack: the person who has watched a control-plane extraction, or a queue boundary placed well, knows which is which.
This is the work we do at Aijutsu: software architecture and product delivery for founders and SME teams — designing new systems, reviewing existing ones against the requirements actually coming, and coaching senior engineers in the judgment this case describes.
If your roadmap contains enterprise customers, an audit, or a second jurisdiction, your architecture already has requirements — the question is whether it reflects them. Book a diagnostic conversation: [email protected]
Frequently Asked Questions
How do you design software architecture that scales?
Identify the requirements that are certain and invest structurally in those alone. In this case, the certain requirements — enterprise scrutiny, audits, multi-jurisdiction operation — dictated a control/data plane separation, queue-decoupled workloads, and mature components; everything speculative was deferred and recorded. The result absorbed 20x team growth and five-region expansion without structural rework.
Should a startup use a monolith or microservices?
The distinction that matters earlier is boundary placement, with deployment granularity following later. A system with well-placed internal boundaries — in this case, the control/data plane separation and queue seams — can be operated as one deployable and divided later along those seams as the team grows. Decomposition ahead of the team size that requires it adds operational cost with no purchaser.
What is premature optimisation in software architecture?
Structural investment in requirements that are speculative. The corresponding error in the other direction — deferring requirements that are certain, such as a known future audit or jurisdiction — is equally costly and less discussed. Sound early architecture consists largely of classifying requirements correctly between the two.
What architecture decisions are hardest to reverse?
Decisions entangled with customer data and commitments: extracting a management layer from a system where it is interleaved with data processing, removing single-region assumptions from a live system, and replacing foundational data stores. These are the decisions worth making deliberately at inception; most others can be revisited at tolerable cost.
When should a startup revisit its architecture?
When a recorded deferral meets its revisiting condition, or when a certain requirement changes — a new jurisdiction, a new compliance regime, an order-of-magnitude change in scale or team size. Recording decisions and deferrals with their conditions, as in this case, converts the question from periodic anxiety into a checklist.
Aijutsu is a founder-led, coaching-informed, AI-leveraged technology practice in Singapore. Its founder previously held senior technology leadership at the company described in this case study, where this work was carried out.