Does Vercel Cron Remember Previous Runs? The Stateless Truth, and How Scheduled AI Jobs Keep Context
Does Vercel Cron Remember Previous Runs? The Stateless Truth, and How Scheduled AI Jobs Keep Context Short answer: no. Every Vercel Cron invocation is a brand-new HTTP GET request to a route in your app. Your handler runs as a serverless function, finishes, and everything in memory disappears with it. Vercel keeps past-run logs in your dashboard, but your code cannot read them, and nothing about the previous run is handed to the next one. If your cron job needs to know what happened last time,
Does Vercel Cron Remember Previous Runs? The Stateless Truth, and How Scheduled AI Jobs Keep Context
Short answer: no. Every Vercel Cron invocation is a brand-new HTTP GET request to a route in your app. Your handler runs as a serverless function, finishes, and everything in memory disappears with it. Vercel keeps past-run logs in your dashboard, but your code cannot read them, and nothing about the previous run is handed to the next one. If your cron job needs to know what happened last time, you have to store that somewhere yourself.
How a Vercel Cron run actually works
Vercel Cron is configured with a crons array in vercel.json: a path plus a schedule in standard cron syntax, always in UTC. On schedule, Vercel sends a GET request to that path on your production deployment, with an Authorization: Bearer header carrying your CRON_SECRET so the route can verify the call genuinely came from Vercel.
That route is an ordinary serverless function. It spins up, runs your code, returns a response, and shuts down. The next scheduled run does the exact same thing from scratch. There is no warm state passed between invocations, no built-in "previous run" object, and no automatic retry of failed invocations: delivery is best-effort, so a run can occasionally be missed or duplicated. On the Hobby plan, crons are limited to once per day and can fire anywhere inside a time window rather than exactly on the minute.
This design suits stateless chores: rebuild a sitemap, ping an endpoint, rotate a cache. It breaks down the moment the job itself needs continuity.
Where the amnesia bites: scheduled AI agents
More and more Vercel Cron jobs now run AI agents: a morning digest that summarizes new signups, a watchdog that checks a supplier API for price changes, a lead-enrichment loop that scores new rows and posts the hot ones to Slack.
Each wakes up blank. In practice:
- The digest agent cannot tell what it already reported yesterday, so it re-sends the same highlights unless you deduplicate by hand.
- The watchdog agent cannot compare "current state" against "state at the last check," so every run either reports everything (noise) or nothing useful.
- The enrichment agent does not remember which leads it already scored, so a retried run scores them twice and burns tokens twice.
None of this is a bug. The cron did exactly what it was built to do: call your endpoint on a schedule. Memory was never part of the contract.
Option 1: store cursors in KV or Postgres
The classic fix: persist a small piece of state yourself. Many operators write a lastRun timestamp or lastProcessedId to Vercel KV or Postgres at the end of each run, and read it back at the start of the next one.
This works well for cursors: "only process rows newer than this timestamp," "skip IDs I have already seen." It costs almost nothing and stays entirely under your control. Its limits show up quickly once an agent is involved. A cursor tells the agent where to resume, not what it decided, what failed, what the user corrected, or why a lead was scored the way it was. You end up encoding judgment calls into database columns, and the schema grows with every new thing the agent must recall.
Option 2: keep a full run log in Postgres
The next step up is logging everything per run: inputs, model outputs, decisions, errors, queryable by time and job. This is the right move for auditability and debugging, and many teams already do it.
But a run log is not agent memory. It is write-heavy and read-awkward: to give the next run "what matters from the last ten runs," your code has to query, rank, and summarize the log before the agent even starts. You end up rebuilding retrieval on top of a database, and paying for summarization tokens on every run.
Option 3: give the agent a memory layer
The third option is to stop storing agent memory in application plumbing and hand the agent a dedicated memory layer it can read and write like a tool.
Vilix AI is built for exactly this pattern. It is cloud-hosted, so there is nothing to run inside your Vercel function: the agent connects over MCP, reads relevant context at the start of the run ("what did I decide about these leads last Tuesday," "which alerts already fired"), and saves what happened back at the end. The memory holds full conversation history, not just extracted facts, so nothing about reasoning or corrections gets flattened away. And because the same memory is shared across every tool over MCP, the scheduled run on Vercel, a debugging session in Claude Code, and a manual re-run from a laptop all stay in sync. It runs on a free plan that stays free, with a 7-day Pro trial that asks for no credit card, and you can export or delete everything at any time.
A note on Vercel Workflows: Vercel also offers a durable-execution product that checkpoints the steps of a long-running workflow. That solves orchestration reliability (resuming a workflow midway after a failure), which is a different problem from agent memory. Durable execution remembers where the workflow was; a memory layer remembers what the agent learned. For an agent cron, you usually want both, not one instead of the other.
A practical pattern for a memory-backed cron agent
A shape that works well:
- The cron handler verifies the
CRON_SECRETbearer token, then asks the memory layer for context relevant to this run. - The agent does its work with that context loaded: dedup against already-reported items, compare current state with the last recorded state, skip already-handled records.
- At the end of the run, the agent saves a short record of what it did, what it decided, and what failed.
The run itself stays stateless. The continuity lives in the memory layer, where it belongs. Missed or duplicated invocations stop being disasters: a duplicate run reads the same memory, sees the work is done, and exits quietly.
Quick answers
Can my code read the previous run's logs? No. Past run logs live in the Vercel dashboard for you to inspect; there is no API that hands them to the next invocation. If the next run needs to know something, store it.
Does upgrading to a paid plan add memory? No. Paid plans raise frequency and execution-time limits; they do not add state between runs.
KV or a memory layer: which one? KV for cursors and flags, a memory layer for context, decisions, and history. Most serious setups end up with both: a tiny cursor in KV, the agent's actual memory in the layer.
The bottom line
Vercel Cron remembers nothing between runs, by design. Your scheduled AI agent does not have to inherit that amnesia. Give the plumbing a cursor, give the agent a memory, and every run starts informed instead of blind.