A look at how ClickPy handles over 2 trillion Python package downloads, from ingestion redesign to fixing historical data at scale.
Overview
This article details how ClickPy, a free Python download statistics platform powered by ClickHouse, scaled to over 2 trillion rows by replacing its legacy cron-based ingestion pipeline with ClickPipes, a managed ingestion service. The post covers the staged hot-swap migration strategy, the discovery of historical data gaps, and the process for correcting past data without rebuilding the entire dataset or interrupting ongoing operations.
What You'll Learn
How to perform a zero-downtime hot-swap of a data ingestion pipeline at trillion-row scale
How to use a staging database and parallel pipeline validation to safely migrate ingestion systems
How to fix historical data gaps in a column-oriented database without rebuilding the full dataset
Why replacing custom cron-based ingestion scripts with managed ingestion services reduces operational burden
When to use materialized views with Null engine tables as a transformation layer in ClickHouse
Prerequisites & Requirements
- Understanding of column-oriented databases and analytical workloads
- Familiarity with ClickHouse concepts including materialized views, table engines, and data ingestion
- Basic understanding of data pipelines and ETL/ELT patterns
- Familiarity with Google BigQuery and Google Cloud Storage (GCS)(optional)
- Experience operating large-scale data systems with high availability requirements(optional)
Key Questions Answered
How do you replace a data ingestion pipeline at trillion-row scale without downtime?
How does ClickPy handle 2 trillion rows of Python download statistics?
How do you fix historical data gaps in ClickHouse without rebuilding the entire dataset?
Why replace a custom cron-based ingestion script with ClickPipes?
What is the Null engine pattern in ClickHouse for data transformation?
How do you handle materialized views during historical data backfills in ClickHouse?
How do you avoid re-ingesting a full historical dataset when migrating to ClickPipes?
Key Statistics & Figures
Technologies & Tools
Some links below are affiliate links. We may earn a commission if you make a purchase.
Key Actionable Insights
1Use a parallel staging environment when migrating data pipelines at scale. Clone table schemas and materialized views into an isolated database, run both old and new pipelines simultaneously, and compare outputs before switching over. This approach ensures zero risk to production data during the transition.This pattern is especially critical when dealing with datasets too large to re-ingest from scratch, where corruption or data loss during migration would be catastrophic.
2Leverage the Null engine with materialized views as a transformation layer to decouple ingestion from data transformation. By having ClickPipes write to a Null engine table and using a materialized view to transform and route data to the final table, you get a clean separation of concerns that is easier to evolve and debug.This pattern centralizes transformation logic inside ClickHouse rather than in external scripts, making it version-controlled and inspectable as part of the database schema.
3Distinguish between daily and non-daily aggregation tables when performing historical data corrections. Daily-aggregated tables allow targeted deletes and re-ingestion via materialized views, while non-daily aggregations require dropping and recreating materialized views to prevent duplicate data during backfills.Failing to account for this distinction can lead to silently duplicated data in aggregation tables, producing incorrect analytics results that are difficult to detect.
4Regularly validate source data against your analytical database to catch ingestion gaps early. At trillion-row scale, missing data is easy to overlook because queries still work and dashboards still render, but results are quietly incorrect. Implement daily row count comparisons between source and destination systems.The ClickPy team only discovered historical discrepancies when they compared BigQuery and ClickHouse data during the pipeline migration, highlighting the need for ongoing data quality monitoring.
5Replace custom cron-based ingestion scripts with managed ingestion services to reduce operational overhead. Hand-rolled retry logic, failure handling, and progress tracking are error-prone and require ongoing maintenance, whereas managed services provide these capabilities out of the box.The original ClickPy pipeline required significant scripting because managed ingestion (ClickPipes) didn't exist yet. Once available, the migration eliminated several categories of operational risk.
6When migrating to a continuous ingestion service that doesn't support arbitrary start points, redirect new source data to a fresh storage location. Configure the new pipeline to read from this fresh bucket, avoiding the need to reprocess historical data while ensuring no gap in new data ingestion.This approach was used for ClickPipes, which tracks processed files but cannot start from a specific timestamp, making a fresh GCS bucket the pragmatic solution.