A referral system's core write happens once, at account creation, and is immutable afterwards. The design rationale is fraud resistance: if the field could be edited, users could self-refer or arbitrage commission structures after the fact.
That rationale is sound. The implementation usually is not.
The problem with write-once
Write-once solves the fraud case and creates a silent-failure case. The referrer column is nullable because signing up without a code is legitimate - so a dropped write is indistinguishable from a deliberate opt-out.
No exception. No retry. No alert. The account is created successfully and the user never learns they are unqualified.
What the fraud model actually needs
Self-referral is a write-side abuse. The constraint that matters is who can create attribution, and how often - not whether attribution can ever be read or repaired.
Three constraints do the work:
- Rate-limit attribution creation per identity document and per device fingerprint.
- Require the referrer to have an active, verified account at the time of referral.
- Cap commission-eligible referrals per referrer per period.
None of those require making the field permanently immutable. All of them target the abuse directly.
What an editable-with-audit model looks like
Instead of write-once, use write-once-with-a-pending-second-write:
- The signup write is the canonical attribution and takes effect immediately.
- A second write is allowed only within a short window (say 24 hours) and only if the first was empty.
- Every write is logged with the source (query parameter, form field, support override) and immutable in the audit trail.
This closes the silent-failure case without opening the self-referral case, because the second write cannot overwrite an existing attribution.
The observability fix
The deeper problem is that the failure is invisible to engineers too. A nullable column with no companion metric means you cannot compute a referral attribution rate, so you never discover that some percentage of signups are silently failing.
The fix is small: persist the referral parameter separately from the resolved attribution. Then a mismatch between "parameter present" and "referrer stored" is a measurable, alertable event.
Why it stays broken
The discount comes out of the customer acquisition budget. The platform pays either way. A silent failure costs the platform nothing, the user a few percent, and the referrer their commission - and only the last of those has any incentive to complain.
When a failure has no owner, it has no fix. That is the actual design lesson.
Disclosure: author has a referral code. Not financial advice.
Top comments (0)