This skill should be used when the user designs a "task scheduler", "job scheduler", "job queue", "cron at scale", "distributed cron", "delayed / scheduled / recurring tasks", a "worker pool", reaches for "Celery / Sidekiq / Airflow", or wrestles with "task leasing", visibility timeouts, job priorities, fairness, or duplicate task execution. Use it whenever work must run later, on a schedule, or be reliably leased to a pool of workers, even if the user doesn't say "scheduler". (For plain queue transport and delivery guarantees, that is `messaging-streaming`.)
npx skills add https://github.com/proyecto26/system-design-skills --skill task-scheduling
Decide *when* work runs and *which worker* runs it: fire jobs on a schedule
(cron/delayed/recurring), hand each job to exactly one worker via a lease, and
make sure it completes once despite crashes and retries. This sits *on top of*
messaging-streaming queues — the queue is the transport; this skill adds the
scheduling, leasing, priorities, and task-level idempotency. Getting it wrong
shows up as jobs that never run, run twice (double charge, double email), or
pile up until a worker fleet falls permanently behind.
Work must run later (send a reminder in 24h), on a schedule (nightly
rollups, hourly cron), or repeatedly (poll every 5 min); a slow operation is
already off the request path (→ messaging-streaming) and now needs reliable
allocation to a pool of workers; jobs need priorities (paid before free) or
fairness (no single tenant starves others); or a job must complete **exactly
once** even though the worker holding it can crash mid-flight.
The caller needs the result inline — that's a synchronous call, not a scheduled
job. A single fire-and-forget async step with no schedule, priority, or
exactly-once need — a plain queue + idempotent consumer (messaging-streaming)
is simpler; don't add a scheduler on top. One periodic job on one box —
OS cron is fine until you have multiple schedulers or need history and
retries. A long-running multi-step saga with rollback — reach for a durable
workflow engine instead of hand-rolling state across jobs. Don't stand up
Airflow/Celery "because we'll have batch jobs eventually" (YAGNI): it's a
stateful control plane to operate and monitor.
recurring (every N), or event-driven (a queue message arrives)? This decides
whether a scheduler is even in scope.
or harmless (idempotent recompute)? Drives the leasing + dedup design.
its time, or is "within a few minutes" fine? Tight timing is more expensive.
job class be prevented from starving the rest? (→ back-of-the-envelope for
arrival vs. service rate.)
lease length and whether long jobs need heartbeats.
(The key contract is owned by api-design.)
Scheduling trigger
when* one node, a handful of jobs, no HA requirement.
jobs into a queue; followers stand by. *Use when* the schedule must survive a
node loss and must not double-fire.
until due (delivery delay, sorted-set scoring, or a timer wheel). *Use when*
per-job delays vary and you don't want a cron tick.
history (Airflow-style). *Use when* batch pipelines have dependencies and you
need a run history and reruns.
Worker allocation
visibility timeout, and ack/delete on success. *Use when* you want
back-pressure for free and elastic, self-balancing workers. The default.
*Use when* affinity/locality matters (a job must run where its data is).
Priority & fairness
some classes must run first.
queues. *Use when* one tenant's burst must not starve others.
| Option | What it solves | What it worsens | Change it when |
|---|---|---|---|
| OS cron / single scheduler | Trivial; zero infra | SPOF — node dies, schedule stops; no retry/history | You need HA or missed-run recovery → distributed scheduler |
| Distributed scheduler (HA cron) | Survives node loss; no double-fire (leader-elected) | Needs leader election (→ consistency-coordination); more moving parts | One box and one job is enough → OS cron |
| Delay queue / timer | Per-job delays without a cron tick; precise-ish timing | Far-future jobs sit in the queue; timer accuracy bounded by poll interval | Delays are uniform/periodic → cron; dependencies exist → DAG |
| Workflow DAG (Airflow-style) | Dependencies, backfill, run history, reruns | Heavy control plane; scheduler latency; overkill for single jobs | Jobs are independent one-shots → plain queue + scheduler |
| Pull (worker leasing) | Self-balancing, elastic, natural back-pressure | At-least-once: lease expiry on a slow job re-runs it (need idempotency) | A job must run on a specific node (data locality) → push |
| Push (dispatcher) | Affinity/locality; central control | Dispatcher is a bottleneck/SPOF; must track worker health | No locality need → pull is simpler |
| Priority queues | Important work runs first | Low-priority starvation under sustained load | Fairness across tenants matters → weighted/fair |
| Weighted / fair scheduling | No tenant starves another | More complex; per-tenant accounting | Only one workload class exists → single queue |
A scheduler can quietly fall behind, or it can *amplify* an outage by
re-dispatching work a struggling fleet can't finish.
and "scheduled for 09:00" runs at 09:40. End-to-end delay climbs while CPU
looks fine. *Mitigate:* alarm on oldest-due-job age and queue depth, not
just rate; scale workers; shed or defer low-priority jobs.
visibility timeout, the lease expires, the queue redelivers it to a second
worker, and now two workers run it — wasting capacity and, without idempotency,
double-applying side effects. *Mitigate:* set the timeout above p99 job
duration, heartbeat to extend the lease on long jobs, and make tasks
idempotent/deduped.
and re-loading a sick downstream. *Mitigate:* cap retries with backoff+jitter,
then route to a dead-letter queue (retries/backoff/DLQ are owned by
resilience-failure).
top of the hour fire at once and stampede a downstream. *Mitigate:* jitter the
schedule, spread triggers, or rate-limit dispatch.
double-enqueue every recurring job. *Mitigate:* a single leader via leader
election + fencing (→ consistency-coordination); idempotent enqueue keyed by
(job, scheduled_time).
everyone else. *Mitigate:* fair/weighted scheduling and per-tenant concurrency
caps.
Monitor: oldest-due-job age (the best lateness signal), queue depth per
priority, lease-expiry / redelivery rate, retry and DLQ rate, worker utilization,
and per-tenant share.
latency budget, priority/fairness, and job duration (see *Clarify first*). If
the work is a single async step with no schedule or priority, stop — a plain
queue + idempotent consumer (messaging-streaming) is enough.
scheduler → delay queue → DAG, cheapest that fits), an allocation model (pull
leasing is the default; push only for locality), and a priority/fairness model
only if more than one class exists.
backoff before the DLQ, the dedup/idempotency key per task, the lease
heartbeat interval for long jobs, and per-tenant concurrency limits.
tasks, tick stampede, scheduler split-brain, and starvation. Confirm a
mitigation exists for each one the workload can trigger.
target concurrency (Little's law); confirm sustained throughput drains peak
arrival, and that far-future delayed jobs fit storage (→ *Numbers that matter*).
if the user named a cloud (see *Choosing a provider*).
Change it when…` table with one row per choice you made here (e.g. the
option, its store, its failure policy); the last column is a concrete trigger
(a number or observable signal). Then name what breaks first.
Do
Don't
Size the worker pool with Little's law: in-flight jobs = arrival rate × average
job duration, so workers ≈ peak arrival × avg seconds-per-job / per-worker
concurrency. Sustained drain must exceed peak arrival or the backlog never
clears. Set the visibility timeout above the p99 job duration (a too-short
timeout is the #1 cause of duplicate runs); set far-future delay storage =
delayed-job rate × max delay × job size. Don't restate the latency/QPS tables —
pull the rates and durations from back-of-the-envelope.
A scheduled task is a contract. Define it, not "a job":
task_id / idempotency key (dedup on retry — keycontract owned by api-design), task_type/version, payload, priority,
scheduled_for (run-not-before), attempt, and a trace_id.
dedup_key = (job_name, scheduled_time) so a double-enqueue is a no-op.
visibility_timeout; it must ack/delete on success or heartbeat to extend.
Lease expiry → automatic redelivery. Failure after the retry cap → DLQ with
attempt count and last error.
Default to the generic recipe above. If the user names a cloud, read
references/providers/<provider>.md for the managed-service mapping,
quotas/limits, and provider-specific trade-offs. If no file exists for that
provider, the generic recipe is the answer.
To visualize the scheduler → queue → leased workers path, or the lease-expiry
redelivery loop, use the in-plugin architecture-diagram skill. Quick inline
sketch: [scheduler] → [delay/priority queue] → workers (lease) ─expire→ requeue ─fail×N→ [DLQ];
main path solid, the expiry/DLQ branches dashed.
messaging-streaming — *depends on* it: queues are the transport this skillschedules onto and leases from; it owns delivery guarantees, ordering, and DLQs
and this skill does not reimplement them.
resilience-failure — *pairs with* it for the retry policy: backoff, jitter,and DLQ-as-containment are tuned there; this skill names them.
api-design — *depends on* its idempotency-key contract, the mechanism thatmakes a re-run after lease expiry safe.
consistency-coordination — *depends on* it for leader election (and fencing)so only one scheduler is active and recurring jobs don't double-fire.
back-of-the-envelope — *feeds into* sizing: arrival rate and job duration setthe worker count and backlog drain.
system-design — *feeds into* the orchestrator's reasoning loop; it routes herewhen work must run later, on a schedule, or be reliably allocated to workers.
references/deep-dive.md — leasing/visibility-timeout mechanics andheartbeats, distributed-cron + leader election, delay-queue implementations
(sorted set, timer wheel), priority/fairness algorithms, exactly-once-effect via
dedup, and Celery/Sidekiq/Airflow internals. Read when designing the scheduler in detail.
references/providers/{generic,aws,azure,gcp,temporal}.md — servicemappings, decision-changing limits, and pitfalls per environment.
Interactive daily standup/meeting update generator. Use when user says 'daily', 'standup', 'scrum update', 'status update', 'what did I do yesterday', 'prepare for meeting', 'morning update', or 'team sync'. Pulls activity from GitHub, Jira, and Claude Code session history. Conducts 4-question interview (yesterday, today, blockers, discussion topics) and generates formatted Markdown update.
Start your day with a prioritized sales briefing. Works standalone when you tell me your meetings and priorities, supercharged when you connect your calendar, CRM, and email. Trigger with "morning briefing", "daily brief", "what's on my plate today", "prep my day", or "start my day".
Full ICP-to-leads pipeline. Describe your ideal customer in plain English and get a ranked table of enriched decision-maker leads with emails and phone numbers.
Analyze meeting notes to find action items and create Jira tasks for assigned work. When an agent needs to: (1) Create Jira tasks or tickets from meeting notes, (2) Extract or find action items from notes or Confluence pages, (3) Parse meeting notes for assigned tasks, or (4) Analyze notes and generate tasks for team members. Identifies assignees, looks up account IDs, and creates tasks with proper context.
When the user wants to optimize post-signup onboarding, user activation, first-run experience, or time-to-value. Also use when the user mentions "onboarding flow," "activation rate," "user activation," "first-run experience," "empty states," "onboarding checklist," "aha moment," or "new user experience." For signup/registration optimization, see signup-flow-cro. For ongoing email sequences, see email-sequence.
Prepare for tomorrow''s meetings and tasks. Pulls calendar from Outlook via WorkIQ, cross-references open tasks and workspace context, classifies meetings, detects conflicts and day-fit issues, finds learning and deep-work slots, and generates a structured HTML prep file with productivity recommendations.
Design meeting rhythms, metric reporting, quarterly planning, and decision-making velocity for scaling companies. Use when decisions are slow, planning is broken, the company is growing but alignment is worse, or leadership meetings consume all time without producing decisions.
Add Google Calendar as an MCP tool (list calendars, list/search/create events, free/busy queries) using OneCLI-managed OAuth. Multi-calendar and multi-account supported. Mirrors /add-gmail-tool's stub pattern — no raw credentials ever reach the container; OneCLI injects real tokens at request time.
Take proyecto26/task-scheduling from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.