Skip to content

EN_IT_Architecture

somaz edited this page Jul 13, 2026 · 2 revisions

IT Terminology: Architecture

31. Monolith vs Microservices

One-line answer: A monolith bundles all functionality into a single deployment unit — simple but hard to scale or deploy in parts — while microservices deploy and scale independently per function, at the cost of distributed-system complexity (networking, data consistency).

A Monolith is an architecture where all functionality (UI, business logic, data access) is integrated into a single deployment unit, while Microservices is an architecture that decomposes a system into a collection of small, independently deployable services. A monolith runs as a single codebase and single process, whereas microservices run each service as its own process, communicating over the network (typically HTTP/gRPC or messaging).

The key point is that microservices are not always the right choice. Microservices trade organizational and operational complexity for the cost of a distributed system, and that cost is only worth paying when you have the team size and operational maturity to absorb it.

Monolith vs Microservices Comparison

Aspect Monolith Microservices
Deployment Deploy the whole thing at once (simple, but even a small change redeploys everything) Independent per-service deployment (frequent deploys possible, but many pipelines)
Scaling Scale the whole app together (inefficient) Selectively scale only the bottleneck service
Team Autonomy Low — shared codebase causes frequent conflicts High — each team develops, deploys, and chooses tech independently
Operational Complexity Low — single deploy, logging, debugging High — service discovery, distributed tracing, network failures
Transaction/Consistency Easy — single-DB ACID transactions Hard — distributed transactions, eventual consistency, Saga needed
Debugging Easy — single stack trace Hard — distributed tracing across service boundaries is mandatory

Modular Monolith — The Middle Ground

A compromise that keeps a single deployment unit (the operational simplicity of a monolith) while separating the internals with clear module boundaries (the modularity of microservices). Modules communicate only through well-defined interfaces, and DB schemas are partitioned per module. Rather than "microservices from day one," the recommended strategy is to start with a modular monolith and extract only the modules that need it into services once the boundaries stabilize.

The "Distributed Monolith" Anti-Pattern

The worst of both worlds: the system is decomposed into microservices, but the services are tightly coupled (synchronous call chains, shared DB, forced simultaneous deployment). You pay the full operational cost of a distributed system while keeping the coupling of a monolith. If deploying one service forces deploying another, or multiple services share the same DB table, suspect a distributed monolith.

What to Choose, and When

  • Monolith / Modular monolith: Early-stage startup, small team, domain boundaries still unclear, fast validation is the priority.
  • Microservices: The team is large enough (multiple teams need independent deployment), domain boundaries are stable, and operational maturity (CI/CD, observability, on-call) is in place.

Conway's Law

"A system's structure mirrors the communication structure of the organization that designed it." In other words, architecture and org structure reflect each other. To adopt microservices, the organization must also be reshaped into small autonomous teams (the Inverse Conway Maneuver).

Bounded Context (DDD)

In Domain-Driven Design (DDD), the boundary within which a single model applies consistently. It is the key tool for finding the right decomposition unit for microservices — aligning service boundaries with bounded-context boundaries lowers coupling. Incorrect boundary splits are a direct cause of the distributed monolith.


32. Serverless / FaaS

One-line answer: A model that delegates server provisioning and operation to the provider and deploys only code as functions — with event-driven execution, usage-based billing, and auto-scaling; statelessness and cold starts are the trade-offs.

Serverless is a model where you delegate code execution to the cloud without directly provisioning or managing servers. It does not mean there are no servers — it means the responsibility for managing them disappears from the developer. FaaS (Function as a Service) is the representative implementation of serverless: you deploy code as functions, and they execute in response to events.

Core Characteristics

  • Stateless: No state is preserved between function invocations — state is delegated to external stores (DB, cache).
  • Event-driven: Events such as HTTP requests, queue messages, file uploads, or schedules trigger the function.
  • Scale-to-zero: When there are no requests, there are zero instances — no idle cost.
  • Pay-per-use: Billed by invocation count × execution time × memory; zero cost when idle.

The Cold Start Problem

The price of scale-to-zero. If a function is not invoked for some time, its instance is reclaimed, and the next invocation must restart from runtime initialization, adding hundreds of ms to several seconds of extra latency. Mitigations include Provisioned Concurrency (keeping warmed instances), lightweight runtimes (preferring Go/Node), and shrinking package size.

Limits

Limit Typical Cap (example)
Execution Time Up to a few minutes per function (e.g., 15 min) — unsuitable for long batch jobs
Payload Request/response size limit (e.g., 6MB synchronous)
Memory Per-function ceiling (e.g., 128MB – 10GB)

Vendor Lock-in

Event sources, triggers, IAM, and the deployment model differ per cloud provider, so portability is low. Mitigations include abstraction tools such as the Serverless Framework or SAM, or open standards like Knative that run on top of Kubernetes.

BaaS (Backend as a Service)

A model that provides backend functionality — authentication, DB, storage, push notifications — as a managed service (e.g., Firebase). Combining FaaS (running your code) with BaaS (managed backend) is what the broad definition of serverless refers to.

Good and Bad Use-Cases

  • Good fit: Irregular/bursty traffic, event processing (image resizing, webhooks), scheduled jobs (Cron), glue code, prototyping.
  • Bad fit: Consistently high traffic (an always-on server is cheaper), long-running batches, ultra-low-latency requirements, cold-start-sensitive workloads.

Examples

AWS Lambda, Google Cloud Functions, Azure Functions, Knative (open serverless on Kubernetes).


33. The Twelve-Factor App

One-line answer: Twelve design principles for SaaS/cloud-native apps (codebase, dependencies, config, backing services, build/release/run separation, stateless processes, port binding, concurrency, disposability, dev/prod parity, logs, admin processes) that improve portability and scalability.

The Twelve-Factor App is a methodology of twelve principles for building SaaS and cloud-native applications, codified by Heroku engineers. It is a set of principles for building apps suited to portability, declarative configuration, deployment automation, and horizontal scaling, and is effectively the baseline assumption of modern container and Kubernetes environments.

# Factor Explanation
I Codebase One version-controlled codebase, deployed to many environments. One app = one repository.
II Dependencies Explicitly declare and isolate dependencies. Never rely implicitly on system-wide packages.
III Config Store config that varies between environments (credentials, endpoints) in environment variables, not in code.
IV Backing services Treat external services like DB, cache, and queue as attached resources, swappable without code changes.
V Build, release, run Strictly separate the three stages. A release is an immutable combination of build + config with a unique ID.
VI Processes Run the app as stateless processes. Persistent data lives in a backing service.
VII Port binding Export services by binding to a port directly, self-contained, without relying on an injected web server.
VIII Concurrency Scale out via the process model. Handle increased load by adding more instances.
IX Disposability Maximize robustness and elasticity with fast startup and graceful shutdown.
X Dev/prod parity Minimize the gaps (time, personnel, tools) between development, staging, and production.
XI Logs Treat logs as event streams. The app only writes to stdout; collection and storage are delegated externally.
XII Admin processes Run DB migrations and one-off tasks as one-off processes in an environment identical to the app.

34. API Gateway & Service Mesh

One-line answer: An API Gateway sits at the external→internal (North-South) entry point handling authentication, routing, and rate limiting, while a Service Mesh handles service-to-service (East-West) mTLS, retries, and observability via sidecars.

These are two layers for handling microservice traffic. An API Gateway is the single entry point for external→internal (North-South) traffic, while a Service Mesh controls service-to-service (East-West) communication at the infrastructure layer.

API Gateway

A single entry point between clients and backend services that handles cross-cutting concerns.

  • Routing: Forward to the appropriate backend service based on path/headers.
  • Auth: Centrally validate tokens (JWT/OAuth) at the gateway.
  • Rate Limiting: Protect backends with per-client request limits.
  • Request Aggregation: Combine multiple service calls into a single response.
  • Protocol Translation: Convert external REST ↔ internal gRPC, etc.
BFF (Backend for Frontend) Pattern

A pattern that provides a dedicated gateway per client type (web, mobile, IoT). It offers responses and aggregation optimized for each frontend, simplifying client-side logic.

Service Mesh

Separates service-to-service communication into an infrastructure layer outside the application code.

  • Sidecar Proxy: Attach a proxy (e.g., Envoy) next to each service to intercept all inbound/outbound traffic.
  • Control Plane vs Data Plane: The data plane (the sidecars) handles actual traffic, while the control plane distributes policy and configuration.
  • mTLS: Automatically encrypt and authenticate service-to-service communication with mutual TLS.
  • Traffic Management/Canary: Weight-based routing for canary and blue-green deployments.
  • Observability: Automatically collect metrics, traces, and logs without code changes.

North-South vs East-West (the Key Distinction)

Aspect API Gateway Service Mesh
Traffic direction North-South (external ↔ internal) East-West (service ↔ service)
Location Cluster/system edge Sidecar next to each service
Primary concern Auth, routing, rate limiting, aggregation mTLS, traffic policy, inter-service observability
Client awareness Client calls it directly Transparent to the application
Examples Kong, APISIX, AWS API Gateway Istio, Linkerd

The two are complementary, not competing. A common combination is using the gateway to control external entry and the mesh to govern internal communication.


35. Event-Driven Architecture

One-line answer: An architecture where components are loosely coupled by publishing/subscribing to events — gaining asynchronous processing, scalability, and resilience, at the cost of managing event ordering, duplication, and eventual consistency.

Event-Driven Architecture (EDA) is an architecture where components collaborate through producing, publishing, and consuming events instead of direct calls. Producers and consumers are decoupled in both time and space, yielding high scalability and flexibility.

Events vs Commands

  • Event: A notification of a fact that has already happened — past tense (OrderPlaced). The producer does not know who receives it, and there may be zero or many receivers.
  • Command: A request asking a specific target to do something — imperative (PlaceOrder). There is a single intended receiver, and it can fail.

Pub/Sub vs Message Queue

  • Pub/Sub: One event is received by many subscribers, each independently (fan-out). The producer does not know its subscribers.
  • Message Queue: A message is processed by a single consumer and removed from the queue (work distribution). A worker pool spreads the load.

Message Broker Comparison

Broker Model Characteristics Good for
Kafka Log-based High throughput, message retention/replay, ordering (within a partition) Event streaming, log pipelines, event sourcing
RabbitMQ Queue/AMQP Flexible routing, message ack, priorities Traditional work queues, complex routing
NATS Lightweight messaging Ultra-light, ultra-low latency, simple (persistence via JetStream) Fast inter-microservice communication, IoT

Eventual Consistency

Due to asynchronous event propagation, parts of the system are temporarily inconsistent but eventually converge. You give up strong consistency (immediate agreement) in exchange for availability and scalability. Adopting EDA means designing on the assumption of eventual consistency.

Delivery Guarantees

  • at-most-once: No duplicates, but possible loss — fast, when loss is acceptable.
  • at-least-once: No loss, but possible duplicates — the consumer must be idempotent. The most common choice.
  • exactly-once: Ideal, but a true guarantee is hard in distributed environments. Typically implemented as at-least-once + idempotent handling for "effectively once"; pure exactly-once is closer to an illusion.

Key Patterns

  • Event Sourcing: Store the sequence of state-change events rather than current state. Enables full history tracking and reconstruction.
  • CQRS (Command Query Responsibility Segregation): Separate the write (Command) model from the read (Query) model. Often combined with event sourcing.
  • Saga: Manage a distributed transaction across multiple services via compensating transactions.
    • Orchestration: A central orchestrator directs and coordinates each step in order. The flow is explicit, but introduces central coupling.
    • Choreography: Each service listens to events and publishes the next event, progressing autonomously. Low coupling, but the flow is hard to trace.

When to Use EDA

  • Good fit: When loose coupling between components is needed, asynchronous processing/fan-out/streaming, high scalability, audit logs (event sourcing).
  • Bad fit: When strong immediate consistency is required, simple CRUD, or a small team that cannot afford the flow-debugging cost.

Reference

Clone this wiki locally