Skip to content

Sticky routing: Redis storage layer — per-customer net habit counts #413

Description

@prajjwalkumar17

Part of #393 (sticky routing). Status: implemented in #419 (commit 575d249), pending review/merge.

One Redis hash per (merchant, customer) holds the customer's NET habit counts — successes add one, gateway failures subtract one (floored at zero; failures never create a key or field, and only positive counts qualify as pin candidates):

Key:    sticky_gw_{merchant_id}_{customer_id}          (ids trimmed, case preserved)
Field:  {PM}:{PMT}:{connector}                          (PM/PMT case-folded, connector verbatim)
Value:  integer net count (+1 success, -1 failure, floor 0)   (HINCRBY — atomic under concurrent feedback)

Example: sticky_gw_m1_cust42 → { "INTERAC:RTP:GIGADAT": 3, "INTERAC:RTP:LOONIO": 2 }. Listpack-encoded: 136 B for a typical 2-combo customer, 952 B at the 30-combo cap (measured on Redis 7.2.7) — ~150–250 MB per 1M active customers.

Eviction safety (sticky keys must never crowd out SR/elimination state):

  1. Sliding TTL on every hash, re-armed in the same MULTI as the write (STICKY_ROUTING_KEY_TTL, default 90 days). Idle customers self-evict; every key stays volatile.
  2. Per-customer combo cap (STICKY_ROUTING_MAX_COMBOS_PER_CUSTOMER, default 30): a new field over the cap prunes the lowest-count fields (full excess drains), keeping the hash listpack-encoded.
  3. Per-merchant admission budget (STICKY_ROUTING_MAX_CUSTOMERS_{mid}, default 1M new hashes per TTL window, tracked by two-window counters sticky_gw_adm_{mid}_{window} with TTL 2×window): once spent, existing customers keep updating but no new keys are created — growth bounded up front, no reliance on Redis eviction.

New wrapper commands on RedisConnectionWrapper: hincrby_with_expire (MULTI: HINCRBY+EXPIRE so a hash can never exist without a TTL), hgetall_map, hdel_field. Module: src/sticky_routing.rs.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions