New to Claude Skills? Learn how to install them โ†’

Ulobehub on GitHub

Upstash Workflow

Free

Streamline asynchronous workflows in LobeHub.

by lobehub81.5k stars on lobehub/lobehub
1 views
Updated Aug 1, 2026
Get this skill

Free ยท Opens the source repo

What Upstash Workflow does

The Upstash Workflow skill provides a structured approach to implementing asynchronous workflows within the LobeHub codebase. It is designed for developers looking to manage complex workflows while adhering to constraints such as rate limits and idempotency. This skill introduces three core patterns: Dry-Run Mode for testing without execution, the Fan-Out Pattern for processing large batches in manageable chunks, and Single Task Execution for ensuring that each workflow instance handles only one item at a time.

By utilizing these patterns, developers can create efficient workflows that minimize the risk of exceeding execution limits and ensure that retries do not lead to duplicate processing. The architecture is divided into three layers: the Entry Point for validation and triggering, Pagination for handling large datasets, and Single Task Execution for executing business logic. This separation of concerns not only enhances code readability but also allows for easier debugging and maintenance.

The skill is particularly useful for teams working with asynchronous operations that require precise control over execution flow and resource management. It is ideal for applications that need to process large datasets or manage multiple tasks concurrently while ensuring that each operation is performed correctly and efficiently. The provided implementation guide includes best practices, examples, and a checklist to help developers smoothly integrate workflows into their applications.

When to use it

Use this skill when building workflows that require processing of large datasets or when you need to ensure that tasks are executed in a controlled manner without exceeding limits.

When not to use it

This skill may not be suitable for simple synchronous workflows or applications that do not require complex processing logic.

What you can build with it

Testing Workflow Execution

Use Dry-Run Mode to simulate workflow processing and determine how many items will be affected before executing.

Handling Large Data Sets

Implement the Fan-Out Pattern to split large batches of items into smaller chunks for efficient processing.

Ensuring Idempotency

Utilize Single Task Execution to guarantee that each workflow execution processes only one item, preventing duplicate operations.

How to install Upstash Workflow

View source

1. Install with the skills CLI

npx skills add lobehub/lobehub/upstash-workflow --agent claude-code

2. Or install it manually

Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.

Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs

Inside SKILL.md

Written by lobehub

Upstash Workflow Implementation Guide

Standard patterns for implementing Upstash Workflow + QStash async workflows in the LobeHub codebase.

๐ŸŽฏ The Three Core Patterns

Every workflow in LobeHub combines these three patterns. They exist because the platform constrains you in three ways: rate limits make blind fan-out dangerous, step limits cap a single workflow's size, and idempotency demands that retries don't double-process.

  1. ๐Ÿ” Dry-Run Mode โ€” get statistics without triggering actual execution
  2. ๐ŸŒŸ Fan-Out Pattern โ€” split large batches into smaller chunks for parallel processing
  3. ๐ŸŽฏ Single Task Execution โ€” each workflow execution processes exactly ONE item

Architecture Overview

All workflows follow the same 3-layer architecture:

Layer 1: Entry Point (process-*)
  โ”œโ”€ Validates prerequisites
  โ”œโ”€ Calculates total items to process
  โ”œโ”€ Filters existing items
  โ”œโ”€ Supports dry-run mode (statistics only)
  โ””โ”€ Triggers Layer 2 if work is needed

Layer 2: Pagination (paginate-*)
  โ”œโ”€ Handles cursor-based pagination
  โ”œโ”€ Implements fan-out for large batches
  โ”œโ”€ Recursively processes all pages
  โ””โ”€ Triggers Layer 3 for each item

Layer 3: Single Task Execution (execute-* / generate-*)
  โ””โ”€ Performs actual business logic for ONE item

Real examples in this codebase: welcome-placeholder, agent-welcome โ€” see references/examples.md.


The Three Patterns in 60 Seconds

1. Dry-Run Mode

Short-circuit Layer 1 before any side effects so callers can preview what would happen:

if (dryRun) {
  return {
    ...result,
    dryRun: true,
    message: `[DryRun] Would process ${itemsNeedingProcessing.length} items`,
  };
}

Use case: check how many items will be processed before committing.

2. Fan-Out Pattern

Layer 2 splits oversized batches into chunks and recursively re-triggers itself with each chunk. This avoids hitting workflow step limits when one page contains too many items:

const CHUNK_SIZE = 20;

if (itemIds.length > CHUNK_SIZE) {
  const chunks = chunk(itemIds, CHUNK_SIZE);
  await Promise.all(
    chunks.map((ids, idx) =>
      context.run(`workflow:fanout:${idx + 1}/${chunks.length}`, () =>
        WorkflowClass.triggerPaginateItems({ itemIds: ids }),
      ),
    ),
  );
}

Defaults: PAGE_SIZE = 50 (items per page), CHUNK_SIZE = 20 (items per fan-out chunk).

3. Single Task Execution

Layer 3 always processes exactly one item per invocation. Parallelism comes from Layer 2 fanning out to many Layer 3 invocations, controlled by flowControl:

export const { POST } = serve<ExecutePayload>(
  async (context) => {
    const { itemId } = context.requestPayload ?? {};
    if (!itemId) return { success: false, error: 'Missing itemId' };

    const item = await context.run('workflow:get-item', () => getItem(itemId));
    const result = await context.run('workflow:execute', () => processItem(item));
    await context.run('workflow:save', () => saveResult(itemId, result));

    return { success: true, itemId, result };
  },
  {
    flowControl: { key: 'workflow.execute', parallelism: 10, ratePerSecond: 5 },
  },
);

File Structure

src/
โ”œโ”€โ”€ app/(backend)/api/workflows/
โ”‚   โ””โ”€โ”€ {workflow-name}/
โ”‚       โ”œโ”€โ”€ process-{entities}/route.ts      # Layer 1
โ”‚       โ”œโ”€โ”€ paginate-{entities}/route.ts     # Layer 2
โ”‚       โ””โ”€โ”€ execute-{entity}/route.ts        # Layer 3
โ”‚
โ””โ”€โ”€ server/workflows/
    โ””โ”€โ”€ {workflowName}/
        โ””โ”€โ”€ index.ts                          # Workflow class

Where to Go Next

Pick the reference that matches what you're doing:

You want to...Read
Write the Workflow class + 3 routes from scratchreferences/implementation.md
Tune flowControl, error handling, logging, testingreferences/best-practices.md
See two real workflows end-to-endreferences/examples.md
Deploy on lobehub-cloud (re-exports, cloud-only ops)references/cloud.md

Environment Variables

# Required for all workflows
APP_URL=https://your-app.com # Base URL for workflow endpoints
QSTASH_TOKEN=qstash_xxx      # QStash authentication token

# Optional (for custom QStash URL)
QSTASH_URL=https://custom-qstash.com

Checklist for New Workflows

Planning

  • Identify the entity to process (users, agents, items, โ€ฆ)
  • Define the per-item business logic
  • Determine filtering logic (Redis cache, database state, โ€ฆ)

Implementation

  • Define payload types with TypeScript interfaces
  • Create workflow class with static trigger methods
  • Layer 1: entry point with dry-run support
  • Layer 1: filtering logic to avoid duplicate work
  • Layer 2: pagination with fan-out
  • Layer 3: single-task execution (ONE item per run)
  • Configure appropriate flowControl for each layer
  • Consistent logging with workflow prefixes
  • Validate all required payload parameters
  • Unique context.run() step names

Quality & Deployment

  • Return consistent response shapes
  • Configure cloud deployment (references/cloud.md if on lobehub-cloud)
  • Write integration tests (dryRun path + full path)
  • Smoke-test with dry-run first
  • Test with a small batch before full rollout

Additional Resources

Frequently asked questions about Upstash Workflow

Similar skills