Skip to main content
Card class: HeroCategory: Cross-Channel: Revenue at Risk

At a glance

When Redis is the session store, the number of session keys it holds should track the number of active shoppers on the storefront. This card puts the two side by side: session-key count from the Redis keyspace against active users from the linked ecommerce connector. They will never match exactly, but they should move together. Drift between them is the alarm. Too few session keys for the live user count means sessions are being lost (evicted, expired early, or never written), which logs shoppers out mid-journey. Too many means orphaned sessions are piling up and wasting memory. Either way the gap is a direct, Redis-distinctive read on whether your session layer is keeping pace with real demand.
What it tracksLive session-key count in Redis compared against the storefront’s active-user count, with the drift between them as the headline signal.
Data sourceRedis side: count of session keys, derived from the configured session key prefix (for example a SCAN MATCH sess:* style count) and corroborated by INFO keyspace. Ecommerce side: active / live users from the linked Shopify, BigCommerce or Adobe Commerce connector.
Time windowRT/24h (real-time headline with a 24-hour trend).
Alert trigger>0 drift between session-key count and active sessions (any sustained, material gap between the two counts).
Rolesowner, engineering, operations

Calculation

The card counts the session keys Redis is holding, scoped to the application’s session key prefix so it ignores caches, queues, and counters living in the same instance. On the other side it reads the active-user count from the linked ecommerce connector for the same moment. It then computes the drift, the signed gap between the two, and flags a sustained, material divergence. The signal is Redis-distinctive: because Redis often serves as the session backend behind a storefront, the session-key population is an independent, infrastructure-side confirmation of how many people are genuinely mid-journey. A healthy store keeps the two curves close. A persistent negative drift (fewer keys than users) is the revenue-relevant case because it means real shoppers are silently being logged out.

Worked example

A fashion retailer on Adobe Commerce stores PHP sessions in Redis with a 30-minute TTL and a sess: key prefix. The instance is shared with the page cache. On 18 Apr 26 a marketing push lifts traffic, the cache grows, and maxmemory is reached. The eviction policy is left at the default noeviction on the session DB but allkeys-lru on the cache DB, except the two share one instance. The platform team watches the drift.
Time (BST)Session keys (sess:*)Active usersDriftReading
10:004,2104,350-140normal (in-flight TTL lag)
10:305,9806,100-120normal
11:006,4009,800-3,400sessions being lost
11:156,35010,200-3,850sessions being lost
Up to 10:30 the small negative drift is expected: a session key lives slightly longer than the user is active (the TTL has not lapsed yet), and some users open multiple tabs. At 11:00 the drift blows out. Active users nearly doubled but session keys barely grew, which means session writes are failing or session keys are being evicted under memory pressure from the shared cache. Shoppers who were logged in are suddenly anonymous: their carts empty, and any who were partway through checkout are bounced back to a guest state.
Why the drift opened up:
  - The shared instance hit maxmemory.
  - LRU eviction on the cache keyspace spilled over and evicted session keys too
    (sessions and cache should not share an eviction-policy fate).
  - Lost session keys = logged-out shoppers = abandoned carts.

Mitigations, in order:
  1. Move sessions to a dedicated Redis (or a dedicated logical DB with its own policy)
     so cache pressure can never evict a live session.
  2. Set the session keyspace to a policy that protects keys with a TTL (volatile-* )
     rather than allkeys-lru.
  3. Raise maxmemory / scale the node so the cache stops competing with sessions.
The owner’s reading is direct: for the busiest 45 minutes of the day, a large block of shoppers was being logged out mid-shop, which shows up downstream as a cart-abandonment spike and a conversion dip. The drift card caught the cause (sessions evicted) before the conversion report even refreshed.

Sibling cards

CardWhy pair it with this cardWhat the combination tells you
Total Keys (db0)The full keyspace count behind the session subset.A flat total with rising users confirms sessions are not being written.
Evicted Keys / minuteThe eviction signal that explains lost sessions.Negative drift co-occurring with evictions equals sessions being evicted, the worst case.
Memory Used vs Maxmemory %The memory-pressure context.Drift opening as memory nears maxmemory confirms cache is starving sessions.
Expired Keys / minuteThe TTL-expiry rate.A spike here means sessions are timing out faster than expected, an alternative cause of negative drift.
Connected Clients Saturation vs Traffic BurstThe connection-side cross-channel join.Confirms whether session writes are failing because connections were refused.
Redis OPS Spike vs Ecom Order RateThe throughput-side cross-channel join.Helps tell real user growth from bot traffic that inflates the active-user count without real sessions.
Operations per Second (live)The raw throughput baseline.Flat ops with rising users hints that session writes are not even being attempted.

Reconciling against the source

Where to look natively:
redis-cli --scan --pattern 'sess:*' | wc -l to count session keys by prefix (use SCAN, never KEYS, on a live instance, as KEYS blocks the server). redis-cli INFO keyspace for the keys= and expires= totals on db0, which bound the session count from above. redis-cli DBSIZE for the total key count if all sessions live in one DB. redis-cli TTL sess:<id> to confirm individual session lifetimes match the application’s configured timeout.
On the application side: compare against the storefront’s own active-session or concurrent-user figure (Adobe Commerce admin, Shopify / BigCommerce analytics) for the same minute. Why our number may legitimately differ:
ReasonDirectionWhy
TTL lagKeys slightly exceed usersA session key persists until its TTL lapses, so it outlives the user’s last action by minutes; a small positive cushion of keys over active users is normal.
Multiple tabs / devicesKeys exceed usersOne shopper across two tabs or a phone and laptop can hold more than one session key, inflating the count relative to unique active users.
Bot trafficUsers exceed keysBots can register as active “users” on the storefront connector without ever creating a real server-side session, widening apparent negative drift.
Prefix scopeVariableIf the configured session prefix does not match every session key (multiple apps, legacy prefixes), the count understates the true session population.
Definition of “active”VariableThe connector’s active-user window (for example last 5 minutes) may differ from the session TTL, so the baseline drift shifts with that window.

Known limitations / FAQs

A small negative drift is permanent on my store. Is that a problem? Usually not. A steady small gap, where active users slightly exceed session keys, is often just bot traffic or analytics counting visitors who never created a server-side session. The card cares about a sustained, material change in drift, not the constant background offset. Set the threshold in the Sensitivity tab to your normal baseline so routine noise does not alert. My drift is positive, more session keys than active users. Should I act? Mild positive drift is expected from TTL lag and multi-tab users. A large, growing positive drift means orphaned sessions are accumulating: keys whose users left but whose TTL is too long, or sessions written without a TTL at all. That wastes memory and can eventually contribute to eviction pressure. Check that every session key is written with an expiry and that the TTL matches your intended timeout. We do not use Redis for sessions. Does this card apply? No. This card is meaningful only when Redis is the session backend. If sessions live in the database or another store, the session-key count will be zero or unrelated to active users, and you should disable or ignore the card. The prefix scope it uses is configured per connector. Why scope to a key prefix instead of counting all keys? A production Redis usually mixes sessions with caches, queues, and counters. Counting all keys would drown the session signal. Scoping to the application’s session prefix (for example sess: or PHPREDIS_SESSION:) isolates exactly the keys that should track active users. Active users doubled but session keys did not move at all. What does that mean? Session writes are failing outright, not just being evicted. Common causes: the connection pool is saturated so the app cannot write to Redis (check Connected Clients Saturation vs Traffic Burst), the instance is read-only after a failover, or a recent deploy changed the session prefix so new sessions are written under a name the card is not counting. How do I confirm the count without hurting the live instance? Use SCAN with a pattern, never KEYS. KEYS sess:* blocks the single-threaded server for the duration of the scan and can itself cause an incident on a busy instance. redis-cli --scan --pattern 'sess:*' iterates in safe batches.

Tracked live in Vortex IQ Nerve Centre

Redis Session Keys vs Active Ecom Users is one of hundreds of KPI pulses Vortex IQ tracks across Redis and 70+ other ecommerce connectors. Nerve Centre runs the detection layer; Vortex Mind investigates the cause when something moves; Ask Viq lets you interrogate any number in plain English. Start for free or book a demo to see this metric running on your own data.