Features β’ Quick Start β’ Architecture β’ Documentation β’ API
ScheduleZero is a resource-conscious, distributed task scheduling system built entirely in Python. Perfect for scenarios where heavyweight solutions like Celery are overkillβespecially on memory-constrained systems like small VMs or edge devices.
Why ScheduleZero?
- πͺΆ Lightweight: No message broker required (RabbitMQ/Redis)
- π Fast: Built on modern async Python (asyncio, Tornado)
- π Distributed: Scale horizontally with worker handlers
- πΎ Persistent: SQLite-based job storage
- π¨ Beautiful UI: Modern web interface for monitoring
- π Brokerless: Direct RPC communication via zerorpc
- π‘οΈ Reliable: Built-in retry logic with exponential backoff
- π Flexible Scheduling: Date, interval, and cron triggers via APScheduler 4.x
- π‘ Remote Execution: Distribute jobs across multiple handler processes
- π Auto-Discovery: Handlers self-register with the central server
- πͺ Resilient: Automatic retries with exponential backoff + jitter
- π REST API: Full HTTP API for programmatic control
- ποΈ Web Dashboard: Real-time monitoring and job management
- πΎ Persistent Storage: Jobs survive restarts via SQLite
- π Thread-Safe: Concurrent job execution with proper locking
- Dynamic Handler Registration: Add/remove workers on-the-fly
- Method-Level Routing: Route jobs to specific handler methods
- Status Tracking: Monitor handler availability and job execution
- Configuration Management: YAML-based instance configuration
- Graceful Shutdown: Clean termination of all components
- Exponential Backoff: Smart retry logic for failed jobs
# Using Poetry (recommended)
poetry install
# Or using pip
pip install -r requirements.txtCreate config.yaml in your project root:
instance_name: "My ScheduleZero Instance"
description: "Production task scheduler"
admin_contact: "[email protected]"
version: "1.0.0"Terminal 1 - Start the Server:
poetry run schedule-zero-server
# Server starts on http://127.0.0.1:8888Terminal 2 - Start a Handler:
poetry run schedule-zero-handler
# Handler auto-registers and starts listeningTerminal 3 - Test the System:
poetry run python test_schedule.py
# Runs end-to-end testsOpen your browser to http://localhost:8888
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ScheduleZero Central Server β
β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β Tornado β β APScheduler β β zerorpc β β
β β Web Server ββββ 4.x Async ββββRegistration β β
β β :8888 β β Scheduler β βServer :4242 β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β β β β
β β β β β
β ββββββΌββββββ ββββββΌβββββββ ββββββΌβββββββ β
β β HTTP β β SQLite β β Handler β β
β β API β β JobStore β β Registry β β
β ββββββββββββ βββββββββββββ βββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
β zerorpc (tcp)
β
βββββββββββββββββββ΄ββββββββββββββββββ
β β
βΌ βΌ
βββββββββββββββββ βββββββββββββββββ
β Handler 1 β β Handler 2 β
β :4243 β β :4244 β
β β β β
β β’ do_work() β β β’ process() β
β β’ backup() β β β’ analyze() β
βββββββββββββββββ βββββββββββββββββ
| Component | Technology | Purpose |
|---|---|---|
| Web Framework | Tornado 6.5+ | Async web server & HTTP API |
| Scheduler | APScheduler 4.x | Job scheduling & execution |
| RPC Layer | zerorpc | Lightweight, brokerless communication |
| Persistence | SQLite + SQLAlchemy | Job storage & retrieval |
| Transport | ZeroMQ | High-performance messaging |
| Serialization | MessagePack | Efficient data encoding |
| Configuration | PyYAML | Human-readable config files |
- Native
asynciosupport for APScheduler 4.x integration - Efficient async I/O for handling many connections
- Built-in web serverβno external dependencies
- Modern async-first design
- Flexible trigger types (date, interval, cron)
- Persistent job storage with datastore abstraction
- No message broker required (unlike Celery)
- Minimal memory footprint
- Built-in heartbeat and timeout handling
- Automatic serialization with MessagePack
- Zero configuration database
- Low memory usage (< 1MB typical)
- Perfect for embedded/edge deployments
- ACID transactions for reliability
src/schedule_zero/
βββ app_configuration.py # App config & environment vars
βββ handler_registry.py # Handler registration & clients
βββ job_executor.py # Job execution with retries
βββ zerorpc_registration_server.py # RPC server for registration
βββ tornado_app_server.py # Main server orchestration
βββ server.py # CLI entry point
βββ api/
β βββ tornado_base_handlers.py # Base Tornado handlers
β βββ handler_list_api.py # Handler endpoints
β βββ job_scheduling_api.py # Job scheduling endpoints
β βββ config_api.py # Configuration endpoint
βββ handlers/
βββ base.py # Abstract handler base class
βββ example.py # Example handler implementation
Documentation Files:
REFACTORING_SUMMARY.md- Detailed refactoring notesTESTING_STATUS.md- Current testing status & known issues
GET /api/handlersResponse:
{
"handlers": [
{
"id": "handler_12345",
"address": "tcp://127.0.0.1:4243",
"methods": ["do_work", "backup", "process"],
"status": "Connected"
}
]
}POST /api/schedule
Content-Type: application/json
{
"handler_id": "handler_12345",
"method_name": "do_work",
"job_params": {
"input_file": "/data/file.txt",
"output_dir": "/results/"
},
"trigger_config": {
"type": "interval",
"hours": 1
}
}Response:
{
"status": "success",
"schedule_id": "job_67890"
}POST /api/run_now
Content-Type: application/json
{
"handler_id": "handler_12345",
"method_name": "do_work",
"job_params": {
"message": "Hello World"
}
}GET /api/schedulesResponse:
{
"schedules": [
{
"id": "job_67890",
"next_fire_time": "2025-10-27T15:30:00Z",
"trigger": "interval[1:00:00]",
"args": ["handler_12345", "do_work", {...}]
}
],
"count": 1
}GET /api/configGET /api/health| Variable | Default | Description |
|---|---|---|
SCHEDULEZERO_TORNADO_ADDR |
127.0.0.1 |
Tornado bind address |
SCHEDULEZERO_TORNADO_PORT |
8888 |
Tornado HTTP port |
SCHEDULEZERO_ZRPC_HOST |
127.0.0.1 |
zerorpc server host |
SCHEDULEZERO_ZRPC_PORT |
4242 |
zerorpc server port |
SCHEDULEZERO_DATABASE_URL |
sqlite:///schedulezero_jobs.db |
Database connection |
SCHEDULEZERO_CONFIG_PATH |
config.yaml |
Config file path |
SCHEDULEZERO_REGISTRY_PATH |
handler_registry.yaml |
Registry file path |
{
"type": "date",
"run_date": "2025-10-27T15:30:00"
}{
"type": "interval",
"hours": 1,
"minutes": 30
}{
"type": "cron",
"hour": "*/2",
"minute": "0"
}# Start server and handler in separate terminals, then:
poetry run python test_schedule.py
# Expected output:
# β Handlers listed successfully
# β Job executed immediately
# β Job scheduled for future execution- Authentication & authorization
- Job execution history & logs
- Advanced UI with charts & graphs
- Docker containerization
- Handler health monitoring
- Job dependency management
- Multi-instance clustering
- Prometheus metrics export
- WebSocket support for real-time updates
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
Built with these excellent libraries:
- Tornado - Async web framework
- APScheduler - Job scheduling
- zerorpc - RPC framework
- ZeroMQ - Messaging library
- SQLAlchemy - Database toolkit
Made with β€οΈ and Python