Stop Using Cron: From Single-Node to Distributed Scheduling to Reach >1k Tasks/s

The article explains why traditional Cron‑based scheduling fails under high load, walks through three architectural stages—from database polling to Redis delay queues and finally a full distributed scheduler—showing code examples, design trade‑offs, and performance numbers that enable thousands of tasks per second.

LuTiao Programming
LuTiao Programming
LuTiao Programming
Stop Using Cron: From Single-Node to Distributed Scheduling to Reach >1k Tasks/s

Why a simple Cron expression fails at high scale

When task volume grows from a few hundred per second to tens of thousands per second, a single‑machine scheduler creates thread pile‑up, excessive GC pressure and CPU saturation, leading to chronic crashes.

Core questions for a distributed scheduler

The design must answer three questions:

Which node should execute a given job?

When should the job run?

Should the job run exactly once or allow multiple executions?

Real‑world example: stock‑trading system

Tasks such as timed buys, price‑threshold triggers and periodic account checks require:

high‑precision timing

potentially tens of thousands of executions per second

strong consistency (no duplicate execution)

Architecture evolution

Stage 1 – Database polling

Worker repeatedly queries the database for due jobs.

SELECT * FROM job WHERE execute_time <= NOW();

Java example:

package com.icoderoad.scheduler.worker;
public class JobWorker {
    public void pollAndExecute() {
        // query DB
        // execute job
    }
}

Problems observed:

Very high DB load

Unpredictable latency

Low scan efficiency

Stage 2 – Redis delay queue

Introduce a Redis sorted set (ZSET) to hold delayed jobs, reducing DB pressure. ZADD job_queue 1690000000 "job1" Worker example:

package com.icoderoad.scheduler.queue;
public class DelayQueueWorker {
    public void consume() {
        // fetch expired tasks from Redis
    }
}

Advantages:

DB load is lowered

Throughput improves

Remaining issues:

Single‑point Redis bottleneck

Timing precision limited by Redis polling interval

Stage 3 – Full distributed scheduler

Decouple a scheduling centre from execution nodes.

/usr/local/scheduler/
├── scheduler-core/
├── scheduler-worker/
├── scheduler-api/
└── scheduler-common/

Package layout:

com.icoderoad.scheduler.core
com.icoderoad.scheduler.worker
com.icoderoad.scheduler.api

Key design components

1. Task sharding

package com.icoderoad.scheduler.core;
public class ShardingStrategy {
    public int route(String jobId, int workerCount) {
        return jobId.hashCode() % workerCount;
    }
}

2. Idempotent execution

package com.icoderoad.scheduler.worker;
public class IdempotentExecutor {
    public void execute(String jobId) {
        // check if already executed
    }
}

3. High‑throughput optimizations

Batch fetch of pending jobs

Asynchronous execution

Thread‑pool isolation

ExecutorService pool = Executors.newFixedThreadPool(32);

4. Timing wheel

A timing wheel provides O(1) insertion and execution, reducing latency compared with polling.

O(1) insert

O(1) execute

Performance comparison (100 → 10 000+ tasks/s)

Cron (single‑node) – low throughput, high latency, no scalability.

DB polling – medium throughput, high latency, poor scalability.

Redis delay queue – high throughput, medium latency, moderate scalability.

Distributed scheduler – extremely high throughput, low latency, strong scalability.

Hidden killers in production

Massive short‑lived objects → frequent GC.

Queue buildup → memory explosion.

Uncontrolled thread growth → CPU saturation.

Optimization suggestions

Object reuse (e.g., Disruptor pattern).

Rate limiting combined with back‑pressure.

Separate scheduling logic from task execution.

Fundamental scheduling principle

Execute the right task on the right machine at the right time, exactly once.

The three essential questions are When, Who, and Once.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaDistributed SchedulingRedisSchedulerCronhigh-throughput
LuTiao Programming
Written by

LuTiao Programming

LuTiao Programming is a friendly community offering free programming lessons. We inspire learners to explore new ideas and technologies and quickly acquire job-ready skills.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.