Complexity should be earned.
I don't add architecture to look impressive. Every service, queue, cache, and abstraction should exist because a specific constraint requires it. When it doesn't, I don't add it. This portfolio is built the same way.
- Principle 01
Start simple
Start with the simplest architecture capable of solving the problem.
I don't introduce microservices because they make architecture diagrams look impressive. Complexity should solve a real constraint.
Simulation · one payment request, two architecturesClientIdentityPaymentsEstatePostgreSQL- Deployables
- 1
- Network calls / request
- 0
- Databases
- 1
- Places it can fail
- 2
Microservices are the right answer when teams or scaling needs force them apart. Until then, they are four extra network calls that can each time out.
- Principle 02
Design for failure
Networks fail. APIs time out. Messages can be delivered twice. Third-party systems become unavailable.
Production software should expect these conditions rather than treating them as exceptional.
Simulation · a dependency that fails 30% of first attempts- Request 1: not sent
- Request 2: not sent
- Request 3: not sent
- Request 4: not sent
- Request 5: not sent
- Request 6: not sent
- Request 7: not sent
- Request 8: not sent
- Request 9: not sent
- Request 10: not sent
succeeded 0/0✓ ok · ↻ recovered by retry · ✕ failedRetries turn transient failures into successes — but every retry is another call to the dependency, which is why they need backoff, limits, and idempotency.
- Principle 03
Observability is a feature
If production fails, the system should tell you what failed, where, when, which request triggered it, which dependencies were involved — and whether it can recover.
Logging, tracing and metrics are part of system design.
Simulation · one failure, two log lines09:41:09 ERROR Something went wrong: The operation has timed out.
- What failed? — answerable
- Where did it fail? — not answerable
- When did it fail? — answerable
- What request triggered it? — not answerable
- What dependencies were involved? — not answerable
- Can it recover? — not answerable
- Principle 04
Data is architecture
Database decisions are architecture decisions.
Before choosing a storage technology, I think about:
- — Transactions
- — Indexes
- — Query patterns
- — Consistency
- — Concurrency
- — Relationships
- — Data lifecycle
Illustration · query plan for a dashboard querySELECT * FROM payments WHERE estate_id = 42 ORDER BY created_at DESC LIMIT 20;
Limit (rows=20) -> Sort (sort key: created_at DESC) -> Seq Scan on payments Filter: (estate_id = 42) rows read: 2,400,000execution time1,284 msSame database, same query, three orders of magnitude apart. Access patterns belong in the design, not in a post-launch fire drill. (Illustrative numbers.)
- Principle 05
Understand the trade-off
There is rarely one universally correct architecture.
Decisions depend on:
- — Constraints
- — Team
- — Traffic
- — Cost
- — Reliability
- — Development speed
- — Operational complexity
- — Maintainability
The goal is not maximum sophistication. The goal is the appropriate trade-off.
Interactive · my rough take for a small team- Operational complexity
- Low
- Cost at low traffic
- Medium
- Independent scaling
- Low
- Team autonomy
- Medium
- Early development speed
- High
- Local debugging
- High
Every option wins somewhere and loses somewhere. The job is picking the losses you can live with.