Trigger.dev Versions Save

Trigger.dev is the open source background jobs platform for TypeScript.

v2.1.0

8 months ago

runTask changes (@trigger.dev/sdk 2.1.0+)

The most important change to be aware of is that we've moved the options param to the third param, and made it optional. When you upgrade your package, you will need to change the order (or if you want you can remove the options).

//old package (@trigger.dev/sdk v2.0.14)
const response = await io.runTask(
  "my-task",
  //this param is required, name is required, and it's before the callback
  { name: "My Task" },
  async () => {
    return await longRunningCode(payload.userId);
  },
);

//new package (@trigger.dev/sdk v2.1.0)
const response = await io.runTask(
  "my-task",
  async () => {
    return await longRunningCode(payload.userId);
  },
  //options are third, and they're not required. name isn't required, if you do pass options.
  { name: "My Task" }
);

This change was made because it was sometimes annoying having to come up with a Task name, when there wasn't a good one. It also moves the most important param, the actual code you want to run, earlier.

New docker image: v2.1.0

If you're self-hosting you'll need to update to the latest image, before you update your packages to the latest. There are new API endpoints that the new packages use, as well as database migrations.

Integration improvements

Less rigid structure and generic support

Previously integrations had quite a rigid structure. Tasks could only live at the top-level. This also meant we couldn't do nice generic type support.

It meant we had slightly awkward names for some of the function calls as well.

//old package (@trigger.dev/openai v2.0.14)
const models = await io.openai.listModels("list-models");

//new package (@trigger.dev/openai v2.1.0)
//this still works
const models = await io.openai.listModels("list-models");
//this is new, and closely matches the official SDK structure
const models = await io.openai.models.list("list-models");

We've made sure that the new integration packages are all backwards compatible. You won't need to update your code to use the more structured Tasks.

integration.runTask

All the integrations now have a runTask function that allows you to more easily use a native SDK function we don't support:

const price = await io.stripe.runTask(
  "create-price",
  async (client, task) => {
    //client is the authenticated Stripe SDK
    return client.prices.create(
      {
        unit_amount: 2000,
        currency: "usd",
        product_data: {
          name: "T-shirt",
        },
      },
      {
        idempotencyKey: task.idempotencyKey,
      }
    );
  },
  //this is optional, it will appear on the Run page
  { name: "Create Price" }
);

Creating integrations

It's now easier to make them, as we've dropped the concept of AuthenticatedTasks. It's more intuitive and like regular code you're used to writing. The guide in the docs on creating integrations needs updating still, but will be done soon including how to add webhooks (currently missing).

Airtable integration (but no webhooks… yet)

The integration changes were required to give a great experience with Airtable. You can set the types of your Table and then use the SDK with nice types.

const airtable = new Airtable({
  id: "airtable-oauth",
});

//The types for my table
type Status = "Live" | "Complete" | "In progress" | "Planning" | "In reviews";
type LaunchGoalsAndOkRs = {
  "Launch goals"?: string;
  DRI?: Collaborator;
  Team?: string;
  Status?: "On track" | "In progress" | "At risk";
  "Key results"?: Array<string>;
  "Features (from 💻 Features table)"?: Array<string>;
  "Status (from 💻 Features)": Array<Status>;
};

client.defineJob({
  id: "airtable-example-1",
  name: "Airtable Example 1: getRecords",
  version: "0.1.0",
  trigger: eventTrigger({
    name: "airtable.example",
    schema: z.object({
      baseId: z.string(),
      tableName: z.string(),
    }),
  }),
  integrations: {
    airtable,
  },
  run: async (payload, io, ctx) => {
    //set the type on the table
    const table = io.airtable.base(payload.baseId).table<LaunchGoalsAndOkRs>(payload.tableName);

    //now everything that uses table has nice types
    const records = await table.getRecords("multiple records", { fields: ["Status"] });
    await io.logger.log(records[0].fields.Status ?? "no status");

    const aRecord = await table.getRecord("single", records[0].id);

    const newRecords = await table.createRecords("create records", [
      {
        fields: { "Launch goals": "Created from Trigger.dev", Status: "In progress" },
      },
    ]);

    const updatedRecords = await table.updateRecords(
      "update records",
      newRecords.map((record) => ({
        id: record.id,
        fields: { Status: "At risk" },
      }))
    );

    await io.wait("5 secs", 5);

    const deletedRecords = await table.deleteRecords(
      "delete records",
      updatedRecords.map((record) => record.id)
    );
  },
});

That Job:

  1. gets all the records (rows)
  2. gets a single record
  3. create a new record
  4. updates the record that was just created
  5. waits 5 seconds
  6. deletes the record that was created/updated

Unfortunately Airtable webhooks aren't quite ready yet. Airtable send such frequent webhooks, like when a user is typing in a cell, we need to batch the updates together so we're triggering tons of runs. They're coming soon though.

Package updates

All of the packages have been updated to 2.1.0.

  • @trigger.dev/airtable
  • @trigger.dev/sdk
  • @trigger.dev/github
  • @trigger.dev/openai
  • @trigger.dev/plain
  • @trigger.dev/resend
  • @trigger.dev/sendgrid
  • @trigger.dev/slack
  • @trigger.dev/stripe
  • @trigger.dev/supabase
  • @trigger.dev/typeform
  • @trigger.dev/astro
  • @trigger.dev/cli
  • @trigger.dev/core
  • @trigger.dev/eslint-plugin
  • @trigger.dev/express
  • @trigger.dev/nextjs
  • @trigger.dev/react

Upgrading all your packages with the CLI

To upgrade to the latest packages, run npx @trigger.dev/cli@latest update

v2.0.1

8 months ago

This release fixes various issues with run executions, including a pretty gnarly memory bloat issue when resuming a run that had a decent number of completed tasks (e.g. anything over a few). This has been released to cloud.trigger.dev but if you are self-hosting I recommend upgrading to this version ASAP.

Other notable fixes:

  • Run executions no longer are bound to a queue, which will allow more parallel runs in a single job (instead of 1). @ericallam
  • Serverless function timeouts (504) errors are now handled better, and no longer are retried using the graphile worker failure/retry mechanism (causing massive delays).
  • Fixed the job_key design of the performRunExecutionV2 task, which will ensure resumed runs are executed
  • Added a mechanism to measure the amount of execution time a given run has accrued, and added a maximum execution duration on the org to be able to limit total execution time for a single run. The default is 15 minutes and is stored in the Organization.maximumExecutionTimePerRunInMs column
  • Improved the dashboard performance when viewing a run with large task outputs. The perf issue was on account of syntax highlighting so any task with an output of greater than 1k lines will forego syntax highlighting.
  • #394 : Reduced graphile worker load by decreasing max attempt counts on tasks that hit development endpoints (thanks @Chigala!)

@trigger.dev/[email protected]

8 months ago

Patch Changes

Added additional triggers for PaymentIntent and Payout events (a1078249)

@trigger.dev/[email protected]

8 months ago

Patch Changes

  • Only use cached tasks if they are completed, otherwise retrying tasks will be considered successful (916a3536)
  • Updated dependencies:

@trigger.dev/[email protected]

8 months ago

Patch Changes

  • Fixes #391, now handling jobs when using new Job instead of client.defineJob (3028b6ad)

@trigger.dev/[email protected]

8 months ago

Patch Changes

  • provided a fix to the CLI dev command tunnel not working if you are already running ngrok (#407)
  • fix: init will no longer fail when outside of a git repo (3028b6ad)
  • feat: Checks for outdated packages when running the dev command with instructions on how to update (#412)

v2.0.0

8 months ago

Trigger.dev v2.0.0

We've dropped the beta label on our v2.0.0 release of the Trigger.dev service, and moving forward we'll be updating the version number like good semantic version citizens.

The following changes have been made in the last few weeks:

Increased performance

We've redesigned the way we queue and execute job runs in order to increase the speed of job execution.

  • Fixed the cached task miss issue in the @trigger.dev/sdk which should speed up resumed runs by A LOT
  • Allow setting graphile worker concurrency settings through env vars WORKER_CONCURRENCY and EXECUTION_WORKER_CONCURRENCY
  • Allow settings prisma pool settings through env vars DATABASE_CONNECTION_LIMIT and DATABASE_POOL_TIMEOUT
  • You can now selectively enable/disable the workers through WORKER_ENABLED=false and EXECUTION_WORKER_ENABLED=false. This means the image can be deployed as 2 or 3 separate services:
    • A WebApp service that serves the API and the Dashboard
    • A Worker service that runs tasks that have been added the standard worker
    • An Execution Worker service that only runs "run execution" tasks
  • Deprecated the JobOptions.queue options as we are no longer using that to control job concurrency. We'll add proper queue support in the future.

Fixed runs with large task outputs

We had an issue where runs that included tasks that had large task outputs could not be resumed after a delay. This was because we send completed task outputs in the request body when we resume a run, and some platforms have a limit on the size of the request body. We now cap the size of the task outputs we send in the request body to 3.5MB.

Disable and delete jobs

You can now disable jobs in your code by setting the enabled option to false:

client.defineJob({
  id: "example-job",
  name: "Example Job",
  version: "0.1.0",
  trigger: eventTrigger({ name: "example.event" }),
  enabled: false,
  run: async (payload, io, ctx) => {
    // your job code here
  },
});

Which will show the job as disabled in the dashboard:

CleanShot 2023-08-23 at 16 27 33

Once you've disabled your job, you can delete it from the dashboard:

CleanShot 2023-08-23 at 16 34 36

For more detailed information, checkout our documentation on managing jobs.

Cancel delayed events

When sending events, you can delay the delivery by setting either the deliverAt or deliverAfter option:

await client.sendEvent(
  {
    id: "event-1",
    name: "example.event",
    payload: { hello: "world" },
  },
  {
    deliverAfter: 1000 * 60 * 60 * 24, // 1 day
  }
);

You can now easily cancel delayed events to prevent subsequent job runs with the new cancelEvent method:

await client.cancelEvent("event-1");

This functionality requires @trigger.dev/[email protected] or later.

@trigger.dev/openai v2.0.11

We've updated our OpenAI package to use the new and improved v4 of the OpenAI SDK.

All of our existing tasks should work as before, but now when you use the .native property you'll get back and nice and shiny v4 SDK:

import { OpenAI } from "@trigger.dev/openai";

const openai = new OpenAI({
  id: "openai",
  apiKey: process.env["OPENAI_API_KEY"]!,
});

// Before: v3 SDK
openai.native.createCompletion({...});

// Now: v4 SDK
openai.native.completions.create({...});

We've also added some new tasks for enabling fine tuning jobs:

  • createFineTuningJob - Create a fine-tuning job for a fine-tuning model
  • retrieveFineTuningJob - Retrieve a fine-tuning job for a fine-tuning model
  • listFineTuningJobs - List fine-tuning jobs for a fine-tuning model
  • cancelFineTuningJob - Cancel a fine-tuning job for a fine-tuning model
  • listFineTuningJobEvents - List fine-tuning job events for a fine-tuning model

@trigger.dev/cli v2.0.11

Our CLI has been updated with some fixes and improvements:

  • 3ce5397: Added the send-event command
  • 3897e6e: Make it more clear which API key the init command expects
  • dd10717: Added --hostname option to the cli dev command
  • 8cf8544: Bugfix: @trigger.dev/cli init now correctly identifies the App Dir when using JS (thx @Chigala ✨)
  • 4e78da3: fix: Add an update sub-command the @trigger.dev/cli that updates all @trigger.dev/* packages (thx @hugomn ✨)
  • 135cb49: fixed the cli init log message to show the correct path to the app route created (thx @Chigala ✨)

@trigger.dev/react v2.0.11

  • a907e2a: chore: updated the type in the eventId argument (thx @Chigala ✨)

New package: @trigger.dev/astro ✨

Thanks to Liran Tal, we now have a native package to use Trigger.dev with Astro.

This is just the beginning and you can keep track of our progress on bringing Trigger.dev to Astro here

How to update

To update your existing projects to the latest version of the SDK, run the following command:

npx @trigger.dev/cli update

If you are self-hosting the Trigger.dev service, you'll need to update to the latest image:

docker pull triggerdotdev/trigger.dev:v2.0.0
# or
docker pull triggerdotdev/trigger.dev:latest@sha256:00d9d9646c3781c04b84b4a7fe2c3b9ffa79e22559ca70ffa1ca1e9ce570a799

If you are using the Trigger.dev Cloud, you'll automatically get the latest version of the service.

Upcoming changes

We're working on some exciting new features for upcoming releases:

Matt is working on our @trigger.dev/airtable integration, which will allow you to interact with Airtable from your jobs and trigger jobs on changes that occur in your Airtable bases. This one is taking a bit longer than expected on account of some interesting challenges and limitations in the Airtable Webhook implementation, but we're getting close.

Dan is working on a new Job Showcase repo and page on our public site to show off some example use-cases for Trigger.dev. We're hoping this will help people get started with Trigger.dev and give some ideas on how to use it in your own projects.

James is working on more dashboard improvements, which he'll be sharing on our Twitter/X soon.

Eric is working on a feature called Background Tasks, which will allow you to create specific tasks that can execute for up to 1 hour without pause. This will be useful for doing tasks that take longer than a serverless function timeout, like training ML models, or doing large data processing tasks.

As always, if you have any questions or feedback, please reach out to us on Twitter/X or Discord.