Architecture, senior software engineering, and technical execution for demanding products.

Case study

Retail: reducing a distributed system before it slowed delivery down

A four-developer team was maintaining seven microservices, several pipelines, a broker, and more coordination than the traffic and organization justified.

The engagement turned a disproportionate distributed architecture into an operable modular monolith: one CI flow, one deployable backend, frontend assets served by the backend, and a progressive migration without a big bang.

Context

An architecture heavier than the product

The microservices choice had been made before the product, traffic, and organization justified it. Each feature crossed several services, logs, pipelines, and environment-variable sets.

Main constraints

Coordination was too expensive

Some features required several pull requests, sequenced releases, and inter-service contracts to watch.

Runtime footprint was disproportionate

With staging, UAT, and production, the 3-pod minimum per service multiplied cost and operations.

Migration had to stay online

The product was live. The target had to be reached without a freeze, without a big bang, and with a clear rollback path.

Decisions

The choices that made simplification possible

The point was not to reject microservices. The point was to put distribution at the right level for the team size and product constraints.

  1. 01

    Migrate by route groups

    Existing HTTP prefixes became the migration unit. A route could move to a local handler without changing its external interface.

  2. 02

    Keep rollback operational

    Each switch was protected by a feature flag: local traffic when enabled, external service when disabled.

  3. 03

    Preserve internal boundaries

    The target was a modular monolith, not an opaque block. Business responsibilities still had to be readable in code.

  4. 04

    Reduce deployment to what mattered

    The frontend was served as static assets from the backend, with one CI flow and one artifact to operate.

Delivery

A progressive migration, one route at a time

The path let the team keep shipping during the transformation. The work combined architecture, implementation, operations, and decommissioning.

Local reimplementation

Service logic was brought into the main application behind the same HTTP interface.

Controlled switch

The flag made it possible to test in production, observe, then make the switch permanent.

Decommissioning

Once stable, the network call was removed, the queue drained, and the service retired.

Impact

What simplification changed

The main effect was removing a distributed-systems tax the organization did not recover through autonomy or scaling.

7 -> 1
Multi-service changes moved back toward one pull-request and deployment flow.
21 -> 3
Minimum pods per environment were reduced, across staging, UAT, and production.
1 setup
Local development moved from orchestrating several processes to one main setup.
Lower cost
Runtime, coordination, and operations were brought back to a level proportional to traffic.

Stack

Technologies and concerns covered

The value did not come from one technology. It came from aligning application architecture, runtime, and delivery.

  • TypeScript
  • NestJS
  • Vue.js
  • MongoDB
  • Kubernetes
  • Kafka
  • CI/CD
  • Feature flags
  • Modular monolith
  • Legacy migration

Lesson

Distribution has to pay rent.

A distributed system is justified when it solves a real organizational, scaling, or isolation problem. Otherwise it turns every feature into unnecessary coordination.