Overview

Upstash Workflow lets you write durable, reliable and performant serverless functions. Get delivery guarantees, automatic retries on failure, scheduling and more without managing any infrastructure.

Key Features

  • Failure Resilience: If your platform experiences a temporary outage, your workflow can pick up right where it left off. Upstash Workflows ensures that your application will continue, even when your environment is unstable.
  • Long-Running Executions on Time-Limited Platforms: Run long-running REST endpoints, such as complex AI models or video processing tools, even on serverless platforms with strict time limits.
  • Events with Wait/Notify Mechanism: Create workflows that wait for external events before proceeding. Ideal for use cases like waiting for user input (e.g., clicking a confirmation email) or handling asynchronous notifications from external systems.
  • Scheduled Jobs: Run jobs at regular intervals with support for cron expressions. Perfect for recurring tasks like reminders, regular reports, or newsletters. Set up scheduled jobs here.
  • Parallel Runs: Start independent tasks in parallel and wait for them to finish simultaneously, reducing latency. Read more about parallel runs here.
  • Long Delays: Need your code to “sleep” for days, weeks, or even months? Upstash Workflows supports long delays beyond the time limits imposed by serverless platforms.
  • Delivery Guarantees: Upstash Workflows guarantees at-least-once delivery. Once a request is accepted, it will run—even if the hosting platform experiences interruptions. In the rare case of failure, the request is logged in a Dead Letter Queue, so you never lose track of critical events.
  • Cost Reduction for Serverless Environments: Serverless platforms charge based on execution time. With Upstash Workflows, you can offload time-consuming, I/O-bound tasks from serverless platforms, reducing operational costs. See cost reduction example here.
  • Rate Limiting (Coming Soon): Prevent overwhelming external services by configuring rate limits for your workflows. Control the maximum number of operations per second, and ensure that burst traffic is managed without dropping any calls.
  • Observability: Monitor your application’s steps with comprehensive insights. Filter events to see which functions succeeded, failed, retried, or stalled. Learn more about observability here.

Quickstarts

Workflow supports Next.js, Cloudflare Workers and many more frameworks.

Example Use Cases

Here are some example real world use-cases for Upstash Workflow:

How it works

Upstash Workflow builds on the principle of steps. Instead of defining a single, complex piece of business logic, workflows contain multiple individual steps.

In case of an error, a failed step is retried individually without needing to re-run any previous steps. Instead of the entire business logic, each step can take up your serverless function execution duration, and many more benefits.

Next.js code example

Let’s see a practical implementation of Upstash Workflow using Next.js and customer onboarding as an example. See our Next.js Quickstart for a complete guide.

api/workflow/route.ts
import { serve } from "@upstash/workflow/nextjs";
import { sendEmail } from "./emailUtils";

// Type-safety for starting our workflow
interface InitialData {
  userId: string
  email: string
  name: string
}

export const { POST } = serve<InitialData>(async (context) => {
  const { userId, email, name } = context.requestPayload;

  // Step 1: Send welcome email
  await context.run("send-welcome-email", async () => {
    await sendEmail(email, "Welcome to our service!");
  });

  // Step 2: Wait for 3 days (in seconds)
  await context.sleep("sleep-until-follow-up", 60 * 60 * 24 * 3);

  // Step 3: AI-generate personalized follow-up message
  const { body: aiResponse } = await context.call(
    "generate-personalized-message",
    {
      url: "https://api.openai.com/v1/chat/completions",
      method: "POST",
      headers: { ... }
      body: {
        model: "gpt-3.5-turbo",
        messages: [
          { role: "system", content: "You are an assistant creating personalized follow-up messages." },
          { role: "user", content: `Create a short, friendly follow-up message for ${name} who joined our service 3 days ago.` }
        ]
      },
    }
  );

  const personalizedMessage = aiResponse.choices[0].message.content;

  // Step 4: Send personalized follow-up email
  await context.run("send-follow-up-email", async () => {
    await sendEmail(email, personalizedMessage);
  });
});

Any HTTP request using context.call, like the AI-generation above, does not count towards your function’s execution time and does not increase your serverless bill. It can also run for up to 2 hours, completely bypassing any platform-specific function timeouts.

The above example should give you a rough idea of how a workflow looks in code. For step-by-step instructions on setting up your first workflow with images along the way, see our Next.js Quickstart.


Here are more details about what the context object does:

See caveats for more complex API usage and best-practices when using Upstash Workflow.


Guides on common workflow topics:

If you’re curious about the behind-the-scenes about how we ensure separate step execution or prevent serverless timeouts, we wrote about it here! :)

Here is our Upstash Workflow roadmap to see what we planned for the future.