Machine coding round
Loyalty Points and Tier Management System Coding Problem
What this interview round tests
The loyalty points system is a favourite low-level design round at e-commerce and fintech companies — the Starbucks-rewards / super-coins style problem. It looks like simple arithmetic on a balance, and that is the trap: points arrive in lots with their own expiry dates, redemption must consume the oldest lots first, and tiers must be recalculated from what a member actually has right now.
Interviewers ask it because it quietly bundles three production patterns into one small domain: FIFO accounting (the same lot mechanics behind inventory and vesting systems), time-based expiry that must be applied lazily and consistently, and idempotency — the earn event that gets retried by infrastructure must never award points twice. A mutable "points" integer fails all three.
The scenario
You are handed the backend of a loyalty program. Members earn points from purchase events, redeem them for rewards, and hold a tier derived from their activity. The happy path looks plausible — and the test suite fails all over it.
Expired lots still get spent, redemption drains newer points while older ones silently expire, replayed earn events double-credit members, and tier upgrades lag or overshoot after expiry sweeps. Your job is to fix lot accounting, redemption order, tier recalculation, and event idempotency until the suite goes green.
What you’ll practice
- FIFO lot accounting: points as dated lots, not one mutable balance
- Expiry rules: excluding expired lots from balances and redemptions consistently
- Oldest-first redemption that spans partial lots correctly
- Idempotent earn events: a replayed event credits exactly once
- Tier recalculation that stays correct after earns, redemptions, and expiry
- Deterministic balances and histories so clients and tests agree
How to approach it
Model the member as a queue of point lots, each with an amount, a remaining amount, and an expiry date. Every read — balance, redemption capacity, tier input — should be derived from live lots at that moment, so expiry becomes a filter rather than a background job you have to keep consistent.
Redemption then walks lots oldest-first, consuming partially where needed, and fails atomically when the live balance is short. For idempotency, key each earn event and record the outcome the first time you see it; a replay returns that outcome instead of appending a new lot. Recalculate tier from the same derived state so it can never disagree with the balance.
The starter repository ships with a failing test suite and a bundled verify.sh. Reviewed reference solutions are part of Gronex Pro — this page stays spoiler-free on purpose.
FAQ
Why is a loyalty points system a common LLD interview question?
Because it compresses FIFO accounting, time-based expiry, and idempotent event handling into one approachable domain. Candidates who model points as a single integer hit a wall the moment expiry or replayed events appear — which is exactly the differentiation interviewers want.
What is the most common mistake in this round?
Storing one mutable balance per member. Expiry then becomes unanswerable (which points expired?), redemption order becomes meaningless, and audits are impossible. Lots-with-remaining-amounts is the pattern interviewers are looking for.
Is this problem free to try?
Yes. It is one of the free Gronex challenges — open the brief, edit in the browser workspace, and run the real test suite with zero setup, or download the starter repo and verify locally in Java, Python, or C++.