Skip to main content
Guide

Caching system

How the Redis cache works, what is cached, and how it is invalidated.

Overview

Vigent uses PostgreSQL as the source of truth and Redis as the cache layer. The goal is to cut latency and external-API cost for hot reads. All cache operations are best-effort: if Redis is down, requests fall through to the DB and nothing blocks.

What is cached?

  • Login OTP — short TTL (minutes), stored only in Redis.
  • Rate-limit counters (e.g. 20 msgs/min for the widget) — atomic in Redis.
  • Text-question embeddings — 7-day TTL. Repeated questions skip the embedding API entirely.
  • Public widget config (name, color, theme, position, font) — 60s TTL. Read on every chat message.

Widget config cache flow

  1. 1The widget browser GETs /api/widget/{agentId}.
  2. 2Server reads widget:cfg:{agentId} from Redis (~1ms).
  3. 3If hit: return config immediately.
  4. 4If miss: run a Prisma query (10–30ms), then write-back to Redis with 60s TTL.
  5. 5When you save widget settings in the dashboard, the cache key is invalidated so new visitors see the change instantly.

Why not cache Postgres rows directly?

Because invalidation gets hard. Instead of caching raw DB rows, we cache only safe public data (like widget config) under a well-defined key, and invalidate at the exact write site (e.g. web-widget-channel after save). This is the "cache-aside" pattern, the most reliable for multi-user systems.

Note: if Redis goes down, Vigent still works — just slightly slower. No data is lost because Postgres remains the source of truth.

Give it one try — you’ll see

Take a few minutes, build your agent from your own info and test it with a few real messages. Not for you? You’ve lost nothing.