Back to Machine Coding
Machine Coding
easy
mid

How would you implement a cart system with real time price updates?

Model the cart as line items with quantities; compute totals as derived state. Apply optimistic UI on user actions, reconcile prices/availability/promotions with the server (the source of truth for money), and push live changes via WebSocket/polling. Handle conflicts gracefully.

7 min read·~25 min to think through

A cart looks simple but has a sharp edge: prices are money, and money must come from the server. The client renders and predicts; the server is authoritative.

Data model

ts
cart = {
  items: [{ id, productId, qty, unitPrice, name }],
  // derived, never stored:
  subtotal, discount, tax, shipping, total
}

Totals are derived state — compute them, don't store them, or they drift.

Local interactions: optimistic UI

Add / remove / change quantity should feel instant:

  1. Update local state immediately.
  2. Fire the API call in the background.
  3. On success, reconcile with the server response.
  4. On failure, roll back and show a clear message.

useReducer (or a store) is a clean fit — actions like ADD_ITEM, SET_QTY, SERVER_RECONCILE.

Why the server must own pricing

The client can't be trusted with money — never let the displayed total drive checkout. The server recomputes on every cart mutation and at checkout, accounting for:

  • Price changes (catalog updated since the item was added).
  • Stock / availability changes.
  • Promotions, coupons, tiered discounts, tax, shipping.
  • Currency and region.

The client shows a prediction; the server returns the truth; the UI reconciles and flags differences ("Price updated from $20 to $18").

Real-time updates

Prices/stock can change while the cart is open:

  • WebSocket or SSE subscription to the products in the cart, or poll on a sensible interval / on tab focus.
  • On a change, update the line item and surface it — don't silently change the total. "This item's price changed" with the old and new value.
  • Re-validate everything at checkout regardless — real-time updates are UX, the checkout re-check is correctness.

Persistence

  • Logged-in: persist server-side so the cart follows the user across devices.
  • Guest: localStorage, then merge into the server cart on login.
  • Cross-tab: storage event or the store's persistence layer to keep tabs consistent.

Conflict handling

  • Item went out of stock → mark it, remove from total, tell the user.
  • Quantity exceeds stock → clamp and notify.
  • Coupon expired → drop it, recompute, explain.
  • Always fail loud and clear — silent money changes destroy trust.

Edge: race conditions

Rapid quantity clicks → debounce the API calls or cancel in-flight requests; reconcile to the last server response, not whichever returns last.

Follow-up questions

  • Why can't the client be trusted to compute the final price?
  • How do you merge a guest cart into a user's cart on login?
  • How do you handle rapid quantity changes without race conditions?
  • Optimistic update rollback — how do you implement it cleanly?

Common mistakes

  • Storing computed totals instead of deriving them — they drift out of sync.
  • Trusting client-side prices at checkout.
  • Silently changing the total when a price updates instead of surfacing it.
  • Not handling optimistic-update failure, leaving the UI in a wrong state.

Performance considerations

  • Debounce quantity updates to cut API chatter. Derive totals with memoized selectors. For real-time price feeds, subscribe only to in-cart products, not the whole catalog. Reconcile to the latest server state, not the last-arriving response.

Edge cases

  • Item goes out of stock while in the cart.
  • Price changes between add-to-cart and checkout.
  • Guest cart merge conflicts with an existing user cart.
  • Rapid quantity clicks causing out-of-order API responses.

Real-world examples

  • E-commerce checkout where the server re-prices the cart on every mutation and at the final step.
  • Marketplace carts showing 'price dropped' / 'only 2 left' live banners.

Senior engineer discussion

Seniors lead with the trust boundary — the server owns money, the client owns responsiveness — and design the reconcile loop around it. They cover optimistic UI with rollback, derived vs stored totals, guest-cart merge, race conditions from rapid input, and the principle that real-time updates are UX sugar while the checkout re-validation is the correctness guarantee.

Related questions