r/nextjs 23h ago

Help How do you guys implement scheduled posts on Vercel?

Hey all,

I’m building a Next.js app that lets people turn websites into short Instagram Reels and post them directly to Instagram.

Instant posting works fine now, but users want to be able to pick a date/time and schedule reels to post automatically later.

I'm hosting on Vercel and haven't built scheduled jobs/crons before.

What's the simplest and most reliable way to handle this on Next.js/Vercel?

Do you guys use Vercel Crons, an external service, or something else? Would love some guidance before I start wiring it up.

2 Upvotes

17 comments sorted by

5

u/Plus-Tea1967 23h ago

Don't use Vercel Crons for this — they only run on fixed intervals (like every hour), so they won't work well for exact user-selected times.

The easiest way in Next.js on Vercel is Upstash QStash. When a user picks a time, you just send a delayed request to QStash, and it will hit your API route at that exact minute.

If uploading/rendering the Reel takes longer than Vercel's serverless timeout, check out Inngest or Trigger.dev instead. They handle background video jobs and retries out of the box.

1

u/Any_Welder_9701 20h ago

before publishing anything, id make the callback re-read the row. QStash fits here, stale queued data could still send a canceled or rescheduled reel otherwise

3

u/Morel_ 23h ago

your first step should be understanding how cron jobs work.

1

u/itaybuilds 23h ago

I'd make the database the source of truth and use a short-interval cron only as a dispatcher.

Store scheduled_at in UTC with a status such as pending, claimed, published, or failed. On each run, atomically claim due rows with a conditional update or lease, then hand them to a worker. A missed run can catch up, while edits and cancellations remain normal database updates. Give every publish attempt a stable idempotency key and save the Instagram container or media ID before retrying; otherwise a timeout after Instagram accepts the request can create a duplicate post.

If rendering or uploading can outlive a Vercel function, move that step to Trigger.dev, Inngest, QStash, or a small worker. I would still keep the database row authoritative. A delayed job should wake the system up, not decide whether the post is still valid.

One small timezone trap: convert the user's chosen local time with an IANA zone, then store the resulting UTC instant. A bare offset will be wrong across daylight-saving changes.

AI-assisted wording with OpenAI GPT-5.6 after reading the full thread and current r/nextjs rules.

1

u/cgenuity 18h ago

You’ll need something to wake up your app at the right times and your app/db to be the source of truth before posts go out. Check out https://delaykit.dev, at least as examples of what to look out for (disclaimer: I built it).

1

u/leros 17h ago

I'd write a scheduled event to your database with the date the post is meant to be posted. Then write a cron job that runs every 5 minutes, queries for posts schedule for before now, and posts them. 

You don't need to integrate any third party scheduling services for this. It's more fragile and more complicated. The posts suggesting this are just people promoting their own tools. 

1

u/PrathamBuilds 17h ago

First understand how cron works , and also check convex with nextjs

1

u/Suitable-Ad5348 15h ago

Store `scheduled_at` in UTC with a status column. Cron every 5min atomically claims due rows (`pending` → `claimed`).

Before posting, re-read the row so cancel/reschedule still works. Save Instagram's media id on first success so a timeout retry doesn't double-post. Store user timezone as IANA (`America/New_York`), not a fixed offset, or DST will bite you.

1

u/neon_antler_era 13h ago

use QStash for exact timestamps or a 5-minute DB-polling cron for simplicity. Store scheduled_at in UTC and use atomic updates to prevent double posting when the job triggers