Skip to main content

Design Funnel

Design Pattern Heuristics

Generally we can apply these designs as explained below to any application systems design request.


Plans

Summary

⚡️ LEVEL 1 - N-TIER

Small to medium-size apps.

  • Instance: easiest for small teams, low cost, but also less scalable/reliable. Use for small-medium apps, lower traffic apps. Improve with autoscaling and ELBs.
  • Container: more scalable/reliable, but a bit more complex to setup. Use for small-medium apps. Improve with ELBs and container orchestration.
  • Managed: combines an easier setup with the managed infrastructure of instances/container. Can be more costly but easier to manage. Use for small-medium apps. Improve with ELBs and container orchestration.

⚡️ LEVEL 2 - API/Microservices

Small to Large-size apps.

  • A good middle ground of usability, scalability, reliability, and cost. Most teams can handle this. Good for larger staffs to work concurrently. Use for medium-large apps.

⚡️ LEVEL 3 - Queue/API/Microservices

Medium to Large-size apps.

  • Similar to API/Microservices, but with a queue in front of the API/Microservices, which can increase performance and reliability, but add complexity. Use for large apps with high traffic/activity.

⚡️ LEVEL 4 - Event-driven

Medium to Largest-size apps.

  • More complex, but highest level of scalability, reliability, and decoupling. Use for large apps with high traffic/activity or with many complex concurrent interactions.

Level 1 Architecture - N-Tier

  • Tiers
    • The "n" in "n-tier" refers to the number of layers, or tiers, in the architecture.
    • 3-tier consists of a presentation tier, application tier, and a data tier.
    • 4-tier adds a business tier between the presentation and application tiers.
  • Decoupling
    • The purpose of separating the application into multiple tiers is to allow for decoupling of components, which can make the application more scalable, flexible, and easier to maintain.
  • Separation of Concerns
    • Each tier is responsible for a specific aspect of the application, and the separation of concerns between the tiers makes it easier to understand and manage the application.
  • Scalability
    • By separating the application into tiers, it becomes easier to scale individual components of the application, rather than having to scale the entire application.
  • Improved Performance
    • N-tier architecture can also help improve performance by distributing the workload across multiple tiers and allowing for more efficient use of resources.
  • Reusability
    • Components in one tier can be reused by other applications, which can help reduce the time and effort required to develop new applications.

Tiers:

  • Presentation Tier: This is the front-end or user interface tier, which is responsible for presenting information to the user. Services in this tier include web servers, application servers, and front-end frameworks and libraries.

  • Application Tier: This is the middleware tier, which is responsible for processing requests from the presentation tier, accessing data from the database tier, and providing response to the presentation tier. Services in this tier include application servers, business logic components, and APIs.

  • Business Tier: Many tier models combine application and business tiers. The business tier is a logical layer within the application tier that is responsible for implementing the core business logic and rules of the application.

    • Business objects: represent the business entities, such as customers, orders, and products, and contain the data and logic for these entities.
    • Business components: components that implement the specific business logic for the application. For example, a component that calculates the total cost of an order, or a component that performs credit card validation.
    • Workflow engines: manage the flow of work between different business components, such as processing an order or performing a financial transaction.
    • Business rules engines: enforce the business rules and policies of the application, such as verifying that an order meets certain criteria before it is processed.
    • Business intelligence and reporting tools: provide data analysis, reporting, and other intelligence services to the business tier.
  • Database Tier: This is the data tier, which is responsible for storing, managing, and retrieving data. Services in this tier include relational databases, NoSQL databases, and data warehousing systems.

  • Infrastructure Tier: This is the underlying tier that provides the underlying hardware, network, and storage infrastructure to support the other tiers. Services in this tier include servers, storage systems, and network devices.


Instance (N-Tier)

  • Initial complexity: LOWEST
  • Scalability: LOWEST
  • Reliability: LOWER-MEDIUM
  • Usability: HIGH initial, moves LOWER as scalability needed.
  • Cost: LOW-MEDIUM
  • Usage: <100k DAU
  • GOOD:
    • for small to medium sized applications
    • for more-coupled or monolithic application platforms
    • if you have a very small dev team
    • if you have less expertise in other designs
    • if you have a small budget
    • if you have a small time frame
  • BAD:
    • to scale a lot quickly
    • for highest availability
    • for highest reliability
    • for high geographic global colocation coverage
    • for high data/event streaming requirements

Container (N-Tier)

  • Initial complexity: LOW-MEDIUM
  • Scalability: MEDIUM
  • Reliability: LOWER-MEDIUM
  • Usability: MEDIUM initial, MEDIUM as scalability needed.
  • Cost: LOW-MEDIUM
  • Usage: <250k DAU
  • Main difference with instances is containers are better/faster for scalability
  • Still tightly coupled but easier to scale
  • GOOD:
    • for a small team with container experience.
    • if you need to scale instances quickly
    • for better availability than instance (can scale quicker)
    • for better reliability than instance
    • for better/moderate handling high burst traffic/requests
  • BAD
    • if your team is not experienced with containers
    • for more highly decoupled services.
    • for highest available multiple geographic colocation coverage
    • for high data/event streaming requirements

Cloud Managed N-Tier

  • Initial complexity: LOW-MEDIUM
  • Scalability: MEDIUM
  • Reliability: MEDIUM
  • Usability: HIGH initial, MEDIUM as scalability needed.
  • Cost: MEDIUM-HIGH
  • Usage: <300k DAU
  • Main difference is that you are using a cloud provider to manage the instances/containers for you.
  • Can be used with fleets of containers and instances.
  • The provider has experience with this design and can scale it for you better with their internal tools.
  • GOOD
    • to scale instances quickly
    • for a more easily manageable admin
    • for less granular control over your infrastructure
    • if you need better availability than instances (scale quicker)
    • if you need better reliability than instances
    • if you need easier geographic global colocation coverage
  • BAD:
    • Bad if managed costs are too high for low usage
    • Bad if you need more highly decoupled services.
    • Bad if you have very high data/even streaming requirements
    • Bad if you want higher granular control over your infrastructure
    • Bad if you have unusual technologies not offered in the managed services
  • Examples:
    • AWS Elastic Beanstalk
    • AWS ECS
    • AWS Fargate
    • AWS Lambda
    • Azure App Service
    • Azure Container Instances
    • Azure Functions
    • Google App Engine
    • Google Cloud Run
    • Google Cloud Functions
    • Heroku
    • Oracle Cloud Infrastructure App Services

Level 2 Architecture - API/Microservices

  • Initial complexity: MEDIUM-HIGH
  • Scalability: MEDIUM-HIGH
  • Reliability: MEDIUM-HIGH
  • Usability: MEDIUM-HIGH
  • Cost: MEDIUM
  • Usage: <1M DAU
  • GOOD:
    • easier horizontal scaling,
    • easier to modify or replace individual components
    • better fault tolerance
    • optimized for specific use cases
    • better for collaboration among teams
    • speed up development, allowing teams to work on their own components in parallel.
    • deployed, tested, and rolled back more quickly and easily, leading to faster time to market
    • Language independence, can be written in different programming languages and environments,
  • BAD
    • Increased complexity
    • Inter-service communication overhead
    • Challenges with data consistency
    • Increased operational overhead
    • Securing a microservices architecture can be more difficult than securing a monolithic architecture due to the increased number of entry points and the complexity
    • Increased infrastructure cost

Level 3 Architecture - Queue/API/Microservices Hybrid

  • Initial complexity: HIGH
  • Scalability: HIGH
  • Reliability: HIGH
  • Usability: LOW-MEDIUM
  • Cost: MEDIUM-HIGH (based on usage and team experience)
  • Usage: <10M DAU
  • GOOD:
    • Great for scalability and reliability.
    • Asynchronous Processing: asynchronous processing, which means that tasks can be added to a queue to be processed later, rather than processing them immediately. This can help to offload resource-intensive tasks and improve the responsiveness of the system.
    • Load balancing: helps to distribute workloads evenly and dynamically adjust to changes in demand, providing a more scalable and reliable solution.
    • Improved reliability: a buffer for processing, allowing for recovery from failures and improved overall reliability. If a service becomes unavailable, the tasks can be redirected to another instance for processing.
    • Increased scalability: possible to scale out the number of instances processing tasks, allowing for horizontal scaling and improved performance.
    • Decoupled architecture: decouple different parts of a system, making it easier to manage and maintain.
    • Improved throughput: improve the throughput of a system by allowing for parallel processing of multiple tasks, improving overall system performance.
    • Better resource utilization: more efficient use of resources by allowing for the distribution of workloads and the processing of tasks at the appropriate time.
  • BAD
    • More difficult to implement
    • Increased complexity: A queue-based API design can add an additional layer of complexity to the system, requiring additional infrastructure and administration overhead.
    • Latency: Task processing can be delayed by the time it takes for the task to be added to the queue, processed, and then returned. This can result in increased latency and potentially impact the user experience.
    • Ordering: In some cases, it may be important to process tasks in a specific order, but a queue-based API design may not provide guaranteed task ordering.
    • Visibility: With a queue-based API design, it can be difficult to track the status of tasks and monitor their progress, leading to a lack of visibility into the system.
    • Resource utilization: Task processing in a queue-based API design can consume resources, and without proper management, the system can become bogged down and unresponsive.
    • Error handling: Error handling can be more complex in a queue-based API design, as errors may occur at any point in the processing of a task, including when the task is being added to the queue, processed, or returned.
    • Debugging and troubleshooting: Debugging and troubleshooting can be more difficult in a queue-based API design, as there are many more components involved in the processing of tasks and errors can occur at multiple points.

Level 4 Architecture - Events-based Microservices

  • Initial complexity: MEDIUM-HIGH
  • Scalability: HIGHEST
  • Reliability: HIGHEST
  • Usability: MEDIUM
  • Cost: MEDIUM-HIGH (based on usage and team experience)
  • Usage: <100M DAU
  • GOOD:
    • Decoupled architecture: Event-based microservices architecture provides a way for services to communicate with each other asynchronously, making the architecture more decoupled and easier to manage.
    • Improved scalability: With event-based microservices architecture, services can scale independently, allowing for improved scalability and the ability to handle increased loads.
    • Improved reliability: Event-based architecture provides a way to handle failures and recover from errors, leading to improved reliability of the system.
    • Improved performance: By processing events asynchronously, the system can handle larger loads and improve overall performance.
    • Improved resource utilization: Event-based architecture allows for the distribution of workloads, improving resource utilization and the ability to handle peak loads.
    • Improved data consistency: Event-based architecture provides a way to ensure that changes to data are propagated to all services that need to be updated, leading to improved data consistency across the system.
    • Flexibility: Event-based architecture provides a way to evolve the system over time, adding new services and functionality as needed, leading to greater flexibility and the ability to adapt to changing requirements.
  • BAD:
    • Increased complexity: Event-based microservices architecture can add an additional layer of complexity to the system, requiring additional infrastructure and administration overhead.
    • Latency: Processing events asynchronously can result in increased latency and potentially impact the user experience.
    • Ordering: In some cases, it may be important to process events in a specific order, but event-based architecture may not provide guaranteed event ordering.
    • Visibility: With event-based architecture, it can be difficult to track the status of events and monitor their progress, leading to a lack of visibility into the system.
    • Error handling: Error handling can be more complex in event-based architecture, as errors may occur at any point in the processing of events, including when events are being generated, processed, or consumed.
    • Debugging and troubleshooting: Debugging and troubleshooting can be more difficult in event-based architecture, as there are many more components involved in the processing of events and errors can occur at multiple points.
    • Interoperability: Ensuring interoperability between different services can be a challenge in event-based architecture, as each service may have its own unique event format and data structure.