25T3 Week 9
Tuesday 10am-1pm (T10A)
Start 10:05am
Assignment 2
Sample Exam
Imagine you’ve built a perfect online banking app. Every feature works flawlessly.
BUT then when 100 users log in, the system crashes. Did you succeed?
Success in building software isn't just about getting the features to work.
It's about designing a system that performs well under expected conditions
What makes software good?
Architectural characteristics, also known as non-functional requirements, define fundamental qualities software architecture must support.
| Characteristic | Description | Example |
|---|---|---|
| Performance | How fast system responds under given load | Page loads in under 2 sec for 1000 users |
| Scalability | Ability to handle increased workload (users, data) | Ticketing sales for a popular band |
| Availability | Percentage of time the system is operational | "Five nines" (99.999%) uptime |
| Reliability | Ability to run consistently without errors | Banking system that never loses a transaction |
| Security | Protection against threats, unauthorised access | OAuth 2.0 authentication |
| Maintainability | Ease of making changes, fixing bugs or adding new features | Modular codebase with clear separation of concerns |
| Testability | How easily the system can be tested | Unit tests can be run in isolation |
| Extensibility | Ability to add new functionality with minimal changes | VSCode extensions |
| Deployability | How easy is it to deploy the software | Microservice-based e-commerce website |
Here are some examples of characteristics, not an exhaustive list:
Architectural styles are predefined patterns and philosophies guiding how software systems are structured and deployed.
Partitioning
Code organised by technical layers vs. domain roles
e.g. For e-commerce platform teams can be separated in
Deployment
Definition: Organises each distinct technical responsibilities into separate layers
Presentation (UI components)
Workflow (business logic components)
Persistence (database schemas and operations)
Example of Layered:
OSI Model which describe the networking system's communication functions
(think IP addresses!)
Definition: Deployed as a single unit and organised in domain-based modular structure
What it looks like as code!
Example of Modular Monolithic:
Gitlab started as monolithic Rails app but later modularised
Definition: Single-purpose, separately deployed units for environments requiring frequent changes and scalability
Example of Microservices:
Confluence, Amazon, Netflix and Uber famously use microservices
Key qualities: maintainability, modifiability, deployability
Source: Gitlab's ADR
Key qualities: scalability, performance, reliability, team autonomy
Source: Atlassian's Engineering Blog
Both took different paths, because they wanted to solve different problems.
Intermediate between Monolith and Microservices
| Characteristic | GitLab (Modular Monolith) | Atlassian (Microservices) |
|---|---|---|
| Maintainability | ⭐️⭐️⭐️⭐️Modules reduce coupling |
⭐️⭐️⭐️Many services, can be complex |
| Team Autonomy | ⭐️⭐️⭐️ Modules help, but teams still share monolith | ⭐️⭐️⭐️⭐️⭐️ Teams own services independently |
| Resilience | ⭐️⭐️ Single app → bigger blast radius | ⭐️⭐️⭐️⭐️⭐️ Failure isolated to individual services |
| Performance | ⭐️⭐️⭐️ Shared memory can bottleneck | ⭐️⭐️⭐️⭐️ Services optimized per region |
| Deployability | ⭐️⭐️⭐️⭐️Can deploy modules separately | ⭐️⭐️⭐️⭐️ Services can deploy independently |
| Scalability | ⭐️⭐️ Limited to one app instance | ⭐️⭐️⭐️⭐️⭐️ Horizontally scalable per service |
| Modifiability | ⭐️⭐️⭐️⭐️ Easier to change modules | ⭐️⭐️⭐️ Service boundaries help, but many moving parts |
Give one real-world scenario where Microservices would be a poor choice. Explain why.
If we had started with microservices in the early stage (Small team, simple requirements), that would’ve been a mistake:
→ Microservices are great for scale, but not for MVPs or small teams
When Microservices would be a poor choice. Explain why.
It is less complex: single deployment, fewer moving parts
Skill growth, lets teams adopt microservice thinking gradually
Cost effective, avoids early microservice overhead
Why might a team choose a Modular Monolith as an intermediate step before adopting Microservices?
So instead, many teams go for a Modular Monolithic: a structures monolithic codebase with clear boundaries between modules like orders, payments, and users
Definition: Structures systems to respond to events, which are significant changes in a system state.
Example of Event-Driven:
AT&T for event ticketing
All of this necessitated a new way to think about communication. Enter Event-Driven Architecture.
What are the potential risks of using an Event-Driven architecture in a mission-critical system?
Eventual consistency: data takes time to sync → fine for notifications, but bad for instant consistency needs
Error handling: hard to trace bugs → when something breaks, it’s tough to figure out where. Errors can quietly get lost.
Operational overhead: Complex deployment & monitoring
Event Storms & Failures: Overloaded queues, poison messages
Governance Gaps: Schema mismatches, data duplication
Which architectural pattern would you choose for a system requiring strong consistency across components? Justify your choice.
Monolithic or Layered (single deployment). Because:
Why not others:
Design the architecture for an online ticketing system.
Identify architectural characteristics
Also consider some of the business drivers that reveal critical characteristics
Discuss which architecture could work best and worst
List some tradeoffs they would make designing the architecture and why
Is it better to optimise early for scalability or wait until it becomes a problem?
Can a modular monolith achieve the same team autonomy as microservices?
Are there systems where event-driven architecture causes more harm than good?
Should every modern application aim to use Microservices?
How do you decide whether to prioritise maintainability or performance in an architecture?