An HTTP server that talks to Redis so you don't have to. Think Upstash, but you run it yourself. Or don't. I'm not your boss.
Downstash is a lightweight HTTP API wrapper around Redis that's compatible with the Upstash REST API format. It lets you interact with Redis over HTTP using simple POST requests, which is handy when you can't (or don't want to) use a native Redis client.
Why would you want this? Maybe you're in a serverless environment. Maybe you're behind a firewall that only allows HTTP. Maybe you just like making things more complicated. Who am I to judge?
- 🚀 Upstash-compatible API - Drop-in replacement for Upstash REST API
- 🔐 Bearer token authentication - Because security is a thing
- 📦 Pipeline support - Batch multiple commands in one request
- 🔄 Transaction support - MULTI/EXEC for when you need atomicity
- 🎨 Base64 encoding - Optional encoding for binary data (Upstash style)
- 🐳 Docker ready - Because containers are the new black
- ⚡ Built with Hono - Fast, lightweight, and actually pleasant to use
- Deno 2.0+ (or Docker if you're fancy)
- A Redis instance (local or remote, we're not picky)
# Clone this thing
git clone <your-repo-url>
cd downstash
# Set up your environment
cp .env.example .env # If you have one, otherwise just set these:
export SR_TOKEN="your-secret-token-here"
export REDIS_URL="redis://localhost:6379"
export PORT=3000 # Optional, defaults to 3000
# Run it
deno task devOr if you're a Docker person:
docker-compose upAll endpoints require Bearer token authentication via the Authorization header.
GET /Returns a friendly welcome message. Mostly for checking if the server is alive.
GET /pingReturns Pong. Because every API needs a ping endpoint.
POST /
Content-Type: application/json
Authorization: Bearer your-token-here
["SET", "key", "value"]Execute a single Redis command. The body should be an array where the first element is the command name, followed by its arguments.
Response:
{
"result": "OK"
}POST /pipeline
Content-Type: application/json
Authorization: Bearer your-token-here
[
["SET", "key1", "value1"],
["GET", "key1"],
["SET", "key2", "value2"]
]Execute multiple commands sequentially. Returns an array of results.
Response:
{
"result": [
{ "result": "OK" },
{ "result": "value1" },
{ "result": "OK" }
]
}POST /multi-exec
Content-Type: application/json
Authorization: Bearer your-token-here
[
["SET", "key1", "value1"],
["GET", "key1"],
["INCR", "counter"]
]Execute commands in a transaction. Currently behaves similarly to pipeline (honestly, the Redis MULTI/EXEC handling could be more sophisticated, but it works).
Response:
{
"result": [
{ "result": "OK" },
{ "result": "value1" },
{ "result": 1 }
]
}If you want responses encoded in base64 (Upstash style), include this header:
upstash-encoding: base64
This is useful for handling binary data or when you need compatibility with Upstash clients.
| Variable | Description | Default |
|---|---|---|
SR_TOKEN |
Bearer token for authentication | (required) |
REDIS_URL |
Redis connection URL | redis://localhost:6379 |
PORT |
Server port | 3000 |
HOST |
Server hostname | 0.0.0.0 |
This was built with Railway in mind, but honestly, it'll run anywhere Deno runs.
- Connect your repo to Railway
- Set the environment variables
- Deploy
- Profit?
docker build -t downstash .
docker run -p 3000:3000 \
-e SR_TOKEN=your-token \
-e REDIS_URL=redis://your-redis:6379 \
downstash- You send an HTTP request with a Redis command
- The server validates your token (or doesn't, if you didn't set one up properly)
- It parses your command and sends it to Redis via ioredis
- Redis does its thing
- The server formats the response in Upstash-compatible JSON
- You get your result (or an error, if you messed something up)
The codebase is pretty straightforward - no magic, just HTTP → Redis → HTTP. The most complex part is probably the base64 encoding logic, and even that's not rocket science.
- Hono - A lightweight, fast web framework. Actually good.
- Deno - A secure runtime that doesn't make you deal with
node_modules - ioredis - Redis client that actually works
- Transactions (
/multi-exec) currently just run commands sequentially. Real MULTI/EXEC support could be added, but it works for most use cases. - Error handling is basic but functional. Don't expect poetry in error messages.
- The code assumes you know what you're doing with Redis commands. It won't hold your hand.
WTFPL - Do What The F*ck You Want To Public License
You want to use this? Go ahead. Modify it? Sure. Sell it? Whatever. Just don't blame me if something breaks.
Made with questionable amounts of coffee and a healthy dose of pragmatism.