A new pricing algorithm is live behind a feature flag and is causing wrong charges. How do you design flags, rollback, and safety so you can disable it instantly without redeploying — and still reconcile wrong charges?
How I frame it
Feature flags are an operational control plane, not just A/B sugar. For money paths: kill switch must be global within seconds, default-safe, audited, and paired with a reconciliation plan for already-wrong charges.
Flag design for pricing
- Flag type: Kill switch boolean + optional percentage rollout. Server-side evaluation only — never trust client for price.
- Config source: Remote config (LaunchDarkly / Unleash / internal) with edge cache TTL ≤ few seconds; on config outage → fail closed to old pricing.
- Versioned algorithm id: Persist
pricing_versionon each order / quote so you know which brain charged the customer. - Dual-run shadow (before full on): Compute new price, log diff, charge old — catch bias before money moves.
Incident: wrong charges 1. Flip pricing_v2 → OFF (seconds) 2. All new checkouts use pricing_v1 3. Query orders WHERE pricing_version=v2 AND created > incident_start 4. Refund / adjust delta via finance playbook
Instant disable without redeploy
- Change flag in UI / API; SDKs stream or poll; app reads boolean each request / quote.
- Break-glass: env override or local file on ops jump host if vendor is down — documented.
- Separate "kill switch" from experiment flag so analysts cannot re-enable during incident without dual control.
Reconcile wrong charges
- Identify cohort by
pricing_version+ time window. - Recompute correct price with v1; if overcharged → refund delta (idempotent per order).
- If undercharged → policy (absorb vs charge) — usually absorb + notify legal.
- Customer comms template ready; freeze related promotions if needed.
Weak answer
"Revert the Git commit and redeploy." Takes minutes to hours; more bad charges land. "Flag in the mobile app." Stolen APK / old clients ignore you.
Follow-up questions
Flag evaluated differently on 2 app servers?
Sticky assignment by user_id hash; short cache; for pricing prefer global % with consistent bucketing and fast propagation over sticky long TTL.
Canary vs flag?
Canary = binary traffic split; flag = behavior inside binaries. Use both — canary limits blast radius; flag disables logic instantly inside the canary/all pods.