Software architecture is specifically the fundamental organization of a system, embodied in its components and their relationships.
Quote
Senior engineers think in systems.
Primary dimensions here include:
- The structure of components, subsystems, modules, their communication as well as any non-functional requirements.
Levels of abstraction are a good thing in software architecture. They allow us to identify commonalities and de-duplicate.
Monoliths Vs Microservices
Monoliths contain one software project that contains functionality. There is a module structure and some amount or organization in the system but it is one deployable unit. Communication between different parts of the monolith are just in-memory or use an internal API.
A microservices architecture is one where deployable units work together via network communication.
In general, start with a monolith and break things off into microservices if this proves valuable.
Pitfalls of Over Engineering
- Excessive network calls:
- networking is slow and has unpredictable delays since each network call has fixed overhead.
- many small calls are often slower than one larger call, even with parallelism and async
- payload size matters too
- Bottlenecks
- This can occur if your architecture has you repeatedly accessing the same data or system.
- Over-taking Responsibility
- Have a clear separation of ownership so that work is evenly distributed across your system. For example, the backend doing work that should be done on the frontend
- Sometimes this is an organizational result
- This could cause tech-debt that people don’t want to touch
- Too much waiting
- Moving to an async model is valuable in reducing perceived waits
- It is better to return partial results and fill them in, then everything all at once if that takes longer
N+1 Query Problem
One query to fetch a list, N queries to fetch related data. This makes the query count explore and latency compounds. This is usually a design bug.
ORMs and GraphQL can silently introduce this.
Always inspect generated SQL and query count profilers.