Skip to content

Swiggy 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 Swiggy hiring for Full Stack with Node.js roles

Swiggy is an Indian on-demand delivery platform offering food delivery, Instamart quick commerce and Dineout. Its technology and analytics teams work on delivery time prediction, partner allocation, pricing and customer experience. It hires for software engineers, SDETs, business analysts, data analysts and data scientists. Analysts frequently work closely with operations teams.

For Full Stack with Node.js roles, this Swiggy practice set focuses most on Asynchronous JavaScript (6), Databases: MongoDB, SQL and Redis (5), Deployment, Scaling and Performance (5), Testing and Debugging (4). It has 2 easy, 19 medium, 9 hard questions, so you can start easy and work up to the harder ones.

Company type
E-commerce & consumer tech
Headquarters
Bengaluru, India
Main India offices
Bengaluru, Hyderabad

Swiggy Full Stack with Node.js interview process

  1. Online assessment (coding or SQL)
  2. Technical or case round
  3. Hiring manager round
  4. HR round

Typical pattern based on public candidate experiences. Rounds vary by role, team and year.

Solved for SwiggyStart 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

Implement the cache-aside pattern with Redis for a product lookup.

Save to ▾
Show answer
async function getProduct(id) { const key = `product:${id}`; const cached = await redis.get(key); if (cached) return JSON.parse(cached); const product = await Product.findById(id).lean(); if (product) { await redis.set(key, JSON.stringify(product), { EX: 300 }); } return product; } async function updateProduct(id, data) { await Product.updateOne({ _id: id }, data); await redis.del(`product:${id}`); // invalidate }
02

What is connection pooling and why is it important in Node.js?

Save to ▾
Show answer
Opening a database connection is slow, so a pool keeps a set of open connections that requests borrow and return. pg Pool, mysql2 and the MongoDB driver all pool by default. Size the pool based on database limits and instance count; too small causes waiting, too large overloads the database. In serverless functions, reuse the client across invocations or use a proxy like RDS Proxy.
03

What is a compound index and why does field order matter?

Save to ▾
Show answer
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.
04

What is the difference between throwing an error and rejecting a promise inside an async function?

Save to ▾
Show answer
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.
05

Production shows intermittent 502 errors from the load balancer but your app logs show nothing. How do you investigate?

Save to ▾
Show answer
A 502 means the load balancer got a bad or no response from the app. Check whether pods restarted or crashed through OOM kills, health check failures and deployment times. A common Node cause is keep-alive mismatch: set server.keepAliveTimeout higher than the load balancer idle timeout and headersTimeout above that. Also check event loop blocking and connection limits.
06

Explain OAuth 2.0 and the Authorization Code flow with PKCE.

Save to ▾
Show answer
OAuth 2.0 lets an app access resources on a user's behalf without seeing their password, for example social login with an existing account. In Authorization Code with PKCE, the app creates a code verifier and sends its hash to the authorisation server. The user logs in and consents, the app receives a code and exchanges it plus the verifier for tokens. PKCE stops intercepted codes being reused.
07

A dashboard endpoint makes five independent database queries one after another and takes 1.5 seconds. How would you speed it up?

Save to ▾
Show answer
Because the queries are independent, run them concurrently with Promise.all so total time is close to the slowest query instead of the sum. Check that the database connection pool is large enough to serve them in parallel. Then add indexes for slow queries, cache rarely changing parts in Redis, and use Promise.allSettled if the page can render with some widgets missing.
08

How do you design an API that needs to handle 50,000 requests per second for reading product details?

Save to ▾
Show answer
Make the read path cache-heavy: CDN caching for public product pages, Redis cache for product details with high hit ratio, and database read replicas behind it. Run many stateless Node instances with autoscaling, keep responses small and compressed, and use keep-alive connections. Avoid cache stampedes with request coalescing or locks, and precompute data that is expensive to build.
09

Write a Dockerfile for a production Node.js API.

Save to ▾
Show answer
FROM node:22-alpine AS deps WORKDIR /app COPY package*.json ./ RUN npm ci --omit=dev FROM node:22-alpine ENV NODE_ENV=production WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . USER node EXPOSE 3000 HEALTHCHECK CMD wget -qO- http://localhost:3000/health || exit 1 CMD ["node", "src/server.js"]
10

A Mongoose query returns large documents and the API is slow. What optimisations can you apply?

Save to ▾
Show answer
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.
11

How do you implement rate limiting on a login endpoint?

Save to ▾
Show answer
const rateLimit = require('express-rate-limit'); const { RedisStore } = require('rate-limit-redis'); const loginLimiter = rateLimit({ windowMs: 15 * 60 * 1000, limit: 5, standardHeaders: 'draft-7', legacyHeaders: false, keyGenerator: (req) => `${req.ip}:${req.body.email}`, store: new RedisStore({ sendCommand: (...a) => redis.sendCommand(a) }) }); app.post('/auth/login', loginLimiter, login); // Add account lockout or CAPTCHA after repeated failures.
12

A regex in your validation code makes the server hang on certain inputs. What is the issue?

Save to ▾
Show answer
This is likely ReDoS, regular expression denial of service. Patterns with nested quantifiers such as (a+)+ can backtrack exponentially on crafted input, blocking the event loop. Fix by simplifying the regex, limiting input length before matching, using well-tested validators like validator.js, or a linear-time engine such as re2. Add tests with long malicious strings.
13

A new developer pushes code that breaks the login API in staging. How would you prevent this in future?

Save to ▾
Show answer
Add automated checks before merge: unit and integration tests for login in the CI pipeline, branch protection requiring green builds and at least one review, linting and type checks. Add a smoke test that runs after each staging deploy and alerts on failure. Treat it as a blameless learning moment and pair with the developer to write the missing tests.
14

What is soft delete and what are its trade-offs?

Save to ▾
Show answer
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.
15

Your service calls three microservices and fails completely if one is down. How would you make it more resilient?

Save to ▾
Show answer
Use Promise.allSettled so one failure does not reject everything, and return partial data with clear flags. Add timeouts to every call, retries with backoff for transient errors and a circuit breaker such as opossum to stop hammering a failing service. Provide fallbacks like cached values and log failures with correlation IDs so the issue can be traced.
16

Write code to verify an HMAC signature on an incoming webhook in Express.

Save to ▾
Show answer
const crypto = require('crypto'); app.post('/webhooks/payment', express.raw({ type: 'application/json' }), (req, res) => { const sig = req.get('X-Signature') || ''; const expected = crypto .createHmac('sha256', process.env.WEBHOOK_SECRET) .update(req.body) .digest('hex'); const ok = sig.length === expected.length && crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected)); if (!ok) return res.status(401).end(); handleEvent(JSON.parse(req.body)); res.status(200).end(); });
17

How do you handle a breaking API change request from a product manager close to a release?

Save to ▾
Show answer
I would first understand why it is needed and who consumes the API. Then I explain the impact on existing clients, propose a non-breaking path such as adding a new field or a v2 endpoint, and estimate effort and risk. Result in a past case: we shipped the additive change on time and scheduled removal of the old field for the next quarter.
18

After adding a new middleware, all routes return 404 or hang. How do you debug it?

Save to ▾
Show answer
A hang usually means the middleware never calls next() or sends a response on some path. A 404 often means it was mounted with a wrong path or registered after routes. I check order of app.use calls, add logging at the start and end of the middleware, verify every branch calls next or responds, and check async code passes errors to next.
19

How do you design Express middleware that checks user roles for a route?

Save to ▾
Show answer
Create a factory: const authorize = (...roles) => (req, res, next) => roles.includes(req.user?.role) ? next() : res.status(403).json({ error: 'Forbidden' }). Use it after authentication, for example router.delete('/:id', authenticate, authorize('admin'), handler). Keep roles and permissions in config or the database, and for complex rules move to permission-based checks or a policy library.
20

How do you scale a Node.js application horizontally?

Save to ▾
Show answer
Run multiple stateless instances behind a load balancer and add more as load grows, using autoscaling on CPU, memory or request rate. Keep state out of the process: sessions in Redis, files in object storage, jobs in a queue. Use Redis adapters for WebSocket broadcasting across instances, and make sure the database can handle the total connection count.
21

Two simultaneous requests both read a wallet balance, deduct money and save it, causing a wrong balance. How do you fix this race condition?

Save to ▾
Show answer
Async code interleaves between awaits, so read-modify-write is unsafe. Make the update atomic in the database: use an UPDATE with balance = balance - amount WHERE balance >= amount, or MongoDB $inc with a filter. Alternatives are row-level locks with SELECT FOR UPDATE inside a transaction, optimistic locking with a version column, or a Redis distributed lock for cross-service work.
22

How do you use a message queue to process background jobs in Node.js?

Save to ▾
Show answer
const { Queue, Worker } = require('bullmq'); const connection = { host: 'redis', port: 6379 }; const emailQueue = new Queue('email', { connection }); await emailQueue.add('welcome', { userId }, { attempts: 5, backoff: { type: 'exponential', delay: 1000 }, jobId: `welcome:${userId}` }); new Worker('email', async (job) => { await sendWelcomeEmail(job.data.userId); }, { connection, concurrency: 10 });
23

How do you use the Node.js cluster module to use all CPU cores?

Save to ▾
Show answer
const cluster = require('cluster'); const os = require('os'); if (cluster.isPrimary) { for (let i = 0; i < os.availableParallelism(); i++) cluster.fork(); cluster.on('exit', (worker) => { console.log(`Worker ${worker.process.pid} died, restarting`); cluster.fork(); }); } else { require('./server'); // each worker listens on the same port } // In Kubernetes, prefer one process per container and more replicas.
24

How do you limit concurrency when calling an external API for 10,000 records?

Save to ▾
Show answer
async function runLimited(items, limit, worker) { const results = []; let i = 0; async function next() { while (i < items.length) { const idx = i++; results[idx] = await worker(items[idx]); } } await Promise.all(Array.from({ length: limit }, next)); return results; } await runLimited(records, 10, callPartnerApi); // Or use the p-limit package.
25

Tell me about a time you improved code quality in a backend codebase you inherited.

Save to ▾
Show answer
Situation: I joined a project where Express routes contained SQL, business logic and responses in 300-line handlers. Task: reduce bugs without stopping feature work. Action: I proposed a controller-service-repository structure, added an error handler, validation with zod and tests for each refactored route, and moved one module per sprint. Result: bug reports dropped and new developers onboarded faster.
26

How do you implement and secure webhooks that your API sends to customers?

Save to ▾
Show answer
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.
27

How does async/await work under the hood?

Save to ▾
Show answer
An async function always returns a promise. await pauses that function until the awaited promise settles, then resumes it with the value or throws the rejection, while the event loop keeps running other work. Internally it is built on promises and generator-like suspension. The code reads like synchronous code but is still non-blocking, and errors are handled with ordinary try/catch.
28

Tell me about a production incident you handled and what you did after it.

Save to ▾
Show answer
Situation: our payment callback endpoint started failing after a deploy on a Friday evening. Task: I was on call. Action: I checked error logs, saw a missing environment variable, rolled back within ten minutes, then added startup config validation and a post-deploy smoke test. Result: impact was limited to a few failed callbacks we replayed, and I wrote a blameless postmortem the team used to improve deploy checks.
29

What is the difference between app.use and app.get?

Save to ▾
Show answer
app.use mounts middleware for all HTTP methods and matches any path that starts with the given prefix, for example app.use('/api', router). app.get registers a handler only for GET requests on an exact route pattern. Use app.use for cross-cutting concerns like parsing and auth, and method-specific functions such as get, post, put and delete for endpoints.
30

npm audit reports a critical vulnerability in a dependency of a dependency. What do you do?

Save to ▾
Show answer
First check whether the vulnerable code path is actually reachable in our usage and read the advisory. Try npm audit fix or updating the parent package to a version that pulls a patched sub-dependency. If none exists, use the overrides field in package.json to force a safe version and run tests. Track it in a ticket and enable Dependabot or Renovate for ongoing updates.

Tips to crack the Swiggy Full Stack with Node.js interview

  • Prepare cases on order delivery time, delivery partner utilisation or Instamart stock-outs, which match Swiggy's core problems.
  • Practise SQL on order-level data, including retention, repeat rate and funnel conversion calculations.
  • Use the Swiggy app critically and be ready to suggest improvements with metrics to track their impact.
  • 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; Swiggy interviewers usually ask follow-ups on your first answer.

Frequently asked questions

How many rounds are there in the Swiggy Full Stack with Node.js interview?

Candidates usually go through 4 stages: Online assessment (coding or SQL); Technical 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 Swiggy Full Stack with Node.js interview?

This practice set leans on Asynchronous JavaScript (6), Databases: MongoDB, SQL and Redis (5), Deployment, Scaling and Performance (5), Testing and Debugging (4). Revise those first, then practise explaining one or two of your own projects end to end, because most Swiggy interviewers ask you to walk through real work.

Are these the exact questions asked at Swiggy?

No. These are curated practice questions that match the skills and difficulty usually tested in e-commerce & consumer tech interviews like Swiggy's. They are not a leaked or verified list of past questions.

Where does Swiggy hire Full Stack with Node.js professionals in India?

Swiggy has large teams in Bengaluru, Hyderabad. Openings and locations change often, so check the Swiggy careers page and filter by city and experience.

Full Stack with Node.js questions for similar companies