Upstash Redis REST API: HTTP-Based Redis for Serverless and Edge Environments
Quick Answer
- What it is: Upstash Redis REST API lets you execute Redis commands over plain HTTPS, eliminating the need for persistent TCP connections. This makes it ideal for serverless functions (Vercel Edge, Cloudflare Workers, AWS Lambda) and edge computing where long-lived connections are impossible.
- First check: Ensure you have your Upstash REST URL and bearer token from the Upstash Console. Authentication requires either an
Authorization: Bearer YOUR_TOKENheader or a?_token=YOUR_TOKENquery parameter. - Minimal command:
curl https://YOUR_REST_URL/set/foo/bar -H "Authorization: Bearer YOUR_TOKEN"— replacesfoowithbarin your Redis database. - Key limitation: Does not support Pub/Sub, blocking commands (
BLPOP,SUBSCRIBE), or streaming responses. Each request incurs HTTP overhead (1–5ms extra latency). - Best for: Serverless architectures, LLM session storage, rate limiting counters, task queues, and any environment where maintaining a Redis TCP connection is impractical.
What Problem It Solves
Traditional Redis clients use persistent TCP connections. Serverless platforms like Vercel Edge Functions, Cloudflare Workers, and AWS Lambda cannot maintain long-lived connections — they are stateless by design. Upstash Redis REST API solves this by exposing Redis commands as HTTP endpoints. Every request is self-contained: authenticate, send the command, get the response, and close. No connection pools, no keep-alive management, no infrastructure to maintain.
This approach also simplifies integration with AI agents and MCP (Model Context Protocol) hosts. A Claude Desktop or Cursor agent can call Redis operations via simple curl or fetch calls without needing a Redis client library.
Minimal Working Configuration
Authentication
You must authenticate every request. Two methods are supported:
| Method | Example |
|---|---|
| HTTP Header (preferred) | -H "Authorization: Bearer YOUR_TOKEN" |
| Query Parameter | ?_token=YOUR_TOKEN |
Always prefer the header method. Passing the token as a query parameter may leak it into server logs, browser history, or proxy caches.
Basic Commands
All commands follow this URL pattern:
https://YOUR_REST_URL/COMMAND/arg1/arg2/.../argN
Set a key:
BASHcurl https://YOUR_REST_URL/set/mykey/hello -H "Authorization: Bearer YOUR_TOKEN"
Get a key:
BASHcurl https://YOUR_REST_URL/get/mykey -H "Authorization: Bearer YOUR_TOKEN"
Delete a key:
BASHcurl https://YOUR_REST_URL/del/mykey -H "Authorization: Bearer YOUR_TOKEN"
POST Requests for Complex Commands
For commands with many arguments or JSON payloads, use POST with the request body:
BASHcurl -X POST https://YOUR_REST_URL/set \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '["mykey", "myvalue"]'
Parameters and Environment Variables
HTTP Headers
| Header | Required | Description |
|---|---|---|
Authorization | Yes (unless using _token) | Bearer token for authentication. Format: Bearer $TOKEN |
Upstash-Encoding | No | Set to base64 to receive base64-encoded string responses |
Upstash-Response-Format | No | Set to resp2 to get binary RESP2 formatted responses instead of JSON |
URL Parameters
| Parameter | Required | Description |
|---|---|---|
_token | Yes (unless using Authorization header) | Query parameter alternative for authentication |
COMMAND | Yes | Redis command name as a path segment (e.g., set, get, hset) |
argN | Yes (depends on command) | Command arguments as subsequent path segments |
Request Body (POST only)
For POST requests, the body can be:
- A plain value (for simple
SETcommands) - A JSON array representing the full command and its arguments:
["COMMAND", "arg1", "arg2", ...]
Root Cause Analysis
Why HTTP Overhead Exists
Each REST API call involves:
- DNS resolution
- TLS handshake
- HTTP request/response round trip
- Server-side command parsing and execution
This adds 1–5ms compared to a persistent TCP connection. For single operations this is negligible, but for high-frequency operations it compounds.
Why Pub/Sub and Blocking Commands Are Unsupported
HTTP is stateless. Pub/Sub requires a persistent connection where the server pushes messages to the client. Blocking commands like BLPOP wait until data is available. Neither pattern maps to request-response HTTP. If you need these features, use the native Redis protocol with a TCP-capable environment.
Why Token Leakage Matters
When you pass _token as a query parameter:
- The full URL (including the token) may be logged by your proxy, CDN, or server middleware
- Browser history stores the URL
- Referrer headers may leak the token to third parties
The Authorization header is stripped from most logging systems and never appears in URLs.
Common Errors and Fixes
| Error | Cause | Solution |
|---|---|---|
401 Unauthorized | Missing or invalid token | Verify the Authorization header or _token parameter. Regenerate the token in Upstash Console if needed. |
400 Bad Request: ERR wrong number of arguments for 'get' command | Incorrect number of path segments | GET requires exactly one key: /get/mykey. SET requires two: /set/mykey/value. Check Redis command syntax. |
504 Gateway Timeout | Network issue or request too large | Check firewall/proxy rules. Reduce request body size. Use Pipelining to batch commands. |
429 Too Many Requests | Rate limit exceeded | Implement exponential backoff. Batch commands using Pipelining or Transactions. Upgrade your Upstash plan. |
Production Notes and Security Checks
Token Management
- Use read-only tokens for query-only operations. Generate separate tokens for write operations.
- Rotate tokens regularly through the Upstash Console.
- Never hardcode tokens in client-side code. Use environment variables or secret management services.
Data Size Limits
Single request bodies are limited to approximately 1MB. For larger payloads:
- Split data across multiple keys
- Use Redis lists or streams for sequential data
- Consider compression before storage
Rate Limiting Strategy
When you receive a 429 response:
- Wait for the
Retry-Afterheader value (if present) - Implement exponential backoff: 1s, 2s, 4s, 8s, max 60s
- Batch multiple commands into a single request using Pipelining
Pipelining and Transactions
Combine multiple commands into one HTTP call to reduce round trips:
Pipelining (non-atomic):
BASHcurl -X POST https://YOUR_REST_URL/pipeline \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '[["SET", "key1", "val1"], ["GET", "key1"], ["SET", "key2", "val2"]]'
Transactions (atomic):
BASHcurl -X POST https://YOUR_REST_URL/multi-exec \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '[["SET", "key", "value"], ["GET", "key"]]'
Transactions guarantee all commands execute atomically, but concurrent clients operating on the same keys may cause conflicts. Implement application-level retry logic for transaction failures.
FAQ
Q: How does Upstash Redis REST API compare to using a native Redis client?
A: Native Redis clients use persistent TCP connections with lower per-command latency (microseconds vs milliseconds). However, they require maintaining connection pools and cannot work in stateless serverless environments. Upstash REST API trades ~1–5ms extra latency per request for zero connection management, automatic scaling, and compatibility with any HTTP-capable runtime. For batch operations, Pipelining reduces the gap significantly.
Q: Can I use Upstash Redis REST API with MCP clients like Claude Desktop?
A: Yes. Create a lightweight MCP server wrapper (Python, Node.js, or any language) that internally calls the Upstash REST API. Configure the MCP host's mcpServers to launch your wrapper. The wrapper exposes Redis operations as MCP tools. For example, a Python wrapper would use requests to call https://YOUR_REST_URL/get/key and return the result as an MCP tool response.
Q: Which Redis commands are NOT supported?
A: Commands requiring streaming or persistent connections are unsupported: SUBSCRIBE, PSUBSCRIBE, MONITOR, BLPOP, BRPOP, BRPOPLPUSH, BZPOPMIN, BZPOPMAX, WAIT, CLIENT, SLOWLOG, and DEBUG. All standard data type commands (String, Hash, List, Set, Sorted Set, HyperLogLog, Bitmap) work normally. Check the Upstash documentation for the complete supported command list.