Skip to content
tezvyn:

Design a variable daily-login reward system with anti-gaming controls

Source: softwareengineeringdaily.comMediumHow cards are made

Design a variable daily-login reward system with anti-gaming controls

Tests server-side reward probabilities and idempotency in distributed systems. Strong answers cover: configurable weights, idempotent tokens with DB unique constraints, rolling windows, and server-side grants.

What's really being asked

Your ability to design a server-authoritative, auditable rewards pipeline that couples probabilistic business logic with strong consistency and anti-fraud primitives. Interviewers want to see that you understand the difference between an action (a raw event like a login) and a behavior (a stateful pattern that qualifies for a reward), and that you can prevent double-granting and gaming without sacrificing configurability for growth teams.

The full answer

First, separate accrual from redemption. Accrual processes actions, matches them to campaigns, and issues points; redemption lets users spend those points on offers. Second, make probability distributions fully server-side and configurable. Store reward tiers and weights in a campaign config table so growth teams can tune a 70/25/5 split without deploying code. Third, ingest events through an idempotent conversion layer. Compute a unique token for each action based on the source event, and enforce a unique constraint on the combination of action type and token in an ActionInstance table so retries never double-grant. Fourth, implement anti-gaming controls: use rolling 24-hour windows rather than calendar days to block timezone manipulation, enforce per-user rate limiting, tie grants to verified account state rather than device ID alone, and add anomaly detection for bots farming bonuses. Fifth, keep an immutable ledger of granted rewards for auditability.

The mistakes people make

Generating the random reward on the client is the biggest red flag because it is trivial to exploit. Using simple calendar-day checks is another weak pattern since users can change timezones or system clocks to collect multiple bonuses. Storing eligibility state only in Redis without a persistent unique constraint invites race conditions and duplicate grants. A vague mention of blockchain or signed tokens without explaining the actual idempotency mechanism is also a warning sign.

What usually comes next

How would you support dynamic A/B tests that change probabilities per user cohort without downtime? How would you scale the action ingestion layer to millions of daily logins while preserving exactly-once semantics? What would you do if a bug caused incorrect probabilities for 24 hours? How do you balance fraud detection with false positives that hurt legitimate user engagement?

A concrete example

Imagine a daily login bonus with three tiers: small (10 coins, 70 percent), medium (50 coins, 25 percent), and large (200 coins, 5 percent). When a user opens the app, the client pings the server; the server emits a user_login event. A conversion layer transforms this into an Action with a token computed as hash(user_id plus floor(last_grant_timestamp divided by 86400)). The accrual service checks the ActionInstance table for this unique token; if absent, it rolls against the campaign weight table, issues points into the user's balance, and commits the ActionInstance in the same transaction. The redemption service handles spending those points later. If the user tries to replay the login event, the unique constraint rejects the duplicate ActionInstance, preventing a double grant.

Interview question

Which approach best satisfies both idempotency and anti-gaming requirements for a distributed daily-login reward system?

  • a.Use a server-side calendar-day check based on the user's local timestamp and store eligibility in Redis with a 24-hour TTL.
  • b.Compute a unique token from the user ID and rolling window, enforce a database unique constraint on that token, and resolve probabilities using server-side campaign weights.Correct
  • c.Issue cryptographically signed JWTs to the client after each login and require the client to present the most recent token to claim the next reward.
  • d.Generate the reward tier client-side using a seeded random function, then submit the result to the server for validation against a Redis-based daily counter.
Why?

Option B is correct because a rolling window prevents timezone gaming, the database unique constraint on the token guarantees idempotency, and server-side weights prevent tampering. Option A is tempting because it mentions server-side logic, but calendar-day checks are vulnerable to timezone manipulation and Redis-only storage lacks the persistent constraint needed to prevent duplicate grants under retries.

Just read this? Test yourself on what you have been reading.

Read the original → softwareengineeringdaily.com

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on growth — each one lists the topics its interview covers.

See open roles