Design a Job Scheduler
Company: DoorDash
Role: Software Engineer
Category: System Design
Difficulty: medium
Interview Round: Onsite
Design a job scheduler. Explain how a submitted job becomes eligible to run, how work reaches an executor, and how the system records what happened when execution succeeds or fails.
This is an open-ended design exercise. The workload, scale, timing guarantees, and execution semantics are unspecified; establish them with the interviewer before choosing the architecture.
### Constraints & Assumptions
- Do not assume that jobs are recurring, have dependencies, or require an exact execution time. Identify which of these features the design must support.
- Separate scheduling a job from running its business logic. State where the scheduler's responsibility ends.
- Any capacity estimate or reliability target you use is a practice assumption, not a supplied requirement.
### Clarifying Questions to Ask
- Are jobs immediate, scheduled for a future time, recurring, or some combination?
- What does a successful submission promise, and what delay between the requested start time and actual execution is acceptable?
- Can a failed job be retried, and can its effects safely happen more than once?
- Do jobs need cancellation, dependencies, priorities, or limits on simultaneous execution?
### Part 1 — Represent and Dispatch Work
Propose a job representation, submission interface, scheduling mechanism, and executor interface. Walk through one job from submission to completion. Explain how the scheduler identifies runnable work and prevents multiple schedulers from claiming it unintentionally.
#### What This Part Should Cover
- A job identity and explicit lifecycle states, with the information needed to determine eligibility.
- A durable record of accepted work and a concrete dispatch path.
- A concurrency mechanism for claiming jobs and the boundary between a scheduled occurrence and an execution attempt.
- A relationship between the chosen data structures and the workload assumptions.
### Part 2 — Recover from Failure and Grow the System
Explain what happens if a scheduler stops after claiming a job, an executor stops during execution, or an acknowledgement is lost. Then identify what must change as the number of scheduled jobs or running jobs grows.
#### What This Part Should Cover
- Recovery of abandoned claims and safe handling of ambiguous completion.
- Retry policy, duplicate effects, and the limits of any execution guarantee.
- Independent scaling of scheduling and execution, with a plan for overloaded workers.
- Signals that distinguish jobs waiting for their due time from jobs that are overdue or repeatedly failing.
```hint
Trace the durable records around each handoff. A process can fail between two operations that look adjacent in a diagram.
```
### What a Strong Answer Covers
A coherent lifecycle matters more than naming a queue or database. The design should explain who owns a job at each step, what persists before a response is sent, and how the next process can recover after a failure. Reliability and scale choices should follow the requirements established during clarification.
### Follow-up Questions
- How would recurring schedules avoid creating the same occurrence twice after a scheduler restart?
- What should cancellation mean when an executor has already started producing effects?
- How would you keep a large backlog from starving jobs with nearer deadlines?
Overview: Design a job scheduler from submission through dispatch, execution, and recovery. Work through durable job state, competing schedulers, retries, duplicate effects, and the scaling choices that follow from the required timing guarantees.
Read the full DoorDash Software Engineer interview experience this question came from