DeskcommCRM External Rate Limiting Using Upstash Redis: Implementation and Configuration Guide

Yes, DeskcommCRM supports external rate limiting using Upstash Redis through a per-tenant fixed-window counter implementation that automatically falls back to in-memory storage when the external store is unavailable.

DeskcommCRM implements robust per-tenant rate limiting for AI dispatches via an external Upstash Redis store defined in lib/ai/dispatcher/rate-limit.ts. The architecture guarantees that throttling constraints persist across serverless invocations while maintaining operational continuity during network partitions through intelligent degradation strategies.

Environment Configuration and Validation

External rate limiting requires specific environment variables that the application validates before establishing connections.

Required Environment Variables

According to the DeskcommCRM source code, the system expects two critical variables defined in lib/env.ts:

  • UPSTASH_REDIS_REST_URL
  • UPSTASH_REDIS_REST_TOKEN

These credentials are validated by lib/redis-config.ts to ensure proper formatting before the Redis client is instantiated. The application will abort startup if these values are missing or malformed, preventing silent fallback to unprotected operation.

Connection Security Settings

When initializing the client in lib/ai/dispatcher/rate-limit.ts, the code explicitly disables automatic retries:

new Redis({ url, token, retry: false })

This configuration ensures that rate-limiting decisions fail fast during network partitions rather than hanging indefinitely on stale connections, allowing the system to trigger the in-memory fallback immediately.

Core Rate Limiting Logic in rate-limit.ts

The primary implementation resides in lib/ai/dispatcher/rate-limit.ts, which exports the checkRateLimit and peekRateLimit functions used throughout the AI dispatch pipeline.

Fixed-Window Counter Algorithm

DeskcommCRM employs a fixed-window counter strategy that partitions time into discrete windows. For each request, the system constructs a composite key using the pattern ${bucket}:${windowStart}, where bucket identifies the tenant/resource and windowStart represents the Unix timestamp of the current window boundary.

The algorithm executes atomic Redis operations in sequence:

  1. redis.incr(key) increments the counter
  2. On first increment (count === 1), redis.expire(key, windowSec) sets the TTL

This approach ensures that Redis handles both the counting and expiration atomically, preventing race conditions in high-concurrency scenarios.

Tenant Isolation Architecture

Each organization receives isolated rate-limiting buckets (for example, ai-runs:org123:42), ensuring that heavy usage by one tenant does not exhaust the quota of another. The bucket parameter passed to checkRateLimit typically includes the tenant identifier, maintaining strict separation between organizations in multi-tenant CRM deployments.

Resilience and Fallback Behavior

When the Upstash Redis endpoint is unreachable, DeskcommCRM does not bypass rate limiting entirely.

In-Memory Degradation Mechanism

The checkRateLimit function maintains a private _memBuckets Map that shadows the Redis state. If the redis.incr call throws an exception—whether from network timeout or authentication failure—the code catches the error, logs a warning, and transitions to the in-memory counter stored in _memBuckets. While this makes the limit per-process rather than globally shared across instances, it preserves protective throttling during external outages.

Non-Destructive Limit Inspection

The peekRateLimit function (lines 63-73 in rate-limit.ts) retrieves the current counter value without incrementing it. This supports "check-before-act" flows such as login attempt validation, where you want to assess remaining quota before consuming a request. The function attempts to read from Redis first, then falls back to the in-memory cache if the external store is unavailable.

Practical Implementation Examples

Enforcing AI Dispatch Limits

Use checkRateLimit to protect AI-intensive operations with configurable windows:

import { checkRateLimit } from '@/lib/ai/dispatcher/rate-limit';

async function dispatchAIRequest(orgId: string) {
  const bucket = `ai-runs:${orgId}`;
  const limit = 60;          // Maximum 60 calls
  const windowSec = 60;      // Per 60-second window

  const { allowed, count } = await checkRateLimit(bucket, limit, windowSec);
  if (!allowed) {
    throw new Error(`Rate limit exceeded – ${count}/${limit} in the last minute`);
  }
  // Proceed with AI dispatch...
}

Peeking Login Attempt Counters

Use peekRateLimit for authentication throttling where you must check status before consuming a quota:

import { peekRateLimit } from '@/lib/ai/dispatcher/rate-limit';

async function canAttemptLogin(orgId: string) {
  const bucket = `login:${orgId}`;
  const windowSec = 300; // 5-minute window
  const current = await peekRateLimit(bucket, windowSec);
  return current < 5; // Allow up to 5 attempts in the window
}

Environment Configuration

Ensure your deployment includes these variables in .env or .env.local:

UPSTASH_REDIS_REST_URL=https://your-redis-instance.upstash.io
UPSTASH_REDIS_REST_TOKEN=your-secret-token

Summary

  • DeskcommCRM supports external rate limiting using Upstash Redis through the @upstash/redis package (version ^1.38.3 as declared in package.json)
  • Configuration relies on UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN environment variables validated in lib/redis-config.ts
  • The checkRateLimit function in lib/ai/dispatcher/rate-limit.ts implements a fixed-window counter with automatic Redis expiry using incr and expire commands
  • If Redis connectivity fails, the system falls back to an in-memory _memBuckets Map to maintain per-process protection while logging warnings
  • The peekRateLimit function enables non-destructive quota inspection for sensitive operations like authentication without consuming the rate limit budget

Frequently Asked Questions

What happens if Upstash Redis is temporarily unavailable?

DeskcommCRM detects connection failures in checkRateLimit and automatically switches to an in-memory fallback stored in the _memBuckets Map. While this limits the constraint to individual process instances rather than the global cluster, rate limiting continues to protect the system. Operators receive warning logs indicating the degradation mode is active.

How does DeskcommCRM prevent rate-limit key collisions between tenants?

The implementation constructs unique keys using the pattern ${bucket}:${windowStart}, where the bucket identifier typically includes the tenant ID (for example, ai-runs:org123). This ensures that counters for different organizations remain strictly isolated in both Redis and the in-memory fallback, preventing cross-tenant quota bleeding.

Can I check remaining quota without consuming a request?

Yes. The peekRateLimit function in lib/ai/dispatcher/rate-limit.ts reads the current counter value from Redis or the in-memory cache without calling incr. This is ideal for pre-flight checks on expensive operations or login attempt validation where you must verify availability before deducting from the limit.

Which version of the @upstash/redis SDK does DeskcommCRM use?

The package.json specifies @upstash/redis version ^1.38.3. The client is instantiated in lib/ai/dispatcher/rate-limit.ts with retry: false to ensure immediate feedback during network partitions rather than hanging on retry loops.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →