Skip to content

Repository files navigation

de-scheduling-evolution

One problem. Six tools. The real architectural reason behind every scheduling decision.


What Is This?

A data engineer needs to collect data. The collection must be automated, periodic, and reliable.

Which tool do they use?

The answer depends entirely on context — company size, team maturity, infrastructure bounds, and cost profiles. This project makes those contexts concrete.

The same ingestion pipeline is implemented six times across six different scheduling layers. Each implementation starts exactly where the previous tool hits its architectural limit. Every decision is explained. Every trade-off is measurable.


The Ingestion Contract

Every chapter solves the exact same data transfer problem:

Fetch weather data from OpenWeatherMap API

Validate constraints via Pydantic v2

Commit via SQLAlchemy 2.0 ORM (Programmatic Alembic Migrations)

Upsert into PostgreSQL (Storing mapped fields + Raw JSONB buffer layer)

Automate & Schedule

What changes across chapters: only the automation and scheduling layer.


The Evolution Matrix

#ToolLevelArchitectural IdentityWhy We Left
01CronJunior DE / Single NodeBuilt-in OS automation, zero infrastructure overhead. Container acts as PID 1 boundary via exec cron -f.OS-level shell isolation, zero native observability dashboards, task overlapping under volume (no backpressure control).
02APSchedulerIn-app ThreadingEmbedded Python scheduling threads, process-level lifecycle control, in-app max_instances and coalesce execution guards.Single process constraint, horizontal scaling blind spot causing multi-instance task collisions, and state volatility (MemoryJobStore loss).
03Celery BeatDistributed WorkersProducer-broker-consumer split, low-latency asynchronous memory queueing via Redis, stateless horizontally elastic worker pools.Pure task execution engine lacking task lineage tracking (No native DAG structures), structural visual blind spots across complex dependencies, and lack of central monitoring UI.
04AirflowEnterprise OrchestrationProgrammatic workflow state management, metadata ledger tracking, Dual Python Runtime isolation (Control Plane vs. Data Plane).Heavy batch-oriented framework constrained strictly by pull-based scheduling semantics and static filesystem DAG parsing loops, rendering it inefficient for event-driven, real-time serverless ingestion topologies.
05PrefectModern OrchestrationCode-first dynamic tasks, low-boilerplate modern deployment hooks.Pending execution analysis...
06Airflow on K8sCloud-Native PeakContainer-native task-isolation pods. True enterprise production standard.The Architectural Ceiling

Design Principles

  • Control Variable Correctness: The data source (API JSON layout) and target destination (PostgreSQL 16 Engine) never change. Only the orchestration boundary shifts. This isolates noise and creates a pure comparison framework.
  • Every Tool Earns Its Place: No tool is introduced as a default choice. Each chapter opens directly by breaking or throttling the previous layer's capacity.
  • Production Standards from Day One: Even the simplest Cron implementation enforces strict Pydantic parsing, Tenacity exponential backoff retries, unified Structlog structured JSON logs, and programmatic Alembic database state updates on container startup.
  • Zero Cost Isolation: Every tool runs completely locally or using free, self-hosted container images. Paid alternatives are technically evaluated but never implemented.

Technical Foundation: The Shared Layer

All standalone containers copy and reference the identical business layer directly to prevent code drift between chapters:

shared/
├── alembic/ → Schema versioning scripts tracking engine states (e.g., unique_city_timestamp)
├── alembic.ini → Local and container configuration mapper
├── extractor.py → Low-level HTTP requests using Tenacity and structured logging
├── loader.py → SQLAlchemy ORM declaration, connection factory, and PostgreSQL transactional upserts
└── models.py → Strict Pydantic parsing schemas isolating raw buffers and parsed items

Key Architectural Decisions

  • Idempotency Contract: Regulated via a database-level UniqueConstraint('city', 'timestamp'). Duplicate runs or backward backfills overwrite mutations safely without state corruption.
  • The Raw JSON Buffer Layer: To survive upstream API schema evolution, the pipeline saves the complete, raw API response inside a JSONB column during the upsert phase. This allows full historical reprocessing if downstream schema fields change retrospectively.
  • Platform Isolation: Each chapter directory operates independently, carrying its own explicit requirements.txt, Dockerfile, and local docker-compose.yaml linked externally to our shared infrastructure network boundary.

Repository Directory Blueprint

de-scheduling-evolution/
├── README.md
├── docker-compose.infra.yml ← Common Infrastructure: PostgreSQL 16 + Redis 7 + pgAdmin
├── shared/ ← The immutable core layer copied during image compilation
│ ├── alembic/
│ ├── extractor.py
│ ├── loader.py
│ └── models.py
├── 01-cron/ ← Verified & Locked
├── 02-apscheduler/ ← Verified & Locked
├── 03-celery-beat/ ← Verified & Locked
├── 04-airflow/ ← Verified & Locked
├── 05-prefect/ ← CURRENT STEP
└── 06-airflow-on-kubernetes/

Common Infrastructure Isolation

To guarantee resource optimization, the repository isolates data storage blocks from active compute layers. Run the primary infra layout once from the root directory:

docker-compose -f docker-compose.infra.yml up -d

Who Is This For?

  • A Junior Data Engineer who needs to understand why enterprise tools exist, rather than just learning syntax.
  • A Mid-level DE tasked with choosing a scheduling architecture for a greenfield project.
  • A Tech Lead who needs a clear, reference-grade comparison to explain architectural trade-offs to stakeholders.

What This Is Not

  • A basic tutorial on how to install tools in isolation.
  • A benchmark tracking raw performance numbers.
  • A vendor-driven cloud platform deployment manual.

Part of the de- series — reference-quality, open-source data engineering blueprints.Maintenaned by Oğuz Kaan Mavice

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages