Approach

We are opinionated about exactly one thing: how complexity is allowed to grow.

Almost every other engineering argument is taste, and we will happily lose those. This one decides whether your system is still worth changing in three years.

The problem

What the wall actually feels like from the inside.

Nobody decides to build a system that resists change. It happens gradually, and the symptoms show up in the business long before anyone names the cause.

The symptoms

  • Estimates stop making sense. A two-day change comes back as three weeks, and the difference is real, not padding.
  • Everything is a release. One small fix cannot ship on its own, so fixes queue up and go out together, which makes each release riskier.
  • Only one person can touch it. The parts that matter have exactly one plausible owner, and everyone quietly plans around their holidays.
  • New people take months. Not to learn the domain — to learn what breaks if they change something.
  • Removing a feature is harder than adding one. Which means the system only ever gets heavier.

The cause

Complexity is not the number of parts. It is the number of relationships between them. Ten things that all know about each other are far more complicated than fifty things that each know about two.

In a tightly coupled system, adding a part adds a relationship to everything already there. The count of things you must hold in your head, test, and keep working grows multiplicatively — so the eleventh part costs far more than the third did, for no visible reason.

Past a certain point, the rational move is to stop changing the system. Teams usually reach that conclusion without ever saying it out loud; it just becomes obvious that the safest release is no release.

The answer

An army of small workers, each replaceable without ceremony.

Break the system into many small services, give each one job and a contract, and the arithmetic changes. Adding a part adds its own complexity and nothing else — the total moves by +n rather than ^n.

01

Small enough to hold entirely

Each service does one job and fits in one person's head. There is no part of the system that requires a two-week orientation before it can be safely touched.

02

Bounded blast radius

A service that breaks is a service that breaks. It degrades the system rather than stopping it, and the search for the cause starts inside one boundary.

03

Symmetrical addition and removal

Deleting a part subtracts exactly what adding it cost. That symmetry is what keeps a system from silently accumulating features nobody uses any more.

04

Contracts instead of assumptions

Services talk through versioned interfaces verified on both sides in CI, so a breaking change fails in the pipeline rather than in production. Contracts also hide the implementation: a service can be rewritten in a different language and the rest of the system never notices.

05

Architecture that stays editable

You do not need to be right up front. The shape can keep changing during the build and long after it — restructuring is a normal operation here.

06

Growth becomes quantitative

A bigger system is more small parts, not a harder one. Scale turns into a question of count and capacity — something you can plan, price and staff for.

The honest caveat

Microservices are not free. You pay for independent deployability and bounded failure with operational overhead — more moving parts to deploy, observe and debug across. Below a certain size that trade is a bad one, and we will tell you when your system is below it.

What makes the trade work above that size is the platform: most of the overhead is a solved problem in Kubernetes, so you pay it once for the cluster instead of repeatedly per service.

The one hard call

If the architecture is editable, what is not?

The technology stack for your particular kind of product. Services can be rewritten in an afternoon; a wrong storage decision is felt for years, because by the time it is clearly wrong there is data in it.

What we settle before writing code

  • What the data actually is — its shape, its volume, how it arrives and how long it must stay true.
  • Which database — relational, time-series, columnar, document, or more than one. The single most expensive line to redraw later.
  • How parts talk — synchronous calls, queues, or an event stream, chosen per relationship rather than as a house style.
  • Where the state lives — because "everywhere" is the default outcome if nobody decides.
  • What must never be lost — the difference between data you can recompute and data you cannot.

What we deliberately leave open

  • The full service list. The main flow nodes have to be understood; the rest can arrive when the need is real.
  • Feature boundaries. They move as the business learns. That is expected, not a planning failure.
  • Where the AI goes. Easier to place well once the data flow exists and you can see what it would actually see.
  • Interface details. The UI follows the system; designing it first tends to invent requirements.
Method

Eight steps, and what each one is actually for

STEP 01

Understand the business

We ask simple questions about how the work happens today and what would count as better. No specification required from you — writing one is our job, not yours.

→ domain notes, constraints, what must never break

STEP 02

Choose the stack

Technology picked for this product type specifically — above all the database and the data model. This is where we deliberately go slowly.

→ stack decision with the reasoning written down

STEP 03

Sketch the architecture

The core microservices, and more importantly the flow of data between them — which deployments run continuously, which jobs run on a schedule, how the pipelines chain, and how services communicate.

→ architecture sketch, main flow nodes, contracts

STEP 04

Fill the containers

Each service in the language that fits its job — Go for throughput and operations, Python for data and models, TypeScript for interfaces, or whatever else the problem calls for. Contracts hide the implementation, so the choice is free per service. Small scope, its own tests, its own metrics.

→ running services, images, CI

STEP 05

Wire the data flow

Make the stream steady end to end: throughput under load, backpressure where it is needed, retries that are safe, and job pipelines that fail loudly.

→ pipelines, schedules, queues, throughput tests

STEP 06

Integrate outward

Connect the system to what your people already use, and to your existing products. Where AI genuinely helps, it goes here — often as a chat bot or an assistant sitting on top of services that already have the answers.

→ integrations, bots, AI-backed services

STEP 07

Deploy the cluster

Across as many hosts as the workload needs, wired into a single cluster, with monitoring and alerting live before anything depends on the system.

→ cluster, dashboards, alerts, runbooks

STEP 08

Hand over

The system becomes yours: repositories, infrastructure, documentation and the reasoning behind the decisions. Continued support is available afterwards and is never something we design you into needing.

→ handover, documentation, optional support

The conversation

Simple questions in, large systems out.

The usual arrangement asks the client to arrive with a technical brief — which means asking the person who knows the business least about software to do the hardest translation in the project. We run it the other way round.

What we ask about

  • How the work happens now — including the spreadsheet nobody officially admits to.
  • What has to be true — what would be embarrassing, expensive or illegal to get wrong.
  • How fast is fast enough — real tolerance, not an aspiration.
  • Who acts on the output — and where those people actually are when they need it.
  • What already exists — the systems we should connect to rather than replace.

What you never have to do

  • Write a technical specification. If you could write it precisely, you would not need us.
  • Choose the technology. You describe the constraints; the stack is a conclusion, not a preference.
  • Design the architecture. Answering “how does this work today” is enough input to start.
  • Know what a job pipeline is. That vocabulary is ours to worry about.
We ask

What happens today between the data arriving and someone making a decision on it?

You

Two people export it, merge it in a spreadsheet, and send it round by mail before lunch.

We ask

What has gone wrong with that in the last year?

You

Twice the source changed format and nobody noticed for a few days.

We ask

If you could ask this data one question at any time of day, what would it be?

You

Where we are exposed right now, without waiting for the morning file.

Result

Ingest with schema validation that alarms on format drift, a merge service that replaces the spreadsheet and keeps its audit trail, a continuously maintained exposure view, and a bot that answers the question on demand. Four small services — none of which the client had to specify.

Operating standards

True of every system we ship

Not negotiated per engagement. This is the baseline that makes everything above it mean something.

Engineering

  • Everything in version control — services, infrastructure, configuration, dashboards, alert rules.
  • Reproducible environments — a new environment is a pipeline run, not a week of archaeology.
  • Metrics and logs with the feature — shipped in the same change as the logic, not after the first incident.
  • Contracts verified in CI — on the producer side and the consumer side both.
  • Reviewed changes — no direct pushes to a production branch, from anyone, us included.

Working together

  • You own everything — repositories, infrastructure accounts and credentials are yours from day one.
  • Written decisions — the reasoning survives the people who made it.
  • Weekly demo, weekly honesty — what shipped, what slipped, and what we learned that changes the plan.
  • We say when we do not know — “this needs a spike before I can price it” is an acceptable answer and saves money.
  • Exit without drama — handover is continuous, not a phase bolted on at the end.

Does this match how you want to work?

If it does, the next step is a conversation about your business — not about technology. If it does not, better to find that out now than three months in.