Cloud Scheduler retries and a static Idempotency-Key: the replay trap

A fixed Idempotency-Key header on a Cloud Scheduler POST replays the first Sume run forever. Derive the key per tick, or use Sume Actions for schedules.

5 min readSume
All posts

Do not put a fixed Idempotency-Key header on a Cloud Scheduler job that calls Sume. Sume returns the original result for the same key and the same body, so every later tick replays the first run and generates nothing new. Build the key from the tick instead, or let Sume Actions own the schedule.

Cloud Scheduler retry facts

From Google's retry configuration page:

Cloud Scheduler retry settings (read 2026-10-02)
SettingValue
retryCountDefault 0, max 5
Min backoff5 s
Max backoff3,600 s
Max doublings5

Why a static key is wrong and a per-tick key is right

The job's headers are fixed text, so Scheduler cannot generate a fresh value per run. Sume treats the same key and the same body as one request and returns the original. If the body also never changes, each tick is a replay. If the body carries a date but the key does not, the second tick returns 409 idempotency_conflict.

The safe design is a tiny endpoint you own. Scheduler calls it, the endpoint computes a key from the schedule id and the tick date, then calls Sume. Scheduler retries of the same tick then reuse one key, which is what you want, while tomorrow gets a new key.

Or let Sume run the schedule

Sume Actions are a scheduled primitive with their own API at /v1/actions and /v1/action-runs. A finished action run emits action.run.terminal with a status of OK or ERROR, an outcome and a payload receipt, signed like other webhooks. Canceled and skipped runs deliver no webhook, so do not wait for one.

  • Use Scheduler when the schedule belongs to your infrastructure and you need a call into your own code.
  • Use Actions when the schedule is part of the Sume workflow itself.
  • Never ask both to run the same work.

Retry settings that match paid calls

Keep retryCount low for a call that can spend money, and make sure every retry within a tick carries the tick's key. A retry that gets 429 rate_limited should honour retry-after. A 402 insufficient_credits should not be retried. If your endpoint returns quickly after creating a job in async mode, the retry budget is rarely needed.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume