Off-Peak AI Agent Scheduling: Route Flexible Work by the Clock, Not by Vibe

Off-peak AI agent scheduling by the clock: classify jobs, map DeepSeek's UTC peak hours and Anthropic's cache timers, route with caps, and review weekly.

Off-peak AI agent scheduling by the clock: a 24-hour UTC strip for one weekday with two peak blocks, a latency-bound job chip that runs now and a flexible job chip that waits for the off-peak window
Latency-bound jobs run when asked. Flexible jobs run when the price says so. The router is the only part that needs a clock.

It is 09:30 UTC on a Tuesday, and a research agent that nobody will read until Thursday is paying DeepSeek’s peak rate because someone pressed Enter when the idea occurred to them. Thirty minutes later the same job would have cost half. Nothing about the job changed at 10:00; only the price did, and the fleet had no way to know.

Off-peak AI agent scheduling is the fix, and it is smaller than it sounds: a job classifier, a calendar of provider windows, a routing table with caps, and a weekly review of what moved. By next Tuesday every recurring job in your fleet carries a class, latency-bound or flexible; every flexible job knows the cheapest window it may wait for and the longest it may wait; every lane has a ceiling; and Friday’s review shows what ran where, what it cost, and what waited too long.

Two pieces of September pricing weather make the schedule worth writing now, and they pull in different directions. DeepSeek’s discount is a clock. Anthropic’s is a cache with a timer. A router that only understands one of them will route the other one wrong.

Two discounts, two dialects: a clock and a cache timer

On September 10, 2026, DeepSeek launched V4.1-Flash with a price cut and a repeat of its standing rule, stated in the launch post as “Off-peak rates are 50% of peak rates. Schedule flexible workloads off-peak to save.” The window is defined on the pricing page by its peak hours, 01:00 to 04:00 and 06:00 to 10:00 UTC, Monday through Friday, excluding Chinese public holidays. Then: “All other hours are off-peak, including weekends and Chinese public holidays in full.”

The deepseek-flash model bills a cache hit at $0.006 per million tokens at peak and $0.003 off-peak, a cache miss at $0.30 and $0.15, and output at $1.20 and $0.60.

DeepSeek API docs pricing page showing the per-token table with off-peak and peak rows, the concurrency limit row, and footnote 2 stating the peak hours in UTC Screenshot: DeepSeek API Docs, “Models & Pricing” (page undated), captured Sep 19, 2026.

Nine days earlier, on September 1, 2026, Anthropic released Claude Fable 5.1 with no clock at all. The launch page says “Cache reads now cost 75% less, or $0.25 per million tokens.” and claims that “For typical workloads, costs are reduced by around 25% relative to Fable 5. For complex coding and highly agentic tasks, the savings could be up to around 45%.”

Those are Anthropic’s numbers, and the chart they sit under carries the method: “Indexed cost of running the same workloads on Fable 5 and Fable 5.1, at usage-based pricing measured at default effort over four weeks of actual usage in August 2026.” The pricing docs put the multiplier at 0.025× the $10 base input price, against 0.1× on every other Claude model.

Anthropic’s launch page for Claude Fable 5.1 and Claude Mythos 5.1, dated September 2026, with a five-part table of contents from Introduction to Claude Mythos 5.1 Screenshot: Anthropic, “Introducing Claude Fable 5.1 and Claude Mythos 5.1” (September 2026), captured Sep 19, 2026.

The timer is in the prompt caching docs: “By default, the cache has a 5-minute lifetime. The cache is refreshed for no additional cost each time the cached content is used.” A one-hour lifetime costs 2× base input to write instead of 1.25×, and the pricing docs say “caching pays off after one cache read for the 5-minute duration (1.25x write), or after two cache reads for the 1-hour duration (2x write)”.

So Anthropic’s window is not an hour of the day. It is the gap between two calls that share a prefix.

There is a third dialect, and it is neither a clock nor a timer. OpenAI’s GPT-6 Astra model page says “Batch and Flex are priced at 50% of Standard rates.” and Anthropic’s batch pricing puts Fable 5.1 at $5 input and $25 output, half of standard. A queue with a discount: you give up the right to say when, and the provider gives up half the price. Three discounts, and each one asks you to promise something different.

Why off-peak AI agent scheduling needs a router, not a reminder

Chatbots suggest; agents act, and the ones that act overnight, in fan-outs, on recurring schedules, are the ones whose start time nobody is watching. A reminder in a channel to run the big jobs after 10:00 UTC lasts until the first person in a different time zone joins the team. A router that reads the job’s class and the provider’s window, and refuses to release a flexible job into a peak block, lasts as long as the config does.

The sibling pieces cover the two providers in depth: the DeepSeek off-peak and cache-hit runbook for prefix shape and re-based budgets, and metering overnight Claude jobs on cheaper cache reads for the dollars-per-job ledger. This piece is the schedule that sits above both.

Step 1: Classify every recurring job as latency-bound or flexible, in writing

A job is latency-bound if a person or a pipeline is waiting on its output, or if its inputs go stale faster than the wait. Everything else is flexible, and flexible is the default: a job earns latency-bound status by naming who is waiting.

Job (examples) Class Max delay Cache shape Runs multi-turn Default lane
PR review on open MRs latency-bound 15 min stable prefix per repo yes, short nearest lane, any window
CI failure triage latency-bound 10 min small prefix yes, short nearest lane, any window
Nightly literature or competitor research flexible 14 h stable prefix, long tail yes, long DeepSeek off-peak
Eval reruns after a model change flexible 24 h stable prefix per suite yes DeepSeek off-peak, or batch
Doc sweeps, changelog drafts flexible 24 h stable prefix per repo yes Anthropic, 1-hour cache, no clock
Bulk classification, one-shot summaries flexible 48 h none reused no batch lane, 50%
Fan-out research (many workers) flexible 14 h stable prefix per worker yes DeepSeek off-peak, capped

Write the max delay as a number, not a mood. It is the field the router uses to decide whether a job can wait for the next off-peak edge, and the field the weekly review uses to catch jobs that waited longer than they were allowed to.

Step 2: Map every provider window onto one UTC calendar

One calendar, one time zone, and it is UTC: DeepSeek writes its window in UTC, and UTC never shifts for daylight saving.

Chart of DeepSeek’s 24-hour UTC pricing day as a single-row timeline: indigo peak blocks from 01:00 to 04:00 and from 06:00 to 10:00, light off-peak tint everywhere else at 50% of peak, weekdays only, with weekends and Chinese public holidays off-peak in full Seven peak hours per weekday, split by a two-hour trough. The other seventeen, plus every weekend hour, are half price. Source: DeepSeek API pricing page; pricing effective Sep 10, 2026.

The DeepSeek window in local clocks for September, for the people who will read the schedule:

Peak block UTC Beijing (UTC+8) Central Europe, CEST (UTC+2) US Pacific, PDT (UTC−7)
Morning peak 01:00–04:00 09:00–12:00 03:00–06:00 18:00–21:00 previous day
Afternoon peak 06:00–10:00 14:00–18:00 08:00–12:00 23:00 previous day–03:00
Off-peak stretch 10:00–01:00 18:00–09:00 12:00–03:00 03:00–18:00

The blocks line up with Beijing’s working day, midday break included, and the whole weekend is off-peak. Two things the docs do not give you: the list of Chinese public holidays, and any promise that the window stays put. Keep the holiday list as a file in the repo, re-check the pricing page each quarter, and recompute the local columns when Europe and the US leave summer time on October 25 and November 1.

Anthropic’s row on the same calendar is a rule rather than a block: a job that reuses a prefix must either keep its calls within five minutes of each other or pay for the one-hour cache. The docs’ own advice is to “send a new pre-warm request at least every 5 minutes to keep the cache warm. For longer gaps between user requests, use the 1-hour cache duration instead.”

A tool call that runs a twelve-minute test suite between two model calls silently breaks the five-minute cache, and the next call writes the prefix again at 1.25×. That is the Anthropic equivalent of a peak hour: an idle gap.

The batch row has no window either, only a promise you make about not needing the answer soon. It belongs on the calendar as a lane, not a time.

# provider-windows.yaml (illustrative shape; one file, read by the router only)
deepseek:
  kind: clock
  tz: UTC
  peak_blocks: {days: [Mon, Tue, Wed, Thu, Fri], hours: ["01:00-04:00", "06:00-10:00"]}
  holidays_file: calendars/cn-public-holidays-2026.yaml     # off-peak in full
  off_peak_multiplier: 0.5
  model: deepseek-flash
anthropic:
  kind: cache_timer
  model: claude-fable-5-1
  cache_ttl_default: 5m          # refreshed at no cost on each use
  cache_ttl_long: 1h             # 2x write instead of 1.25x; use when call gaps exceed 5m
  min_cacheable_tokens: 512
batch:
  kind: queue
  discount: 0.5                  # OpenAI Batch/Flex; Anthropic Batch API
  deadline_hint: "the provider sets the turnaround, not you; treat as flexible with max delay >= 24h"

Step 3: Write the routing table, and put a cap on every row

The router reads the job’s class, max delay and cache shape, and picks a lane and a release time. Every row carries a cap, because a scheduler that knows when to run a job but not how many to run at once has only learned half the trick; the arithmetic for the concurrency half is in metering subagent fan-out.

Class Cache shape Lane Release rule Caps (illustrative)
Latency-bound any nearest healthy lane now $2 per job; 8 concurrent
Flexible, multi-turn, stable prefix prefix reused across turns DeepSeek off-peak next off-peak edge, wait ≤ max delay $1 per job; $40 per night; 12 concurrent
Flexible, multi-turn, slow tools prefix reused, call gaps > 5 min Anthropic, 1-hour cache now, no clock $6 per job; $60 per night; 4 concurrent
Flexible, one-shot bulk no prefix reuse batch lane (50%) enqueue immediately $25 per batch; 1 batch in flight per suite
Flexible fan-out prefix reused per worker DeepSeek off-peak, capped 10:00 UTC weekday or 00:00 UTC Saturday 16 workers; $80 per fan-out
Any, provider degraded any next lane in the failover matrix now same caps, alert on switch

The last row is the one people forget. A job routed off-peak to a lane that is degraded at 10:00 UTC either waits (fine, if within max delay) or fails over (fine, if the target is a real lane). Which of the two happens should be a rule in the table, and forced routing inside a provider’s catalog is the case where the lane changes under you without failing at all.

# routing.yaml (illustrative shape)
rules:
  - match: {class: latency_bound}
    lane: nearest_healthy
    release: now
    caps: {usd_per_job: 2, concurrent: 8}
  - match: {class: flexible, cache_shape: stable_prefix, slow_tools: false}
    lane: deepseek
    release: {at: next_off_peak_edge, max_wait_hours: from_job}
    caps: {usd_per_job: 1, usd_per_night: 40, concurrent: 12}
  - match: {class: flexible, cache_shape: stable_prefix, slow_tools: true}
    lane: anthropic
    cache_ttl: 1h
    release: now
    caps: {usd_per_job: 6, usd_per_night: 60, concurrent: 4}
  - match: {class: flexible, cache_shape: none}
    lane: batch
    release: enqueue
    caps: {usd_per_batch: 25, in_flight: 1}
on_wait_exceeded: fail_and_page      # never silently run at peak

The on_wait_exceeded line is the policy in one word. A flexible job that cannot make its window is a broken job, and the honest outcome is a page, not a quiet run at double the price.

Step 4: The weekday off-peak AI agent scheduling table, hour by hour in UTC

Here is what the router produces for a weekday. Picture a fleet with nightly research, a few eval suites, doc sweeps with slow test tools, and a PR-review lane that never sleeps.

UTC DeepSeek lane Anthropic lane Batch lane Notes
00:00–01:00 off-peak, last hour before the 01:00 block: release only jobs that finish by 01:00 doc sweeps run, 1-hour cache drain results a long job started here runs into peak; hold it for 10:00
01:00–04:00 peak: hold flexible; latency-bound only keep running; gaps under 5 min or 1-hour cache enqueue new bulk held jobs release at 04:00 if they fit the trough, else at 10:00
04:00–06:00 off-peak trough: release jobs that finish inside 2 h same same a fan-out that needs 3 h waits for 10:00 instead
06:00–10:00 peak: hold flexible same same PR review keeps running here; that is what latency-bound means
10:00–24:00 off-peak, 14 h: nightly research, eval reruns, fan-outs same drain the main flexible window; concurrency caps do the rest
Sat 00:00 onward off-peak for 48 h same same weekly backfills and the largest fan-outs start here

Diagram of the clock router: a job enters with a class; latency-bound jobs skip straight to a provider and run now; flexible jobs go through the window step, which picks the next cheap edge within the job’s max delay, then a provider, then a cap, then run, then a weekly review that feeds back into the classification Job class → window → provider → cap → run → review. Latency-bound jobs skip the window step; nothing skips the cap.

Two details make the timetable work. The 04:00 trough and the 00:00 hour are real money for short jobs and a trap for long ones, so the router releases into them only what fits; the rule is release-if-duration-fits, using the job’s trailing median runtime. And the weekend is the plan: a fan-out that costs $80 on a weekday night costs the same $80 on Saturday, but from Saturday 00:00 UTC the next peak block is 49 hours away, so the weekly heavy jobs are pinned there by default.

Step 5: Keep the caches warm on the lanes that reward it

On the Anthropic lane the clock is the gap between calls, so the scheduler’s job is to keep chained calls dense or to buy the hour. Minimum cacheable prompt on Fable 5.1 is 512 tokens; below that there is nothing to keep warm. Read cache_creation_input_tokens and cache_read_input_tokens from every response: the docs say that when both are zero, the prompt was not cached, which is the signal that a prefix fell under the minimum or that a breakpoint moved.

On the DeepSeek lane the context cache is best-effort and clears after hours to days of idleness, so a flexible job held from 06:00 to 10:00 may pay one miss on its first request after release. That is one 50k-token miss at $0.15 off-peak, about a cent, against a job that would otherwise have run at double price. Hold anyway. The prefix rules that keep turn two onward hitting are in the DeepSeek sibling and do not change with the clock.

The one place the two lanes interact is a job that starts on one and fails over to the other mid-run. The prefix that hit on DeepSeek is a fresh write on Anthropic, and the Anthropic cache that was warm is worthless to DeepSeek. Failover between lanes resets the cache; budget the reset and do not let a job flap between lanes because one of them was slow for a minute.

Step 6: The Friday review of what moved, and what waited too long

The review is one page, generated, and it answers five questions.

Question Metric Healthy Act when
Did flexible work actually run off-peak? share of flexible DeepSeek tokens billed at off-peak ≥ 90% < 75%: the router is releasing into peak, or class labels are wrong
Did anything wait past its max delay? count of wait_exceeded pages 0 any: raise max delay, or reclass the job, never both
Are caches hitting? hit rate per lane, turn 3 onward DeepSeek ≥ 80%; Anthropic reads ≥ 70% of input < 50%: prefix churn or a slow-tool gap; fix the job, not the lane
Did a lane change price under us? lane spend vs trailing-week median, volume-adjusted within ±30% outside: a routing or pricing change; check the provider’s page before touching config
What did a job cost, per lane? USD per job, per class, per lane trending flat or down a class that got dearer on the lane the table assigned it: revisit the row

The fourth row is where cost-anomaly alerts plug in; a drop is as much an anomaly as a spike, and after September 14 a deepseek-v4-pro line suddenly billing at Flash rates was exactly that signal. The fifth row is what makes the routing table a living document: a lane that stops being the cheapest for a class loses the row.

# illustrative weekly rollup from the job ledger (one JSON line per job)
jq -r 'select(.class=="flexible") | [.lane, .window, .usd, (.wait_h > .max_delay_h)] | @tsv' jobs.jsonl \
  | awk '{n[$1" "$2]++; usd[$1" "$2]+=$3; late+=($4=="true")}
         END {for (k in n) printf "%-22s jobs=%d usd=%.2f\n", k, n[k], usd[k]; print "late:", late}'

Keep the review in the same place the fleet’s session evidence lives, so that a job that cost three times its class median can be replayed rather than argued about.

Six ways an off-peak schedule drifts, and the signal for each

The window is written in local time. Someone set the peak blocks as 03:00–06:00 because that is what their laptop showed. Signal: the review’s off-peak share falls under 75% with no config change you remember. Fix: the window file has one tz: UTC line and a test that asserts it.

A holiday is missed, or invented. The router holds jobs on a day that is off-peak in full, or releases into peak on a day it thought was a holiday. Signal: a held queue on a Chinese public holiday, or a peak-billed weekday you expected to be free. Fix: the holiday file carries a source and a checked-on date, because DeepSeek’s pricing page excludes Chinese public holidays without listing them.

A flexible job is secretly latency-bound. It waited fourteen hours and the person who wanted it on Wednesday morning got it Wednesday night. Signal: a complaint, which is the worst signal. Fix: max delay is a required field at job creation, and the person who sets it is the person who waits.

The Anthropic cache goes cold mid-job. A tool call ran eleven minutes; the next model call wrote the whole prefix again. Signal: cache_creation_input_tokens jumps mid-job on a lane using the 5-minute default. Fix: any job whose tools can exceed five minutes is routed with the 1-hour cache, per the table.

A batch never comes back in time. The job was classified as bulk and enqueued, and the deadline was shorter than the provider’s turnaround. Signal: wait_exceeded on a batch lane. Fix: batch is only for max delay of 24 hours or more, and the table says so.

The lane changed price under you. A provider rerouted a model id, a promotion ended, a peak window moved. Signal: the fourth review row, or the anomaly floor. Fix: the pricing pages are the source of truth, checked on a date you record; the routing table changes only after that check.

The operating layer holds the clock

No model ships the router, the calendar, the caps or the review. They belong to the layer that starts, holds, steers and stops agents across every provider and CLI you run, which is the command-center thesis applied to the bill. A model’s price list is a fact about a vendor. Which jobs may wait for the cheap hours is a decision about your fleet, made once, in one file, and inherited by every agent that runs.

That is also the difference between the operating bill and the token bill: the token bill is what the providers charge, and the operating bill is what it costs you to be the one who decides when. This schedule moves the second one from a person’s memory to a config that the overnight merge gates already assume exists.

FAQ: off-peak AI agent scheduling

When is DeepSeek off-peak in UTC?

DeepSeek’s peak hours are 01:00 to 04:00 and 06:00 to 10:00 UTC, Monday through Friday, excluding Chinese public holidays. Every other hour is off-peak at half the peak rate, including the weekday trough from 04:00 to 06:00, all weekend hours, and Chinese public holidays in full, per the API pricing page.

Does Anthropic have off-peak pricing for Claude?

No clock-based discount is published. Claude Fable 5.1 cuts the cache-read price to $0.25 per million tokens, 0.025× base input, and the Batch API halves input and output prices. The saving depends on prefix reuse and on keeping call gaps under the 5-minute cache lifetime, or paying for the 1-hour cache.

How do I decide which agent jobs can run off-peak?

Classify every recurring job as latency-bound or flexible, and require a maximum delay in hours on each. A job is latency-bound only when a named person or pipeline waits on it. Flexible jobs with a stable prompt prefix go to a clock-priced lane off-peak; one-shot bulk goes to a batch lane; everything carries a cap.

Sources