MakeMyTrip Full Stack with Node.js Interview Questions & Answers
Curated interview practice questions with answers. These are practice scenarios, not a verified list of past interview questions.
About MakeMyTrip hiring for Full Stack with Node.js roles
MakeMyTrip is an Indian online travel company offering flights, hotels, holidays, buses and trains, and it also owns Goibibo and redBus. Its technology and analytics teams work on search, pricing, personalisation and customer service. It hires for software engineers, SDETs, business analysts and data scientists.
For Full Stack with Node.js roles, this MakeMyTrip practice set focuses most on Databases: MongoDB, SQL and Redis (5), REST API Design (5), Authentication and Security (4), Node.js Core and Event Loop (4). It has 1 easy, 20 medium, 9 hard questions, so you can start easy and work up to the harder ones.
Company type
E-commerce & consumer tech
Headquarters
Gurugram, India
Main India offices
Gurugram, Bengaluru
MakeMyTrip Full Stack with Node.js interview process
Online assessment (coding or SQL)
Technical round 1
Technical round 2 or case round
Hiring manager round
HR round
Typical pattern based on public candidate experiences. Rounds vary by role, team and year.
Solved for MakeMyTripStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
✓ 3 questions free • Unlock the rest in seconds
01
A security audit finds that users can see other users' orders by changing the order ID in the URL. How do you fix it?
This is broken object level authorisation. Every query must be scoped to the authenticated user: Order.findOne({ _id: id, userId: req.user.id }), returning 404 if not found. Put this check in a shared service or middleware so no route can skip it, add tests that try other users' IDs, and consider non-guessable IDs like UUIDs as defence in depth, not as the fix.
02
Is Node.js single-threaded? Explain the role of libuv.
Your JavaScript runs on a single main thread, but Node.js itself is not purely single-threaded. libuv, the C library under Node, provides the event loop and a thread pool (default 4 threads, set with UV_THREADPOOL_SIZE) used for file system work, DNS lookups, crypto and zlib. Network I/O uses OS async mechanisms like epoll or IOCP instead of threads.
Soft delete marks a record as deleted with a flag or deletedAt timestamp instead of removing it, so data can be restored and audited. Trade-offs: every query must filter out deleted rows, unique constraints need care, tables grow over time and privacy laws such as India's DPDP Act may require real deletion of personal data on request. Use partial indexes and periodic purging.
04
A test passes locally but fails randomly in CI. How do you approach this flaky test?
Run it repeatedly to reproduce, then look for shared state between tests, missing awaits, reliance on test order, real timers, current date or time zones, random data and network calls. Fix by isolating data per test, using fake timers, freezing dates, mocking external calls and awaiting all promises. Quarantine the test only temporarily with a ticket, never delete it silently.
05
How do you prevent server-side request forgery when your API fetches a user-supplied URL?
An attacker could make your server call internal addresses such as 169.254.169.254 for cloud metadata or localhost admin ports. Allow only http and https, resolve the hostname and block private, loopback and link-local IP ranges, use an allowlist of domains where possible, disable redirects or revalidate them, set short timeouts and size limits, and run fetchers in an isolated network.
Send a POST with a JSON event, a unique event ID and timestamp. Sign the body with HMAC-SHA256 using a per-customer secret and include it in a header, so receivers verify authenticity and reject old timestamps to stop replays. Retry failures with exponential backoff, log delivery attempts and make events idempotent so receivers can safely handle duplicates.
08
How do you handle async errors in Express 4 routes?
const asyncHandler = (fn) => (req, res, next) =>
Promise.resolve(fn(req, res, next)).catch(next);
router.get('/:id', asyncHandler(async (req, res) => {
const user = await User.findById(req.params.id);
if (!user) throw new AppError('Not found', 404);
res.json(user);
}));
// Without this, a rejected promise is never sent to the error handler.
// Express 5 does this automatically.
09
What is the difference between throwing an error and rejecting a promise inside an async function?
Inside an async function they behave the same: throw new Error() causes the returned promise to reject with that error. Outside async functions, a throw inside a plain callback such as setTimeout is not caught by promise handlers and becomes an uncaught exception. Always reject with Error objects, not strings, so you keep a stack trace.
10
Tell me about a time you had to balance speed of delivery with technical quality.
Situation: sales needed a partner API in one week for a client launch. Task: deliver fast without creating a mess. Action: I agreed with my manager to ship the core endpoints with validation, auth and tests, and to defer caching and admin tooling, logging them as tickets with dates. Result: the partner went live on time, and we completed the deferred work in the next sprint as planned.
11
How would you handle uncaughtException and unhandledRejection in production?
Log both with full stack traces and context, then exit the process after flushing logs, because state may be corrupted. A process manager like PM2, systemd or Kubernetes restarts it. Never use uncaughtException to keep running as if nothing happened. Since Node 15, unhandled rejections crash the process by default, so every promise chain should have proper error handling.
12
What is backpressure in streams and how does pipeline handle it?
Backpressure happens when a readable source produces data faster than the writable destination can consume it, causing memory to grow. write() returns false when the internal buffer exceeds highWaterMark, and the producer should pause until the drain event. stream.pipeline and pipe handle this automatically, and pipeline also forwards errors and destroys all streams on failure, which pipe does not.
13
A Mongoose query returns large documents and the API is slow. What optimisations can you apply?
Use .select() to fetch only needed fields, and .lean() to return plain objects instead of full Mongoose documents, which cuts memory and CPU. Make sure the filter and sort use an index, checked with explain. Paginate results, avoid populating deep references, and cache frequently read data. For large exports, use a cursor with for await instead of loading everything.
14
What is a compound index and why does field order matter?
A compound index covers multiple fields, such as { userId: 1, createdAt: -1 }. It supports queries that use a prefix of the fields, so it helps queries on userId alone or userId plus createdAt, but not createdAt alone. A good rule in MongoDB is ESR: put equality fields first, then sort fields, then range fields, to avoid in-memory sorts.
15
How do you limit concurrency when calling an external API for 10,000 records?
Browsers block cross-origin requests unless the server sends CORS headers. Use the cors package: app.use(cors({ origin: ['https://app.example.com'], credentials: true })). Avoid origin '*' with credentials, and restrict methods and headers you allow. CORS is a browser protection, not a security layer for your API, so you still need authentication and authorisation.
17
Your app gets 'too many connections' errors from PostgreSQL after scaling to 20 pods. What would you do?
Each pod opens its own pool, so 20 pods with max 20 connections need 400, beyond the database limit. Reduce the per-pod pool size, put PgBouncer or RDS Proxy in front of the database for transaction pooling, and make sure connections are released, for example client.release() in finally blocks. Also check for long-running idle transactions holding connections.
18
A partner integration retries POST requests on timeouts and creates duplicate orders in your API. How would you redesign the endpoint?
Require an Idempotency-Key header on order creation and store it with a unique index alongside the created order ID and response. On a repeated key with the same payload, return the original response; with a different payload, return 409 or 422. Also add a unique business constraint such as partner order reference, respond quickly by queueing slow work, and document retry behaviour for partners.
19
How would you add OTP-based login for an Indian mobile app?
Generate a random 6-digit OTP with crypto.randomInt, store only its hash in Redis with a 5-minute TTL and an attempt counter, and send it through an SMS provider on a DLT-registered template. Verify with a timing-safe compare, limit to about 3 to 5 attempts and rate limit sends per number and IP. On success, issue access and refresh tokens and delete the OTP.
20
What are the common strategies for API versioning?
URL versioning like /api/v1/orders is the most common and easy to route and cache. Header versioning uses a custom header or Accept media type, keeping URLs clean but less visible. Query versioning like ?version=2 is simple but messy. Whatever you choose, version only for breaking changes, support old versions for a deprecation period and announce sunset dates.
Express 5, now the stable line, forwards rejected promises from async handlers to error middleware automatically. It updates path-to-regexp, so route patterns are stricter: wildcards must be named and some regex characters are no longer allowed in strings. Deprecated methods such as res.send(status) and req.param() were removed, and it requires a modern Node.js version. Upgrade by running tests and checking route patterns.
22
How would you design an API for a long-running task such as exporting a 1 GB report?
Do not keep the HTTP request open. POST /exports creates a job, pushes it to a queue and returns 202 Accepted with a job ID and status URL. Clients poll GET /exports/:id or receive a webhook or WebSocket event. A worker generates the file, uploads it to object storage, and the status endpoint returns a short-lived signed download URL.
23
Tell me about a time you found a security issue in code and how you handled it.
Situation: during code review I noticed an admin export route that only hid the button in the frontend. Task: make sure no regular user could call it. Action: I reproduced it with a normal user token, reported it privately to my lead, added role middleware and tests, and checked similar routes. Result: we fixed four endpoints before release and added an authorisation checklist to pull requests.
24
How do you manage database schema migrations in a Node.js project?
Use a migration tool such as Prisma Migrate, Knex, Sequelize CLI or TypeORM migrations, and commit migration files to Git. Each migration has up and ideally down steps and runs in CI and before deployment. For zero downtime, use expand and contract: add new columns first, deploy code that writes both, backfill, switch reads, then drop old columns in a later release.
25
What is the difference between process.nextTick and setImmediate?
process.nextTick queues a callback to run immediately after the current operation, before the event loop continues to any phase, even before promise microtasks. setImmediate queues a callback for the check phase of the next loop iteration. Overusing nextTick recursively can starve I/O because the loop never moves on, so setImmediate is safer for deferring heavy work.
26
Explain the difference between Promise.all, Promise.allSettled, Promise.race and Promise.any.
Promise.all resolves with all results when every promise fulfils, and rejects as soon as one rejects. Promise.allSettled waits for all and returns each status and value or reason, useful when partial failure is fine. Promise.race settles with the first promise to settle, often used for timeouts. Promise.any resolves with the first fulfilled promise and rejects only if all reject.
27
Implement cursor-based pagination for a products endpoint.
Inject a clock function instead of calling Date.now directly, or use Jest fake timers: jest.useFakeTimers().setSystemTime(new Date('2026-01-01')). Then test before, exactly at and after expiry. Store dates in UTC and convert for display in IST, which avoids bugs near midnight. Reset timers after each test with jest.useRealTimers to avoid leaking into other tests.
29
How do you prepare a Node.js app for production readiness review?
I check that config is validated, secrets are in a secret store, and logs are structured with request IDs. Health and readiness endpoints exist, graceful shutdown works, timeouts and retries are set on outbound calls, and rate limiting and helmet are enabled. Dashboards, alerts and runbooks are ready, load tests pass targets, backups are verified and a rollback plan is documented.
30
How do you optimise JSON serialisation for very large API responses?
Large JSON.stringify calls block the event loop. Reduce payload size with pagination and field selection first. For unavoidable large outputs, stream the response as NDJSON or a streamed JSON array, use schema-based fast serialisers like fast-json-stringify, which Fastify uses, and cache precomputed responses. Offload heavy transformation to worker threads or background jobs that write files to storage.
Tips to crack the MakeMyTrip Full Stack with Node.js interview
Prepare cases on travel funnels, such as drop-offs between search and booking or hotel conversion rates.
Practise testing scenarios for booking flows, including fare changes, payments, cancellations and refunds across flights and hotels.
Read about MakeMyTrip, Goibibo and redBus to understand its multi-brand travel business.
Keep a one-minute story ready for every project on your CV: problem, your part, tools, result.
Practise the hard questions on this page aloud; MakeMyTrip interviewers usually ask follow-ups on your first answer.
Frequently asked questions
How many rounds are there in the MakeMyTrip Full Stack with Node.js interview?
Candidates usually go through 5 stages: Online assessment (coding or SQL); Technical round 1; Technical round 2 or case round; Hiring manager round; HR round. The exact rounds change with the role, team, location and your experience, so confirm the process with the recruiter.
Which topics should I prepare for the MakeMyTrip Full Stack with Node.js interview?
This practice set leans on Databases: MongoDB, SQL and Redis (5), REST API Design (5), Authentication and Security (4), Node.js Core and Event Loop (4). Revise those first, then practise explaining one or two of your own projects end to end, because most MakeMyTrip interviewers ask you to walk through real work.
Are these the exact questions asked at MakeMyTrip?
No. These are curated practice questions that match the skills and difficulty usually tested in e-commerce & consumer tech interviews like MakeMyTrip's. They are not a leaked or verified list of past questions.
Where does MakeMyTrip hire Full Stack with Node.js professionals in India?
MakeMyTrip has large teams in Gurugram, Bengaluru. Openings and locations change often, so check the MakeMyTrip careers page and filter by city and experience.
Full Stack with Node.js questions for similar companies