Below is a structured explanation of how a flight/hotel booking works on MakeMyTrip.
- The user logs into the MakeMyTrip platform (via website or mobile app).
- The user selects a flight or hotel they want to book.
- The user is redirected to the checkout page, where they review their selection and proceed with payment.
- The user selects HDFC Net Banking as the preferred payment method.
- A new popup window opens, redirecting the user to HDFC Net Banking (
netbanking.hdfc.com) to complete the transaction.
- Instead of waiting, the user closes the MMT checkout page while the payment is still in progress on the HDFC website.
- The user completes the payment successfully on HDFC Net Banking.
- HDFC Bank transfers the paid amount to MakeMyTrip’s bank account.
- After the transaction is successful, HDFC Bank triggers a webhook API call to MMT’s server.
- The webhook is a listener on the server that waits for payment confirmations from banks.
- The HDFC server sends the following payload (data) to MMT’s webhook API:
{
"userId": 67,
"amount": 19000,
"flightDetails": {}
}- The MMT Webhook API processes this payment confirmation.
- It updates the database for the specific userId (67).
- The booking details are added to the database, confirming the reservation.
NOTE : Never process two withdrawl request parallely, let the requests be reside in the queue and process each request sequentially at a time.
MMT uses a separate webhook server instead of merging it into the main backend for the following reasons:
- The main backend handles user authentication, bookings, and searches.
- The webhook server only listens for bank payment confirmations.
- Keeping them separate ensures better structure and organization.
- Bank webhook calls must always be processed without failure.
- If MMT’s main backend is slow or down, the webhook server still works.
- Ensures payments are never lost even during heavy traffic.
- Banks require strict security rules for webhook handling.
- A separate server allows better access control for only trusted banks.
- Different security policies ensure safer transactions.
- Webhooks work independently and don’t need an instant response.
- If a webhook request fails, it can retry automatically.
- Prevents delays in the main backend.
- As bookings grow, bank webhook traffic increases.
- MMT can scale only the webhook server instead of the entire system.
- Reduces costs and improves efficiency.
- A dedicated webhook server helps quickly find payment issues.
- Logs and errors are separate from the main backend.
- Faster troubleshooting for failed transactions.
MMT keeps a separate webhook server for banks to ensure better performance, security, reliability, and scalability while avoiding issues in the main backend. 🚀
This document explains the flow of problem submission on LeetCode, from user submission to execution and result delivery.
- A user writes and submits code via:
- Browser
- Mobile App
- The request contains:
{ "userId": 43, "problemId": 91, "language": "java", "code": "..." }
- The request is sent to the Primary Backend (BE), which handles:
/problems→ Problem-related data/contest→ Contest-related data/profile→ User profile data
- The backend processes the request and forwards it to the Queue.
- The Queue ensures smooth processing and distributes tasks efficiently to Workers (w1, w2, etc.).
- The workers execute the submitted code on LeetCode’s servers.
- Once execution is complete, the result is published via a Pub/Sub (Publish-Subscribe) system.
- Example result:
{ "userId": 43, "problemId": 91, "language": "java", "status": "TLE" } - This result is sent to users subscribed to updates for
userId: 43.
- The user's browser or mobile app subscribes to their execution results via WebSockets (
WS1,WS2,WS3). - WebSockets push the response back to the user’s interface in real-time.
- The user sees their submission result (e.g., Accepted, TLE, Wrong Answer) instantly.
✅ Efficient handling of high traffic
✅ Real-time updates for users
✅ Optimized execution via queueing & worker distribution
1. Why are we not running user code in our primary backend? Why are we delegating the task of running code to workers?
Running user-submitted code directly on the primary backend poses several risks, including:
- Performance issues – Inefficient or resource-heavy user code can slow down the entire backend.
- Security vulnerabilities – Malicious or infinite loops in user code could crash the system, impacting all users.
To prevent these issues, we delegate code execution to workers, which are independent processing units designed for handling such tasks.
Workers are dynamically scaled based on the queue length to ensure efficient resource usage:
- If the queue length is 100 → Scale up to 20 workers
- If the queue length is 3 → Scale down to 1 worker
This ensures that the primary backend remains available and responsive while workers handle the compute-intensive operations.
A queue system helps in managing and processing multiple submissions efficiently. Instead of executing user code instantly, the queue organizes and schedules tasks systematically.
- Orderly execution – Tasks are processed in sequence, avoiding bottlenecks.
- Prevents system overload – Manages sudden spikes in requests without crashing the system.
- Ensures priority-based execution – For example, premium users may get faster execution times.
- If the number of pending tasks increases, more workers are automatically added.
- When the load reduces, workers scale down, saving resources.
A Pub/Sub (Publish-Subscribe) system is used for real-time communication between the backend and clients. Since a user may be logged in on multiple devices (e.g., browser and mobile), both devices should receive the same update simultaneously.
- When a user submits a request, they subscribe to a specific topic, such as
"user:1". - Once the task is completed, the backend publishes the response to that topic.
- All devices listening to
"user:1"receive the update instantly.
✅ Real-time updates on all devices.
✅ Eliminates the need for polling, reducing backend load.
✅ Improves the overall user experience.
Workers are independent processing units that execute user-submitted code. The number of workers is dynamically adjusted based on the queue length to ensure efficient execution.
Workers can process tasks in different ways, depending on the system design:
- Single-threaded – Each worker processes one task at a time.
- Multi-threaded – A worker can execute multiple tasks concurrently.
- Prevents the primary backend from being overloaded.
- Allows better resource utilization by running multiple tasks in parallel when needed.
- Ensures scalability – more workers can be added during high demand and reduced during low activity.
By using a combination of workers, a queue system, and Pub/Sub, the system is designed for:
✅ Scalability – Dynamic worker allocation based on queue length.
✅ Efficiency – Ordered task processing without overloading the backend.
✅ Real-time Updates – Pub/Sub ensures users get instant responses across all devices.


