Gather requirements and constraints. Identify the business capabilities the system must support. Quantify expected scale: request volume, data volume, latency requirements, consistency requirements, and availability targets (e.g., 99.9% uptime).
Identify bounded contexts. Map business domains to system boundaries. Use domain-driven design principles to separate concerns. Determine which entities are shared across contexts and which are private.
Model the data. Design the core entities, their relationships, and their access patterns. Decide on storage technology (relational, document, key-value, graph, time-series) based on query patterns and consistency needs. Draft the initial schema with indexes for known query patterns.
Design API contracts. Define the endpoints, methods, request and response schemas, error codes, and pagination strategy. Use OpenAPI or Protocol Buffers to formalize the contract. Ensure every endpoint has a defined success response, at least 3 error responses, and rate limiting specification.
Plan communication patterns. Determine which interactions are synchronous (request-response) and which are asynchronous (event-driven, message queue). Design event schemas and define delivery guarantees (at-most-once, at-least-once, exactly-once).
Design the caching layer. Identify read-heavy queries that benefit from caching. Choose cache placement and invalidation strategy. Define cache key structure, TTL values, and behavior on cache miss.
Architect for resilience. For every external dependency, define: timeout value, retry policy (count, backoff, jitter), circuit breaker thresholds, and degraded-mode behavior. Design health check endpoints and readiness probes.
Plan scaling strategy. Identify the first bottleneck that will appear under load (database connections, CPU, memory, network). Design the horizontal scaling approach: stateless services, read replicas, connection pooling, queue-based load leveling.
Document decisions. Write an Architecture Decision Record (ADR) for every significant choice. Include the context, the decision, the alternatives considered, and the consequences. These ADRs are as important as the code.
Review and validate. Walk through the design with at least one critical scenario: the happy path, a failure scenario (dependency down), and a scale scenario (10x current load). Identify gaps and iterate.