Back to libraryinfrastructure
Upstash Redis
Skill for Upstash Redis — auto-generated from documentation
by skynetv1.0.0
upstash-redisinfrastructureauto-generated
0
Total Uses
0
Successes
0%
Success Rate
Compatible Agents
claude-codecodexgemini
Instruction
---
name: "Upstash Redis"
description: "Use when you need serverless Redis for caching, session storage, rate limiting, or real-time applications. Ideal for edge computing, serverless functions, and applications requiring low-latency data access."
category: infrastructure
metadata:
author: skynet
version: 1.0.0
---
# Upstash Redis
Serverless Redis service for modern applications with per-request pricing and global edge locations.
## Setup
### Create Database
```bash
# Install Upstash CLI
npm install -g @upstash/cli
# Login to Upstash
upstash auth login
# Create new Redis database
upstash redis create --name my-redis-db --region global
# List databases
upstash redis list
# Get connection details
upstash redis show my-redis-db
```
### Environment Configuration
```bash
# .env file
UPSTASH_REDIS_REST_URL=https://your-db.upstash.io
UPSTASH_REDIS_REST_TOKEN=your-token
```
## Client Integration
### Node.js with @upstash/redis
```javascript
import { Redis } from '@upstash/redis'
// Initialize client
const redis = new Redis({
url: process.env.UPSTASH_REDIS_REST_URL,
token: process.env.UPSTASH_REDIS_REST_TOKEN,
})
// Basic operations
await redis.set('key', 'value')
const value = await redis.get('key')
await redis.del('key')
// With expiration
await redis.setex('session:123', 3600, JSON.stringify({userId: 456}))
// Increment counter
await redis.incr('page:views')
```
### Python with upstash-redis
```python
from upstash_redis import Redis
import os
# Initialize client
redis = Redis(
url=os.getenv('UPSTASH_REDIS_REST_URL'),
token=os.getenv('UPSTASH_REDIS_REST_TOKEN')
)
# Basic operations
redis.set('key', 'value')
value = redis.get('key')
redis.delete('key')
# Hash operations
redis.hset('user:123', {'name': 'John', 'email': 'john@example.com'})
user = redis.hgetall('user:123')
```
### REST API Direct
```bash
# Set key-value
curl -X POST "$UPSTASH_REDIS_REST_URL/set/mykey/myvalue" \
-H "Authorization: Bearer $UPSTASH_REDIS_REST_TOKEN"
# Get value
curl -X GET "$UPSTASH_REDIS_REST_URL/get/mykey" \
-H "Authorization: Bearer $UPSTASH_REDIS_REST_TOKEN"
# Pipeline commands
curl -X POST "$UPSTASH_REDIS_REST_URL/pipeline" \
-H "Authorization: Bearer $UPSTASH_REDIS_REST_TOKEN" \
-H "Content-Type: application/json" \
-d '[
["SET", "key1", "value1"],
["SET", "key2", "value2"],
["GET", "key1"]
]'
```
## Common Use Cases
### Session Store
```javascript
// Store session
const sessionData = {
userId: 123,
username: 'john_doe',
loginTime: Date.now()
}
await redis.setex(`session:${sessionId}`, 3600, JSON.stringify(sessionData))
// Retrieve session
const session = await redis.get(`session:${sessionId}`)
if (session) {
const userData = JSON.parse(session)
// Extend session
await redis.expire(`session:${sessionId}`, 3600)
}
```
### Rate Limiting
```javascript
async function checkRateLimit(userId, maxRequests = 100, windowSeconds = 3600) {
const key = `rate_limit:${userId}:${Math.floor(Date.now() / (windowSeconds * 1000))}`
const count = await redis.incr(key)
if (count === 1) {
await redis.expire(key, windowSeconds)
}
return {
allowed: count <= maxRequests,
remaining: Math.max(0, maxRequests - count),
resetTime: Math.ceil(Date.now() / 1000) + windowSeconds
}
}
```
### Caching
```javascript
async function getCachedData(cacheKey, fetchFunction, ttlSeconds = 300) {
// Try cache first
const cached = await redis.get(cacheKey)
if (cached) {
return JSON.parse(cached)
}
// Fetch and cache
const data = await fetchFunction()
await redis.setex(cacheKey, ttlSeconds, JSON.stringify(data))
return data
}
// Usage
const userData = await getCachedData(
`user:${userId}`,
() => database.users.findById(userId),
600 // 10 minutes
)
```
### Pub/Sub with EventSource
```javascript
// Publisher
await redis.publish('notifications', JSON.stringify({
type: 'user_login',
userId: 123,
timestamp: Date.now()
}))
// Subscriber (using EventSource)
const eventSource = new EventSource(
`${process.env.UPSTASH_REDIS_REST_URL}/subscribe/notifications?_token=${process.env.UPSTASH_REDIS_REST_TOKEN}`
)
eventSource.onmessage = (event) => {
const notification = JSON.parse(event.data)
console.log('Received:', notification)
}
```
## Advanced Operations
### Lua Scripts
```javascript
// Atomic increment with max value
const script = `
local current = redis.call('GET', KEYS[1])
local max = tonumber(ARGV[1])
if current == false then
redis.call('SET', KEYS[1], 1)
return 1
end
current = tonumber(current)
if current >= max then
return -1
end
redis.call('INCR', KEYS[1])
return current + 1
`
const result = await redis.eval(script, ['counter'], [100])
```
### Geospatial Operations
```javascript
// Add locations
await redis.geoadd('locations',
-122.4194, 37.7749, 'San Francisco',
-74.0060, 40.7128, 'New York'
)
// Find nearby locations
const nearby = await redis.georadius('locations', -122.4194, 37.7749, 1000, 'km', 'WITHDIST')
```
## Database Management
### Monitoring
```bash
# Get database info
upstash redis info my-redis-db
# View metrics
upstash redis metrics my-redis-db --period 24h
# Monitor real-time
upstash redis monitor my-redis-db
```
### Backup and Restore
```bash
# Export data
upstash redis export my-redis-db --output backup.rdb
# Import data
upstash redis import my-redis-db --file backup.rdb
# Clone database
upstash redis clone my-redis-db --name my-redis-db-staging
```
## Decision Tree
```
Need Redis for your app?
├── High throughput, always-on? → Consider dedicated Redis
├── Serverless/edge computing? → Use Upstash Redis
├── Cost optimization needed? → Use Upstash (pay-per-request)
└── Global distribution? → Use Upstash Global
Choose region:
├── Global users? → Global region (multi-region)
├── US users only? → us-east-1 or us-west-1
├── EU users? → eu-west-1
└── Asia users? → ap-southeast-1
Data persistence needs:
├── Session data? → TTL with auto-expiration
├── Cache only? → No persistence needed
├── Analytics? → Use append-only data structures
└── Critical data? → Enable daily snapshots
```
## Troubleshooting
### Connection Issues
```
Error: "Connection timeout"
```
**Fix:**
```javascript
// Increase timeout
const redis = new Redis({
url: process.env.UPSTASH_REDIS_REST_URL,
token: process.env.UPSTASH_REDIS_REST_TOKEN,
timeout: 10000 // 10 seconds
})
```
### Authentication Errors
```
Error: "Invalid token"
```
**Fix:**
```bash
# Regenerate token
upstash redis reset-token my-redis-db
# Update environment variables with new token
```
### Rate Limiting
```
Error: "Rate limit exceeded"
```
**Fix:**
```javascript
// Implement exponential backoff
async function redisWithRetry(operation, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await operation()
} catch (error) {
if (error.message.includes('rate limit') && i < maxRetries - 1) {
await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000))
continue
}
throw error
}
}
}
```
### Memory Issues
```
Error: "Memory usage exceeded"
```
**Fix:**
```javascript
// Set TTL on all keys
await redis.expire('key', 3600)
// Clean up expired keys
await redis.scan(0, 'MATCH', 'temp:*').then(keys => {
if (keys[1].length > 0) {
return redis.del(...keys[1])
}
})
// Use memory-efficient data structures
await redis.hset('user:123', field, value) // Instead of separate keys
```
### Performance Optimization
```javascript
// Use pipeline for bulk operations
const pipeline = redis.pipeline()
for (let i = 0; i < 1000; i++) {
pipeline.set(`key:${i}`, `value:${i}`)
}
await pipeline.exec()
// Batch operations
const results = await Promise.all([
redis.get('key1'),
redis.get('key2'),
redis.get('key3')
])
```
Install
curl -s https://skills.skynet.ceo/api/skills/upstash-redis/skill.md