Zepto 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 Zepto hiring for Full Stack with Node.js roles
Zepto is an Indian quick commerce company delivering groceries and daily essentials from dark stores within minutes. Its technology and analytics teams work on demand forecasting, inventory, dark store operations, delivery routing and app experience. It hires for software engineers, SDETs, business analysts, data analysts and data scientists.
For Full Stack with Node.js roles, this Zepto practice set focuses most on REST API Design (7), Authentication and Security (5), Deployment, Scaling and Performance (4), Asynchronous JavaScript (4). It has 2 easy, 23 medium, 5 hard questions, so you can start easy and work up to the harder ones.
Company type
E-commerce & consumer tech
Headquarters
Mumbai, India
Main India offices
Mumbai, Bengaluru
Zepto Full Stack with Node.js interview process
Online assessment or take-home assignment
Technical or case round
Hiring manager round
Founder or leadership round
Typical pattern based on public candidate experiences. Rounds vary by role, team and year.
Solved for ZeptoStart 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
npm audit reports a critical vulnerability in a dependency of a dependency. What do you do?
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.
02
How do you implement rate limiting on a login endpoint?
If you pass req.body directly into a query, an attacker can send { "password": { "$ne": null } } and bypass checks. Prevent it by validating and casting input types with zod or Joi, rejecting objects where strings are expected, enabling Mongoose strictQuery and sanitizeFilter, and never building queries from raw user objects. Avoid $where and server-side JavaScript evaluation.
04
What is idempotency and how do you implement idempotency keys for a payment API?
An idempotent operation gives the same result when repeated. For POST /payments, the client sends a unique Idempotency-Key header. The server stores the key with the request hash and response, for example in Redis or a table with a unique index. If the same key arrives again, it returns the saved response instead of charging twice. Keys expire after about 24 hours.
05
How do you prioritise when multiple teams ask you for backend changes at the same time?
I list the requests with their business impact, deadlines and effort, then discuss priority with my manager or product owner rather than deciding alone. I communicate clear timelines to each team, look for shared solutions such as one generic endpoint serving two needs, and protect time for urgent production issues. This keeps expectations realistic and avoids half-finished work.
06
A dashboard endpoint makes five independent database queries one after another and takes 1.5 seconds. How would you speed it up?
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.
07
How do you read a large file efficiently in Node.js?
const fs = require('fs');
const readline = require('readline');
async function countErrors(path) {
const rl = readline.createInterface({
input: fs.createReadStream(path),
crlfDelay: Infinity
});
let count = 0;
for await (const line of rl) {
if (line.includes('ERROR')) count++;
}
return count;
}
// Streams line by line, so a 5 GB log uses little memory.
08
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.
09
After adding a new middleware, all routes return 404 or hang. How do you debug it?
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.
10
Write a basic GitHub Actions workflow that tests and builds a Node.js app.
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.
12
Implement the cache-aside pattern with Redis for a product lookup.
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.
14
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.
15
How do you use the Node.js cluster module to use all CPU cores?
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.
16
What is SQL injection and how do you prevent it in Node.js?
SQL injection happens when user input is concatenated into a query, letting attackers change it, for example ' OR 1=1 --. Prevent it with parameterised queries, such as pool.query('SELECT * FROM users WHERE email = $1', [email]) in pg, or an ORM like Prisma or Sequelize that parameterises automatically. Also validate input and give the database user minimum privileges.
17
Write a centralised error handler with a custom AppError class.
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.
REST exposes multiple endpoints with fixed response shapes, uses HTTP caching easily and is simple to reason about. GraphQL exposes one endpoint where clients query exactly the fields they need, reducing over-fetching and multiple round trips, which helps mobile apps. GraphQL adds complexity: N+1 query risks needing DataLoader, harder caching, query cost limits and schema governance.
20
How does the this keyword behave in arrow functions compared to regular functions?
A regular function's this depends on how it is called: the object before the dot, undefined in strict mode for plain calls, or whatever bind, call or apply set. Arrow functions do not have their own this; they capture it lexically from the surrounding scope. That makes arrows ideal for callbacks inside class methods, but unsuitable as object methods that need this.
21
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.
22
How do you mock a database or external service in Jest?
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.
24
Tell me about a time you improved code quality in a backend codebase you inherited.
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.
25
How do you manage secrets such as database passwords and API keys in a Node.js app?
Never commit secrets to Git. Load them from environment variables, using a .env file only for local development and keeping it in .gitignore. In production, use a secrets manager such as AWS Secrets Manager, Azure Key Vault, HashiCorp Vault or Kubernetes secrets with encryption. Rotate keys regularly, scan repos with tools like gitleaks and validate required variables at startup.
26
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.
27
When would you use Kafka instead of a Redis-based queue like BullMQ?
BullMQ suits task queues inside one application: emails, reports, retries and scheduled jobs. Kafka is a distributed, durable event log for high-throughput streaming, where many consumer groups read the same events independently and can replay history, such as order events consumed by analytics, notifications and inventory. Kafka adds operational complexity, so use it when you need event streaming at scale.
28
How do you implement graceful shutdown in a Node.js server?
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.
30
You must change a response field name used by many clients. How do you do it without breaking them?
Treat it as a breaking change. Option one: add the new field alongside the old one, mark the old field deprecated in docs and response headers, track usage through logs and remove it after clients migrate. Option two: release it in /v2 and keep /v1 for a deprecation window. Communicate timelines clearly and add contract tests for both.
Tips to crack the Zepto Full Stack with Node.js interview
Prepare cases on dark store operations, such as reducing stock-outs, improving picking time or choosing new store locations.
Practise SQL and Python for forecasting and inventory questions, including handling daily demand data.
Show comfort with a fast-paced startup environment and give examples of taking ownership in tight timelines.
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; Zepto interviewers usually ask follow-ups on your first answer.
Frequently asked questions
How many rounds are there in the Zepto Full Stack with Node.js interview?
Candidates usually go through 4 stages: Online assessment or take-home assignment; Technical or case round; Hiring manager round; Founder or leadership 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 Zepto Full Stack with Node.js interview?
This practice set leans on REST API Design (7), Authentication and Security (5), Deployment, Scaling and Performance (4), Asynchronous JavaScript (4). Revise those first, then practise explaining one or two of your own projects end to end, because most Zepto interviewers ask you to walk through real work.
Are these the exact questions asked at Zepto?
No. These are curated practice questions that match the skills and difficulty usually tested in e-commerce & consumer tech interviews like Zepto's. They are not a leaked or verified list of past questions.
Where does Zepto hire Full Stack with Node.js professionals in India?
Zepto has large teams in Mumbai, Bengaluru. Openings and locations change often, so check the Zepto careers page and filter by city and experience.
Full Stack with Node.js questions for similar companies