[Experience] Meesho Machine Coding Round SDE3– Inventory Management System (with solution)

meesho logo
meesho
· SDE III
April 10, 2026 · 0 reads

Summary

I completed a machine‑coding round for an SDE3 position at Meesho, where I was asked to design an in‑memory inventory management service and I presented a thread‑safe Python implementation.

Full Experience

[Experience] Meesho Machine Coding Round – Inventory Management System (with solution) Hey everyone, Recently gave a machine coding interview at Meesho. Sharing the problem and my approach — hopefully useful for folks prepping for similar rounds at e-commerce companies.

Problem: Inventory Management Service Design an in‑memory inventory service for an e‑commerce platform with the following APIs:

  • addProduct(productId, name, count) – Register a new product
  • getInventory(productId) – Get available stock
  • updateInventory(productId, count) – Supplier restocks a product
  • blockInventory(productId, count, orderId) – Block stock when user initiates payment (holds for 5 min)
  • confirmOrder(orderId) – Permanently deduct blocked stock on payment success; if not called within 5 min, release the block automatically

Constraints:

  • In‑memory only, no DB
  • Thread‑safe (10M active users, 5M products, ~1M orders/day)
  • Handle race conditions explicitly

My Approach Data structures:

  • products dict: productId → Product object
  • quantity dict: productId → available count (separated from Product to avoid holding product‑level locks for reads)
  • product_lock dict: productId → threading.Lock() — per‑product lock so concurrent operations on different products don’t block each other
  • orders dict: orderId → Order object with expiry timestamp

Key design decisions:

  • Per‑product locking instead of a global lock — a single global lock would serialize all inventory ops across all 5M products, killing throughput. Per‑product locks mean operations on Product A and Product B are fully concurrent.
  • Optimistic block‑then‑expire pattern — when blockInventory is called, stock is immediately deducted from quantity. This prevents double‑selling. A background cleanup thread periodically scans for expired orders and releases stock back.
  • Cleanup thread — runs in a daemon thread, sleeps 1 s between scans, iterates over active orders and releases expired ones under the product lock to avoid race between expiry release and concurrent confirmOrder.

Code (Python)

import time
import threading

class Product:
    def __init__(self, product_id, name, count=0):
        self.product_id = product_id
        self.name = name
        self.count = count

class Order:
    def __init__(self, order_id, product_id, quantity, expiry):
        self.order_id = order_id
        self.product_id = product_id
        self.quantity = quantity
        self.expiry = expiry

class InventoryService:
    def __init__(self):
        self.products = {}
        self.quantity = {}
        self.product_lock = {}
        self.orders = {}

    def addProduct(self, product_id, name, inventory_count):
        if product_id in self.products:
            return
        self.products[product_id] = Product(product_id, name, inventory_count)
        self.quantity[product_id] = inventory_count
        self.product_lock[product_id] = threading.Lock()

    def getInventory(self, product_id):
        if product_id not in self.products:
            return None
        return self.quantity.get(product_id)

    def updateInventory(self, product_id, additional_quantity):
        if product_id not in self.products:
            return False
        with self.product_lock[product_id]:
            self.quantity[product_id] += additional_quantity
        return True

    def blockInventory(self, product_id, order_quantity, order_id):
        if product_id not in self.products:
            return False
        with self.product_lock[product_id]:
            if self.quantity[product_id] < order_quantity:
                return False
            self.quantity[product_id] -= order_quantity
            expiry_time = time.time() + 300  # 5 min
            self.orders[order_id] = Order(order_id, product_id, order_quantity, expiry_time)
        return True

    def confirmOrder(self, order_id):
        if order_id not in self.orders:
            return False
        order = self.orders[order_id]
        with self.product_lock[order.product_id]:
            if order_id not in self.orders:  # re-check inside lock
                return False
            del self.orders[order_id]
        return True

    def _cleanup(self):
        while True:
            time.sleep(1)
            now = time.time()
            for order_id in list(self.orders.keys()):
                order = self.orders.get(order_id)
                if order and now > order.expiry:
                    with self.product_lock[order.product_id]:
                        if order_id in self.orders:  # double‑check inside lock
                            self.quantity[order.product_id] += order.quantity
                            del self.orders[order_id]

    def start_cleanup(self):
        t = threading.Thread(target=self._cleanup, daemon=True)
        t.start()

What I'd improve with more time

  • orders dict itself needs a lock — concurrent blockInventory and _cleanup both mutate it; in production you'd use a threading.Lock or a concurrent‑safe structure around it
  • Lazy expiry — instead of a background scan, check expiry at confirmOrder time and reject stale orders; cleaner for low‑order‑volume scenarios
  • Metrics/observability — track block → confirm conversion rate, expiry rate per product
  • Persistence layer interface — even if in‑memory for now, abstract behind a repository so swapping to Redis is a single‑file change

Feel free to ask questions or suggest improvements. Happy to discuss trade‑offs on the locking strategy.

Tags: #machinecodinginterview #systemdesign #python #threading #meesho

Interview Questions (1)

1.

Inventory Management Service Design

System Design

Design an in‑memory inventory service for an e‑commerce platform with the following APIs:

  • addProduct(productId, name, count) – Register a new product
  • getInventory(productId) – Get available stock
  • updateInventory(productId, count) – Supplier restocks a product
  • blockInventory(productId, count, orderId) – Block stock when user initiates payment (holds for 5 min)
  • confirmOrder(orderId) – Permanently deduct blocked stock on payment success; if not called within 5 min, release the block automatically

Constraints:

  • In‑memory only, no DB
  • Thread‑safe (10M active users, 5M products, ~1M orders/day)
  • Handle race conditions explicitly

📣 Found this helpful? Please share it with friends who are preparing for interviews!

Discussion (0)

Share your thoughts and ask questions

Join the Discussion

Sign in with Google to share your thoughts and ask questions

No comments yet

Be the first to share your thoughts and start the discussion!