Skip to content

(SP: 1) [Backend] Move session heartbeat from DB writes to Redis sorted set #410

@LesiaUKR

Description

@LesiaUKR

Goal

Eliminate DB writes from the session heartbeat (/api/sessions/activity). Currently each call does 2-3 SQL operations (INSERT/UPDATE + COUNT + occasional DELETE). Move to Redis sorted set — 3 commands pipelined into 1 HTTP call, zero DB writes.

Scope

  • Add heartbeatViaRedis(sessionId) — Redis sorted set online_sessions with pipeline (ZADD + ZREMRANGEBYSCORE + ZCARD)
  • Extract existing DB logic into heartbeatViaDb(sessionId) as fallback
  • POST handler: Redis first, DB fallback via nullish coalescing (??)
  • SESSION_TIMEOUT_MS constant replacing 2 duplicate calculations
  • Pattern: same as lib/quiz/quiz-answers-redis.tsgetRedisClient() null check + try/catch

Expected impact

  • Zero DB writes in normal operation; active_sessions table untouched when Redis is available
  • 2-3 SQL queries per navigation replaced by 1 Redis HTTP call

Out of scope

What was implemented

  • heartbeatViaRedis(sessionId) — Redis sorted set online_sessions with pipeline (ZADD + ZREMRANGEBYSCORE + ZCARD = 1 HTTP call)
  • heartbeatViaDb(sessionId) — existing DB logic extracted as fallback
  • POST handler: Redis first, DB fallback via ?? (nullish coalescing)
  • SESSION_TIMEOUT_MS constant replacing 2 duplicate calculations
  • Zero DB writes in normal operation; active_sessions table untouched when Redis is available
  • Verified in Upstash CLI: sorted set populating correctly, scores updating on navigation

Files changed:

  • frontend/app/api/sessions/activity/route.ts — rewritten with Redis-first pattern

Metadata

Metadata

Assignees

Labels

performancePerformance and efficiency optimizations without functional changes.

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions