Start with requirements
Design a booking service by listing users, booking creation, cancellation and availability queries. State expected traffic, data size and acceptable latency as assumptions. Separate functional behaviour from reliability and performance goals before drawing infrastructure.
Model a working first version
Define API requests and responses, database entities and a transaction that prevents double booking. Start with a single application and relational database. Trace one request end to end and identify the component that owns each consistency rule.
Scale from a measured bottleneck
Add an index before adding an entire caching layer. If caching is justified, define keys, expiry and invalidation. If background jobs are needed, plan retries and idempotency so repeated delivery cannot create duplicate bookings or notifications.
Explain failure behaviour
Describe what happens when a database is unavailable, a client retries or a worker crashes after completing work. Document monitoring, timeout choices and recovery. Deliver a diagram, API sketch, schema and tradeoff table; there is no single architecture that fits every workload.
System design lab: prevent duplicate bookings
Write a sequence of two clients requesting the last seat at the same time. Identify where availability is checked and where ownership becomes permanent. Propose a database constraint or transactional update that enforces the rule, then show what each client receives. Add an idempotency key for a retried booking request and describe how it is stored. Review the design against one worker crash, one timeout and one repeated request.
Check your progress
Keep your working files, test cases and notes together. Explain one design decision, demonstrate a failure case and list what you would improve next. These concrete outputs make it easier to identify the next skill to practice.