Skip to content

Upstash Redis Setup (Optional Performance Optimization)

Upstash Redis is an optional feature that improves Sellf performance. The application works perfectly fine without it, but with Upstash you’ll get:

  • <10ms latency for cached data (vs ~50-100ms database queries)
  • 50-70% reduced database load
  • Global edge network (16+ regions)
  • Better rate limiting accuracy in serverless environments
  • Free tier: 10,000 requests/day, 256MB storage

Sellf is designed to work without Redis:

ScenarioPerformanceBehavior
Without RedisGood ✅All data from database (~50-100ms)
With RedisExcellent 🚀Cached data ~10ms, fallback to database

If Redis fails or is misconfigured, the app automatically falls back to database queries. No errors, no crashes.


  1. Go to console.upstash.com
  2. Sign up (free tier, no credit card required)
  1. Click “Create Database”

  2. Choose settings:

    • Name: sellf-prod (or any name)
    • Type: Regional (cheaper, faster for single region)
    • Region: Choose closest to your VPS location
    • TLS: Enabled (recommended)
    • Eviction: No eviction (recommended for caching)
  3. Click “Create”

After creation, you’ll see:

REST API Endpoint: https://your-region.upstash.io
REST API Token: AX...your-token-here...==

Add to .env.fullstack:

Terminal window
# Upstash Redis (Optional - Performance Optimization)
UPSTASH_REDIS_REST_URL=https://your-region.upstash.io
UPSTASH_REDIS_REST_TOKEN=AX...your-token-here...==
Terminal window
# PM2
pm2 restart all
# Docker
docker-compose restart
# Dev mode
npm run dev

Check logs for:

✅ Upstash Redis connected - caching enabled

If you see this instead:

ℹ️ Upstash Redis not configured - using database fallback (this is OK)

…that means Redis is not configured, but app still works fine.


shop_config query: ~50-100ms
Product query: ~50-100ms
Total page load: ~200-300ms
shop_config query: ~5-10ms ⚡ 10x faster
Product query: ~5-10ms ⚡ 10x faster
Total page load: ~50-100ms ⚡ 3-5x faster

Currently cached data:

DataTTLCache Key
Shop Configuration1 hourshop:config
Rate LimitsDynamicratelimit:*

Future caching (coming soon):

  • Product data (5 min TTL)
  • User purchases (1 min TTL)
  • Analytics data (5 min TTL)

Terminal window
# From admin-panel directory
node -e "
const { Redis } = require('@upstash/redis');
const redis = new Redis({
url: process.env.UPSTASH_REDIS_REST_URL,
token: process.env.UPSTASH_REDIS_REST_TOKEN
});
redis.ping()
.then(() => console.log('✅ Redis connected'))
.catch(err => console.error('❌ Redis error:', err.message));
"

Login to Upstash console → Your database → Monitoring tab to see:

  • Requests per second
  • Hit rate
  • Data size

  • 10,000 requests/day
  • 256 MB storage
  • 1 region
  • TLS included

Good for: Up to ~400 visitors/day with caching

  • 100,000 requests/day
  • 1 GB storage
  • 1 region

Good for: Up to ~3,000 visitors/day

  • $0.20 per 100,000 requests
  • $0.25 per GB storage

Good for: High-traffic sites

Calculate your needs:

Daily visitors: 1000
Cache hit rate: 80%
Cached requests/visitor: 5
Total requests: 1000 * 5 * 0.8 = 4,000 req/day
→ Free tier is enough! 🎉

Issue: “Expected 3 parts in JWT; got 1”

Section titled “Issue: “Expected 3 parts in JWT; got 1””

Cause: Upstash token is incorrect or incomplete.

Fix:

  1. Go to Upstash console
  2. Copy full REST API Token (should start with AX and end with ==)
  3. Make sure no spaces or newlines

Cause: Network issue or wrong URL.

Fix:

  1. Check UPSTASH_REDIS_REST_URL is complete (with https://)
  2. Try pinging from VPS: curl -I <your-url>
  3. Check firewall rules

Possible causes:

  1. Redis is far from your VPS (choose closer region)
  2. Database queries are still slow (check database location)
  3. ISR not enabled (check revalidate in pages)

Debug:

Terminal window
# Check logs for cache hits
pm2 logs | grep "Redis"

DO:

  • Keep tokens in .env.fullstack (never commit!)
  • Use TLS (enabled by default)
  • Rotate tokens periodically (Upstash console → Settings → Rotate)

DON’T:

  • Hardcode tokens in code
  • Share tokens publicly
  • Use same Redis for dev and production

You can cache your own data using the cache helpers:

import { cacheGet, cacheSet, CacheKeys, CacheTTL } from '@/lib/redis/cache'
// Get from cache
const product = await cacheGet<Product>(`product:${slug}`)
// Set to cache (5 min TTL)
await cacheSet(`product:${slug}`, productData, CacheTTL.MEDIUM)
// Delete from cache
await cacheDel(`product:${slug}`)
// Delete pattern (all products)
await cacheDelPattern('product:*')

Pro tip: Always check if cacheGet() returns null and fallback to database.


  1. Check Upstash Docs
  2. Check Sellf Issues
  3. Ask in discussions

Remember: Redis is optional. If you’re having issues, you can simply not configure it and the app will work fine! 🎉