When I added a referral system to ScsDriver (my $5.50 lifetime WebDAV mount tool), I had to make a series of decisions about what to expose to users vs. keep internal. After 8 months in production, here's the actual list.
What I expose (3)
1. Daily invite cap = 3
Visible to user as "X / 3 invites used today". After hitting cap, button hides and shows "Resets in 18h 32m".
This is user-facing because the cap is the commitment. Users need to know I won't let them spam. Hiding it would create anxiety ("did my invite send?") and disputes ("my invite didn't work, give me back my trial days").
2. +14 days per accepted invite
The reward is public. Users need to know what they're optimizing for. Trial extension makes sense; users see "14 days added" appear in their account.
3. Trial expiration countdown
The trial itself is visible: "Your trial expires in 4 days". Without this, users have no urgency to invite or buy.
These three are exposed because users need them to make decisions. Everything else is internal.
What I deliberately hide (7)
1. Cumulative invite count
I track every invite ever sent. The user doesn't see this counter. Showing it would invite grinders.
2. Leaderboard (top inviters)
No public ranking of "who's invited the most". Not even in admin views.
3. Reward multipliers
No "if you invite 5+ users, +20 days instead of +14". Flat reward for everyone.
4. Streak bonuses
No "invite 3 days in a row, get bonus". Users would game this.
5. Quality scores of invitees
I score invitees internally (did they activate? did they use the product? are they a real account?). The inviter never sees these scores. Showing them would let users target "high-quality" patterns.
6. Fraud detection flags
I have an internal heuristic that flags suspicious invite patterns. The flagged user doesn't know — they're silently rate-limited.
7. Internal "ban list" for invite farms
Some IP ranges / email patterns / device fingerprints are blocked from sending invites at all. No notification. Just silent rejection.
Why hiding 7 settings matters
When I expose a setting, users optimize for it. Every metric visible becomes a target. This is Goodhart's law in product design.
If "cumulative invite count" is visible, users grind. If "top inviters" exists, users grind for rank. If "quality score" is visible, users game the quality signal. If fraud alerts are public, abusers adapt.
The cleanest referral systems hide all the meta. The user sees:
- "I sent an invite"
- "My trial got 14 more days"
- "I have 2 of 3 invites left today"
That's it. Three levers, no optimization surface.
What I learned the hard way
I shipped v1.0 with 5 exposed settings. Two of them — cumulative count and "top inviters" badge — created a measurable spike in grind behavior within 48 hours. I removed both, grind dropped to baseline in 72 hours.
Lesson: every visible metric is a honeypot for abusers. The fastest way to detect a setting is over-exposed: watch the metrics for 24-48 hours after launch. If you see a spike, you exposed too much.
The exception: opt-in power user views
I do have a /admin/referrals page for the most active inviters (top 0.1%). On that page, they see their own quality stats. They opted into power-user mode explicitly. They use it to optimize legit, not to game.
This is opt-in transparency, not default transparency. Most users never see it.
For ScsDriver specifically
Three exposed settings. Seven hidden. The exposed ones are necessary for users to use the system. The hidden ones are necessary for the system not to game itself.
If you're building referral: minimize the surface. Three exposed settings is generous. Two is better. One ("you have 14 days added") is ideal but my trial countdown required a second. The cap is the third, non-negotiable.
The takeaway
Every public metric is an attack surface. Default to hiding. Expose only what users need to make their next decision. Watch for grinder spikes in 24-48 hours after every change.
Top comments (0)