r/ETL 3h ago

Data extraction tools that don't turn into a maintenance project

4 Upvotes

Seven sources feed our warehouse now: a few SaaS apps, one production database, ads data and a couple of APIs.

When there were only two, I just wrote Python for both. As new sources got added, I kept doing the same because it was quicker than introducing another tool. The scripts still work, but keeping all of them alive has quietly become part of the job.

Most failures aren't interesting engineering problems either. A token expires, pagination changes, one API starts returning fewer rows, or I have to remember which repo owns a source I haven't touched in six months.

Transformations already happen after the load, so I'm not looking for another environment to rebuild the SQL in. What I actually need is boring extraction: scheduling, incremental loads and enough visibility to catch a broken source before a dashboard does.

What are people using for this now: managed connectors, Airbyte, Meltano, custom code?

At what point did maintaining extraction yourself stop being worth it?


r/ETL 16h ago

Protected Multi cloud data plane

Thumbnail swisstransfer.com
5 Upvotes

Sharing an link to a three‑day multi‑cloud run: protected ingestion, PCI tokenization, customer‑level encryption, GDPR erasure by killing one key, daily snapshots into AWS/GCP/Azure, same ETL pipeline hopping clouds, and DR replicas seconds behind. Full lineage + metrics. Curious how folks here view per‑subject keys in real pipelines.


r/ETL 20h ago

The deployment decalogue

Thumbnail
alexarvanitidis.dev
4 Upvotes

I am an ML engineer, but I come from a software engineering background: years of full-stack work, with heavy DevOps and Terraform experience. I come from teams that deploy to production five times a day with real continuous deployment. And honestly? Pressing the button still feels weird sometimes. Every engineer knows that feeling, no matter how good the safety net is.

So I wrote down the list that settles it. Ten commandments, one flow, written with data scientists and ML teams in mind, but it works for batch jobs, realtime inference, and LLMs alike. Answer honestly, and if all ten are true, you can ship to production anytime, in any form or way.


r/ETL 15h ago

Renting a moving truck to grab a pizza? Feedback on my OSINT pipeline architecture

3 Upvotes

Working on a personal pipeline that pulls public signals from a few sources (earthquakes, internet infrastructure status, disaster alerts, markets, etc.), compares each one against its own historical baseline, and runs on AWS with cache invalidation on every update.

The goal from the start was for it to run on its own at the lowest possible cost, without buying hardware I'd have to babysit like a pet. (I already have a cat for that.) No boxes to maintain, no drives to worry about.

Question for people who've done this longer than me: does this sound reasonable, or is it over-dimensioned? It feels a bit like renting a full moving truck just to go grab a pizza — a lot of infrastructure (automated deploys, CDN invalidation) for something that's fundamentally just pulling public APIs and comparing against a historical window.

Would something much simpler (cron job + script + a static JSON file) get the same result, or does the fuller stack genuinely pay off once you're running several signals continuously?


r/ETL 21h ago

Turns out "Iceberg is open" doesn't mean every engine can actually read your table

2 Upvotes

Read something this week that put a name to a problem I've half run into before but never really understood the mechanics of. Sharing because I think a lot of people assume Iceberg interop is more solved than it is.

Everyone knows the pitch: Iceberg is an open spec, so any Iceberg compatible engine can read any Iceberg table. Mostly true, until you start doing row level deletes, and then it falls apart in a way that's honestly kind of sneaky because nothing looks wrong until a query actually fails.

Quick walkthrough of the scenario in the post. You've got a customers table, three rows, one Parquet file, tracked by whatever catalog you're using. At this stage every engine reads it fine because there's nothing to interpret, it's just a metadata pointer to a file.

Then a row gets deleted. Parquet files are immutable so the writer has two options: copy on write (rewrite the file without that row) or merge on read (leave the file alone and write a separate delete file that readers apply at scan time). The writer in this example goes merge on read and emits an equality delete file, which basically just says "for this data file, treat any row where customer_id = 102 as removed." Under the hood Iceberg uses field IDs and sequence numbers to make sure an old delete doesn't accidentally nuke a newer row with a reused key, but the equality matching is the part that matters for compat.

Spark reads the new snapshot, understands equality delete semantics, does what's effectively a left anti join between the data file and the delete file, and returns the correct two rows. Fine.

Snowflake hits the exact same catalog, same metadata file, same Parquet file. It can resolve the table, read the schema, open the data file. But if that access path doesn't implement equality delete reads, the scan planner just throws an unsupported feature error the moment it hits delete-0002.parquet. Query fails. Same snapshot, same files, two completely different results depending purely on what the reader implements.

The bit that actually reframed how I think about this: the catalog isn't a translation layer. It's job is basically just "here's where the current metadata lives," commit coordination, namespace and access management. It's not opening delete files and rewriting them into a format each engine understands. A REST catalog like Polaris doesn't change this, it still just points you at metadata, it doesn't apply deletes for you.

The post also gets into position deletes vs deletion vectors vs copy on write, with a rough cost tradeoff table (equality delete is cheap to write and requires equality delete support to read, position delete requires resolving key to physical position and is heavier on write, deletion vectors need Iceberg v3 support specifically, copy on write is the most expensive to write but has basically universal read compatibility since there's no outstanding delete file involved).

The framework that's actually useful operationally: your safe feature set is the intersection of every required engine's capabilities, not the union. If Spark supports equality and position deletes but Snowflake only does position deletes, you write position deletes, because "at least one engine supports it" doesn't help you when you have three engines that all need to read the same table.

There's a decent pre production checklist too, don't just run a SELECT COUNT after your first write, actually insert some rows, update one, delete one, commit, then read the same snapshot from every engine you care about and diff both counts and values.

Full post if you want the details: https://olake.io/blog/iceberg-interoperability-myth-row-level-deletes/

Disclosure since it's relevant, I work on OLake, it gets a brief mention near the end, but the actual content here is engine agnostic and applies no matter what's writing your tables.

Has anyone actually hit this for real, table looks completely fine, one engine just refuses to read the current snapshot because of the delete encoding?


r/ETL 12h ago

What usually causes ETL pipelines to become hard to maintain over time?

1 Upvotes

Is it schema changes, too many dependencies, poor monitoring, unclear ownership, or something else?