thyme/labs
Start building
Thyme Flow

Migrate from Chainlink Automation

Keep the upkeep. Change the keeper.

If your contract implements checkUpkeep and performUpkeep, Flow can call them as they are. A short TypeScript task reads checkUpkeep on every run and sends performUpkeep when it returns true. Time-based upkeeps become a cron trigger.

Read on every run
checkUpkeep
Replaces time-based upkeeps
Cron
Gas charged in USD
No LINK

01 / Mapping

Each upkeep type has a match.

Automation simulated checkUpkeep off-chain and sent performUpkeep when it returned true. A Flow task does the same thing on the schedule you choose.

Chainlink AutomationThyme FlowNotes
Chainlink AutomationCustom logic upkeepThyme FlowA task that reads checkUpkeep and returns a performUpkeep callThe contract does not change. See the task below.
Chainlink AutomationTime-based upkeepThyme FlowA cron triggerThe task returns the target function call directly, with no check contract.
Chainlink AutomationLog trigger upkeep (checkLog)Thyme FlowAn interval trigger that polls getLogsKeep the last processed block in ctx.storage and skip when there are no new logs.
Chainlink AutomationcheckDataThyme FlowA task argumentSet it per executable in the console.
Chainlink AutomationOff-chain simulation by Automation nodesThyme FlowAn eth_call from run on every triggerYou choose how often: from every 30 seconds to once a day, or a cron expression.
Chainlink AutomationUpkeep balance in LINKThyme FlowWorkspace dBank credit in USDMainnet gas is sponsored and charged to dBank. Testnet gas is free.
Chainlink AutomationForwarder as msg.senderThyme FlowYour Safe as msg.senderAllow the Safe address wherever your contract allowed the forwarder.
Chainlink AutomationAutomation App: pause, cancel, historyThyme FlowFlow console: pause, resume, execution logsEach run records its decision, the calls it sent and the transaction hash.

02 / Code

One task for any upkeep.

This task works with any contract that implements the Automation interface. Point upkeep at the contract, pass the same checkData, and pick an interval.

contracts/Counter.solUnchanged
// Your contract keeps its Automation interface
function checkUpkeep(bytes calldata checkData)
    external view returns (bool upkeepNeeded, bytes memory performData)
{
    upkeepNeeded = block.timestamp - lastRun > interval;
    performData = checkData;
}

function performUpkeep(bytes calldata performData) external {
    require(block.timestamp - lastRun > interval, "too early");
    lastRun = block.timestamp;
    // your work here
}
functions/upkeep/index.tsThyme Flow
import { defineTask, z } from '@thyme-labs/sdk'
import { encodeFunctionData, parseAbi, type Hex } from 'viem'

const abi = parseAbi([
  'function checkUpkeep(bytes) view returns (bool, bytes)',
  'function performUpkeep(bytes)',
])

export default defineTask({
  schema: z.object({
    upkeep: z.address(),
    checkData: z.string().default('0x'),
  }),
  async run(ctx) {
    const [upkeepNeeded, performData] = await ctx.client.readContract({
      address: ctx.args.upkeep,
      abi,
      functionName: 'checkUpkeep',
      args: [ctx.args.checkData as Hex],
    })
    if (!upkeepNeeded) {
      return { canExec: false, message: 'checkUpkeep returned false' }
    }

    return {
      canExec: true,
      calls: [{
        to: ctx.args.upkeep,
        data: encodeFunctionData({
          abi,
          functionName: 'performUpkeep',
          args: [performData],
        }),
      }],
    }
  },
})

03 / Steps

From upkeep to executable.

Move one upkeep at a time. Simulate it locally against the chain first, then schedule it.

  1. 01

    Install the CLI and scaffold a task

    Create a project and a task for the upkeep.

    npm install -g @thyme-labs/cli
    thyme init my-flow-project
    cd my-flow-project && npm install
    thyme new upkeep
  2. 02

    Paste the upkeep task

    Use the task above and put the upkeep contract and its checkData in args.json.

    { "upkeep": "0xYourUpkeepContract", "checkData": "0x" }
  3. 03

    Simulate it against the chain

    Set RPC_URL and SIMULATE_ACCOUNT in .env and run the task. It shows whether checkUpkeep returned true and the call it would send.

    thyme run upkeep
  4. 04

    Declare performUpkeep

    Add permissions.json so the release may only call performUpkeep on the upkeep contract.

    {
      "calls": [
        { "target": { "arg": "upkeep" }, "function": "performUpkeep(bytes)" }
      ]
    }
  5. 05

    Upload and schedule it

    Upload a release, set up a Safe profile that allows performUpkeep on the contract, and create an executable on an interval that suits the upkeep.

    thyme upload upkeep --tag v1
  6. 06

    Allow the Safe in your contract

    If performUpkeep only accepts the Automation forwarder, allow your Safe address instead. Then use Execute now in the console to confirm the first run.

04 / Differences

Flow or CRE.

Chainlink's own replacement is CRE. Flow is a simpler hosted keeper. These are the differences that decide between them.

A hosted keeper, not a network

CRE runs each workflow step on a decentralized oracle network and reaches consensus on the result. Flow runs your task on Thyme infrastructure and sends calls from your Safe. If you need consensus on every run, use CRE.

No receiver contract to deploy

Flow calls performUpkeep on your contract from your Safe. There is no bridge or receiver contract in between, so the only contract change is allowing the Safe when performUpkeep checks the sender.

No LINK to hold

Gas is charged in USD to the workspace dBank, and the plan covers compute. There is no token balance to keep topped up per upkeep.

You set the check frequency

Automation checked on every block. Flow checks on your interval or cron, so pick one that matches how quickly the upkeep needs to react.

05 / FAQ

Questions

Is Chainlink Automation still running?
No. Chainlink deprecated Automation v1.x on June 30, 2026 and v2.1 on July 31, 2026. Chainlink's own path forward is CRE, its runtime for Go and TypeScript workflows.
Do I need to change my contract?
Usually not. checkUpkeep and performUpkeep stay as they are. If performUpkeep only accepts the Automation forwarder as msg.sender, allow your Safe address too.
Which chains does Flow support?
Mainnet automation runs on Polygon, OP Mainnet and BNB Smart Chain, and Ethereum Sepolia is available for testing. The console lists the networks enabled for your workspace. If you need another EVM chain, write to support@thymelabs.io.
Does Thyme hold the keys to my funds?
No owner key. With a Safe profile, Thyme runs an executor that is a member of one role on your Safe. That role only allows the contracts and functions you approve, and you can remove it from the Safe at any time.
How much does Flow cost?
The Free plan covers testnets. Pro is $29 a month and Ultimate is $149 a month, both with mainnet access and more executables. Mainnet gas is sponsored and charged in USD to your workspace's prepaid dBank credit, so you do not keep a gas token on each chain.
Can you help move our upkeeps?
Yes. Send the upkeep contract address and chain to support@thymelabs.io and we will help you set up the task and check the first runs.

Start here

Same upkeep. Running again.

Point one task at your upkeep contract, simulate it, and schedule it from your own Safe.