Anik Sikder’s essay starts where architecture actually starts: a founder says “we need an ERP,” and the first questions are about responsibilities, not frameworks. The thesis running through the whole piece — organize around meaningful business capabilities before technical abstractions, and give every component a reason to exist.
Capabilities, boundaries, ownership
- Map business capabilities first (identity, inventory, sales, billing, reporting) so the code structure starts reflecting the business — someone joining six months later can read the product from the layout.
- A boundary is not a folder; it defines ownership. Poorly isolated responsibilities turn a change to Inventory into a chain of breakages across Sales and Reporting.
- Layers (API → application service → domain rules → persistence → database) exist for clear ownership, not for their own sake — the API layer shouldn’t become the entire business engine.
Follow the request, not the diagram
- Walk a real request (create order) through the system: authenticate, authorize, validate, apply domain rules, commit the transaction, emit the event.
- “If you cannot explain why a component exists in the request journey, question whether you need that component.”
- Don’t turn everything into a service — hundreds of abstractions are not architecture. Ask what business operation each component represents.
Data, transactions, and async
- The database is not “just storage”: model inventory movements, not just a quantity, so the system can answer both “how much do we have?” and “why do we have this amount?”
- Operations that must succeed or fail together share a transactional boundary; emails, PDFs, and analytics don’t belong inside it.
- Queues and workers follow from “which work should not block the user’s request?” — not from “let’s install RabbitMQ.”
Security and multi-tenancy
- Authentication asks who you are; authorization asks what you’re allowed to do — different architectural concerns.
- Tenant isolation is an architectural security boundary: “can this user, inside this organization, perform this action on this resource?” The database schema should reinforce it.
Microservices are earned, not assumed
- A five-developer, ten-customer company that starts with a service mesh has built a distributed system before it had a distributed problem.
- Start with a modular monolith: boundaries stay explicit while deployment stays simple. Extract one capability (e.g., reporting) only when it becomes a real bottleneck.
- Five questions before adding any component: what problem are we solving, who owns this, does it need to happen immediately, what happens as the system grows, and what does it cost operationally?
The takeaway: good architecture is an evolution path, not a perfect day-one diagram — complexity should be earned by the problem. Sikder closes with a production checklist spanning business, data, security, performance, reliability, and observability: if you can’t answer those questions, the architecture probably isn’t finished.