Claude Skills Guide

Claude Code Upstash QStash Scheduled Tasks Setup Guide

Upstash QStash is a serverless message queue and cron service that integrates smoothly with Next.js, Cloudflare Workers, and other serverless platforms. Combined with Claude Code’s skill system, you can create powerful automated workflows that handle scheduled tasks intelligently. This guide walks you through setting up QStash scheduled tasks while using Claude Code’s capabilities for enhanced productivity.

Understanding QStash Scheduled Tasks

QStash provides HTTP-based task scheduling that works without dedicated servers. You send an HTTP request to QStash, specify when it should be delivered, and QStash calls your endpoint at the scheduled time. This approach offers several advantages over traditional cron jobs:

Setting Up Your Project

Before creating scheduled tasks, set up a basic Node.js project with the required dependencies:

mkdir my-scheduled-tasks && cd my-scheduled-tasks
npm init -y
npm install @upstash/qstash next

Create a .env.local file to store your QStash credentials:

QSTASH_TOKEN=your_qstash_token_here
QSTASH_NEXT_SIGNING_KEY=your_next_signing_key_here

Creating Scheduled Tasks with Claude Code

Here’s how to create a basic scheduled task using the QStash SDK:

import { QStash } from '@upstash/qstash';

const qstash = new QStash({
  token: process.env.QSTASH_TOKEN,
});

// Schedule a task to run every hour
await qstash.publish({
  url: 'https://your-domain.com/api/cronjob',
  schedule: '*/60 * * * *', // Cron expression for every 60 minutes
  body: JSON.stringify({
    task: 'data-sync',
    timestamp: new Date().toISOString()
  }),
});

The schedule field accepts standard cron expressions. QStash also supports human-readable intervals like in 1 hour or every day at 9am.

Integrating with Next.js API Routes

Create an API route to handle the scheduled task:

// pages/api/cronjob.js
import { verifySignature } from '@upstash/qstash/nextjs';

async function handler(req, res) {
  // Verify the request comes from QStash
  const body = await req.text();
  
  // Process the task
  const payload = JSON.parse(body);
  console.log('Received task:', payload.task);
  
  // Your business logic here
  await processScheduledTask(payload);
  
  res.status(200).json({ success: true });
}

export default verifySignature(handler);

The verifySignature middleware ensures only QStash can trigger your endpoint, adding security to your scheduled tasks.

Building a Claude Code Skill for Task Management

You can create a Claude Code skill to manage your QStash tasks more efficiently. Here’s a skill that helps you create, list, and delete scheduled tasks:

---
name: qstash-manager
description: Manage Upstash QStash scheduled tasks - create, list, and monitor cron jobs
---

# QStash Task Manager

This skill helps you manage scheduled tasks in Upstash QStash.

## Available Commands

### List All Scheduled Tasks

To view all your scheduled tasks, you'll need to call the QStash API:

```bash
curl -X GET "https://qstash.upstash.io/v2/scheduled" \
  -H "Authorization: Bearer $QSTASH_TOKEN"

Create a New Scheduled Task

Use the following pattern to create scheduled tasks:

curl -X POST "https://qstash.upstash.io/v2/schedules" \
  -H "Authorization: Bearer $QSTASH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "destination": "https://your-domain.com/api/handler",
    "schedule": "*/30 * * * *",
    "body": {"task": "cleanup"}
  }'

Delete a Scheduled Task

Remove a task by its schedule ID:

curl -X DELETE "https://qstash.upstash.io/v2/schedules/{scheduleId}" \
  -H "Authorization: Bearer $QSTASH_TOKEN"

Best Practices

When working with QStash scheduled tasks, keep these best practices in mind:

  1. Idempotency: Design your handlers to handle duplicate deliveries gracefully. Use the idempotencyKey parameter when publishing tasks.

  2. Error handling: Always return a 200 status code from your handler. QStash interprets non-2xx responses as failures and triggers retries.

  3. Payload size: Keep your request body under 1MB. For larger payloads, store the data in a database and pass only an ID.

  4. Monitoring: Use QStash’s dashboard to track task success rates and identify failing jobs quickly.

  5. Time zones: Cron expressions use UTC by default. Account for time zone differences when scheduling tasks.

Advanced: Dynamic Task Scheduling

You can create dynamic schedules based on business logic:

// Schedule tasks based on user activity patterns
const getOptimalSchedule = (userTimezone) => {
  const hour = new Date().getHours();
  return hour >= 9 && hour <= 18 
    ? '*/15 * * * *'  // Every 15 minutes during business hours
    : '*/60 * * * *'; // Every hour after hours
};

await qstash.publish({
  url: processUserDataEndpoint,
  schedule: getOptimalSchedule(user.timezone),
  body: JSON.stringify({ userId: user.id }),
});

Monitoring and Debugging

QStash provides built-in metrics. Check your task statistics:

curl "https://qstash.upstash.io/v2/stats" \
  -H "Authorization: Bearer $QSTASH_TOKEN"

The response includes delivery success rates, average latency, and retry counts.

Conclusion

Upstash QStash combined with Claude Code creates a powerful system for managing scheduled tasks. The serverless approach eliminates infrastructure concerns, while Claude Code skills provide a natural interface for task management. Start with simple cron jobs and gradually add complexity as your needs grow.

Remember to always design for failure, monitor your tasks, and keep payloads small. With these practices, you’ll build reliable scheduled task systems that scale effortlessly.

Built by theluckystrike — More at zovo.one