Files
notifkit/.env.example
T
coo1estguy d439f051a6 fix(metrics): compute true stream backlog via consumer group lag and set retention to 100k
- Cap Redis stream retention at 100,000 messages (down from 10,000,000) in
  src/config/index.ts and .env.example to prevent unbounded memory growth.
- In src/services/api/handlers.ts, update getSystemMetrics to resolve stream
  queue depths using consumer group lag and in-flight pending entries (via
  XINFO GROUPS) instead of raw XLEN. This prevents acknowledged and delivered
  notifications from persisting as ghost backlog in the dashboard.
- Retain XLEN measurement for DEAD_LETTER queue where messages persist until
  replayed or deleted.
- Adjust dashboard capacity scaling to 100,000 items in AnalyticsPage.tsx and
  update backpressure warning threshold to 80,000 in DashboardHeader.tsx.
- Ensure 0-depth queues render empty (0% width) in the backlog gauge meter.
- Update queue test expectations in tests/queue.test.ts and add unit tests
  verifying consumer group lag resolution in tests/api-admin.test.ts.
2026-09-25 12:57:02 +05:30

47 lines
2.9 KiB
Bash

# ── Core ──────────────────────────────────────────────────────────────────────
NODE_ENV=development
LOG_LEVEL=debug
PORT=3000
# Bind address. 127.0.0.1 keeps the server off the network; use 0.0.0.0 in a container.
HOST=127.0.0.1
# ── Dependencies ──────────────────────────────────────────────────────────────
# Omit both in development and notifkit starts throwaway containers for you.
REDIS_URL=redis://localhost:6379
DATABASE_URL=postgres://platform:platform@localhost:5432/notifkit
# ── Auth ──────────────────────────────────────────────────────────────────────
# Bootstrap key. Full access to every project — mint per-project keys for apps.
ADMIN_API_KEY=my_super_secret_admin_key
# Allowed origins for CORS on session-authenticated admin endpoints (comma-separated).
# CORS_ORIGIN=https://dashboard.example.com
# ── Unsubscribe ───────────────────────────────────────────────────────────────
# Signs unsubscribe tokens. Minimum 16 characters. Required in production. Treat it as permanent:
# rotating it breaks every unsubscribe link already sitting in an inbox, and a
# dead unsubscribe link sends people to the spam button instead.
# Where an inbox can reach this API. Not HOST/PORT, which are the bind address
# behind your proxy.
PUBLIC_URL=https://notify.example.com
UNSUBSCRIBE_SECRET=change_me_to_a_long_random_string
# ── Limits ────────────────────────────────────────────────────────────────────
# Per-user sliding-window cap. `critical` priority bypasses it.
RATE_LIMIT_PER_HOUR=100
# Largest segment or topic fan-out. A send exceeding this is rejected whole,
# not truncated, so raise it before your list grows past it.
SEGMENT_MAX_USERS=10000
# In-flight messages a worker will process concurrently.
WORKER_CONCURRENCY=10
# Redis stream trim length. The cap on unconsumed backlog.
QUEUE_MAX_LEN=100000
# Postgres pool size, per process. Multiply by your replica count.
DB_MAX_CONNECTIONS=2
# ── Log buffering ─────────────────────────────────────────────────────────────
# Delivery logs are batched into Postgres. Lower the interval for fresher logs,
# raise the buffer for fewer writes under load.
LOG_FLUSH_INTERVAL_MS=500
LOG_BUFFER_MAX_SIZE=5000