Upstash Qstash JS
UpstashOfficialCreated by Upstash
- Skill
- Tool integration
- Automation and integrations
- MIT
- Low risk
- Has scripts
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The QStash JavaScript SDK provides a robust interface for interacting with Upstash's HTTP-based messaging and scheduling platform. Designed for serverless and edge environments like Next.js, Cloudflare Workers, and Deno, this skill enables developers to implement asynchronous task processing, cron-style scheduling, and reliable event-driven communication without maintaining persistent worker infrastructure.
What it does
- Publishes HTTP messages to individual endpoints or URL groups
- Schedules recurring tasks using cron expressions
- Manages FIFO queues with configurable parallelism and flow control
- Verifies incoming webhook signatures for secure communication
- Handles advanced messaging patterns like retries, callbacks, and dead letter queues
- Supports message deduplication and multi-region configurations
When to use it
- When building serverless applications requiring background job processing
- When you need to schedule delayed or recurring tasks in edge runtimes
- When implementing event-driven architectures between microservices
- When you need reliable webhook delivery with automatic retries
- When you need to ensure ordered message processing with flow control
Advantages
- Native support for serverless and edge runtimes
- Simplifies complex background job orchestration
- Built-in security via webhook signature verification
- Flexible configuration for retries, delays, and dead letter queues
- Supports local development workflows
Usage examples
- “How do I publish a JSON message to a webhook using QStash?”
- The agent provides a code snippet using the Client.publishJSON method, demonstrating how to initialize the client with an environment token and send a payload to a specific URL.
- “How can I verify that a webhook request came from QStash?”
- The agent explains how to use the Receiver class to validate incoming request signatures, including platform-specific guidance for frameworks like Next.js.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/upstash/upstash-qstash-js/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip upstash-qstash-js.zip -d .agents/skills
Documentation by Upstash
QStash JavaScript SDK
QStash is an HTTP-based messaging and scheduling solution for serverless and edge runtimes. This skill helps you use the QStash JS SDK effectively.
Bundled docs and source
Before writing or debugging SDK code, check node_modules/@upstash/qstash/docs/ for bundled docs and node_modules/@upstash/qstash/src/ for readable TypeScript source. Read and search the relevant files when present; otherwise use the references in this skill.
When to use this skill
Use this skill when:
Publishing HTTP messages to endpoints or URL groups
Creating scheduled or delayed message delivery
Managing FIFO queues with configurable parallelism
Verifying incoming webhook signatures from QStash
Implementing callbacks, DLQ handling, or message deduplication
Quick Start
Installing the SDK
npm install @upstash/qstashBasic Publishing
import { Client } from "@upstash/qstash";
const client = new Client({
token: process.env.QSTASH_TOKEN!,
});
const result = await client.publishJSON({
url: "https://my-api.example.com/webhook",
body: { event: "user.created", userId: "123" },
});Core Concepts
For fundamental QStash operations, see:
Local Development — automatic dev server via
devMode: true
For verifying incoming messages:
Receiver Verification - Core signature verification with the Receiver class
Platform-Specific Verifiers:
Next.js - App Router, Pages Router, and Edge Runtime
For advanced features:
Region migration & multi-region support
If needed, multi-region env variable setup verification script. Can be run without arguments
Platform Support
QStash JS SDK works across various platforms:
Next.js (App Router and Pages Router)
Cloudflare Workers
Deno
Node.js (v18+)
Vercel Edge Runtime
SvelteKit, Nuxt, SolidJS, and other frameworks
Note on Workflow SDK: For building complex durable workflows that chain multiple QStash messages together, consider using the separate QStash Workflow SDK (
@upstash/workflow). The Workflow SDK empowers you to orchestrate multi-step processes with automatic state management, retries, and fault tolerance. This Skills file focuses on the core QStash messaging SDK.
Best Practices
Always verify incoming QStash messages using the Receiver class
Use environment variables for tokens and signing keys
Set appropriate retry counts and timeouts for your use case
Use queues for ordered processing with controlled parallelism
Implement DLQ handling for failed message recovery
Files
- ATTRIBUTION.mdAdded by AutoGineer886 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md4.0 KiB
- advanced/callbacks.md4.6 KiB
- advanced/deduplication.md2.2 KiB
- advanced/dlq.md4.1 KiB
- advanced/multi-region/summary.md10.5 KiB
- advanced/multi-region/verify-multi-region-setup.tsScript12.6 KiB
- fundamentals/local-development.md4.2 KiB
- fundamentals/publishing-messages.md3.5 KiB
- fundamentals/queues-and-flow-control.md3.9 KiB
- fundamentals/schedules.md4.2 KiB
- fundamentals/url-groups.md3.0 KiB
- verification/platform-specific/nextjs.md4.2 KiB
- verification/receiver.md5.2 KiB
advanced/dlq.md
Dead Letter Queue (DLQ)
Messages that fail after all retries are moved to the Dead Letter Queue for manual inspection and recovery.
What is the DLQ?
When a message fails delivery after exhausting all retries, QStash moves it to the DLQ instead of discarding it. This lets you:
Investigate failure reasons
Manually retry after fixing issues
Delete permanently failed messages
Track patterns in failures
Common failure reasons:
Destination endpoint errors (5XX responses)
Timeouts
Network issues
Invalid responses from destination
Listing DLQ Messages
import { Client } from "@upstash/qstash";
const client = new Client({ token: process.env.QSTASH_TOKEN! });
const result = await client.dlq.listMessages();
console.log(`Found ${result.messages.length} failed messages`);
result.messages.forEach((msg) => {
console.log(`Message ${msg.messageId} to ${msg.url}`);
console.log(`Status: ${msg.responseStatus}`);
console.log(`DLQ ID: ${msg.dlqId}`);
});Pagination
Use cursor-based pagination for large DLQ:
let cursor: string | undefined;
const allMessages = [];
do {
const result = await client.dlq.listMessages({
cursor,
count: 50, // Return up to 50 messages
});
allMessages.push(...result.messages);
cursor = result.cursor;
} while (cursor);
console.log(`Total failed messages: ${allMessages.length}`);Filtering DLQ Messages
Filter by various criteria:
const result = await client.dlq.listMessages({
filter: {
messageId: "msg_123...",
url: "https://api.example.com/webhook",
urlGroup: "payment-webhooks",
queueName: "order-processing",
scheduleId: "scd_123...",
label: "payment-processing",
responseStatus: 500,
fromDate: oneDayAgo,
toDate: Date.now(),
callerIp: "192.168.1.1",
},
});Message Details
Each DLQ message includes:
type DlqMessage = {
dlqId: string; // Unique DLQ identifier
messageId: string; // Original message ID
url: string; // Destination URL
method?: string; // HTTP method
header?: Record<string, string[]>; // Request headers
body?: string; // Request body
urlGroup?: string; // URL group name
queueName?: string; // Queue name
scheduleId?: string; // Schedule ID
createdAt: number; // Creation timestamp (ms)
notBefore?: number; // Scheduled delivery time (ms)
label?: string; // Message label
// Failure details
responseStatus?: number; // HTTP status from destination
responseHeader?: Record<string, string[]>; // Response headers
responseBody?: string; // Response body (UTF-8)
responseBodyBase64?: string; // Response body (base64 if non-UTF-8)
};Deleting Messages
await client.dlq.delete("1725323658779-0");
await client.dlq.deleteMany({
dlqIds: ["1725323658779-0", "1725323658780-1", "1725323658781-2"],
});Understanding Failures
Inspect failure details:
const result = await client.dlq.listMessages();
for (const msg of result.messages) {
console.log(`\nMessage ${msg.messageId}:`);
console.log(`URL: ${msg.url}`);
console.log(`Status: ${msg.responseStatus}`);
if (msg.responseBody) {
console.log(`Response: ${msg.responseBody}`);
} else if (msg.responseBodyBase64) {
const decoded = Buffer.from(msg.responseBodyBase64, "base64").toString();
console.log(`Response: ${decoded}`);
}
if (msg.responseHeader) {
console.log(`Headers:`, msg.responseHeader);
}
}Using Failure Callbacks
Instead of polling the DLQ, use failure callbacks for real-time notifications:
See Callbacks for more details.
DLQ Retention
Messages remain in the DLQ based on your plan:
Free: 7 days
Paid: Check your plan on QStash Pricing
Messages are automatically deleted when retention expires.
Best Practices
Set up failure callbacks for critical messages
Regularly monitor DLQ for patterns
Delete non-retriable messages to keep DLQ clean
Use labels to categorize and filter failures
Alert on DLQ message count thresholds
Document common failure scenarios and resolutions
Consider automated retries for known transient issues
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Node.js
Security
What our scanner noticed· Low risk
- Scripts that your agent may run
This skill includes scripts that your agent may run. Read them before you use it.
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Upstash
- Publisher
- Upstash (Official)
- Source
- upstash/skills · skills/upstash-qstash-js · commit 9f9e3e5
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Upstash.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download upstash-qstash-js.zip