Skip to main content
Data Lake Anti-Patterns

When Your Data Lake's Schema-on-Read Becomes Schema-on-Despair

You've heard the pitch. Data lakes let you dump everything—raw logs, clickstreams, sensor readings—without deciding on a schema upfront. Schema-on-read, they call it. Query-time interpretation. Sounds liberating. But in practice, that freedom often curdles into a mess of undocumented fields, brittle parsing logic, and angry emails from analysts who can't find the data they need. I've seen teams burn months trying to untangle a lake that turned into a swamp. This article is about when schema-on-read becomes schema-on-despair—and how to avoid the trap. Where Schema-on-Read Shows Up in Real Work IoT Sensor Data Ingestion Picture a manufacturing floor with two hundred vibration sensors, each spitting JSON payloads shaped by different firmware versions. One sensor sends 'temperature_C' as float, another as string—and a third omits it entirely when the reading is nominal. Schema-on-read should handle this. And it does—for about three weeks.

图片

You've heard the pitch. Data lakes let you dump everything—raw logs, clickstreams, sensor readings—without deciding on a schema upfront. Schema-on-read, they call it. Query-time interpretation. Sounds liberating.

But in practice, that freedom often curdles into a mess of undocumented fields, brittle parsing logic, and angry emails from analysts who can't find the data they need. I've seen teams burn months trying to untangle a lake that turned into a swamp. This article is about when schema-on-read becomes schema-on-despair—and how to avoid the trap.

Where Schema-on-Read Shows Up in Real Work

IoT Sensor Data Ingestion

Picture a manufacturing floor with two hundred vibration sensors, each spitting JSON payloads shaped by different firmware versions. One sensor sends 'temperature_C' as float, another as string—and a third omits it entirely when the reading is nominal. Schema-on-read should handle this. And it does—for about three weeks. The pipeline slurps everything into Parquet files, and analysts write Spark jobs that cast fields at runtime. It works because nobody has agreed on a shared schema yet, and the hardware vendor refuses to standardise. The catch? Every time a new sensor type appears, the parsing logic forks. I have seen teams end up with seventeen custom deserialisers, each tuned to a specific device revision, and zero documentation about which version maps to which asset tag. That's not agility—it's technical debt wearing a hoodie.

What usually breaks first is the anomaly detection model. It expects 'vibration_rms' in microns, but sensor batch 4B ships it in millimetres. Schema-on-read could convert—but who owns the conversion table? The ingestion script? The query layer? Nobody. So the model silently consumes garbage for six months until a bearing fails and somebody traces the error back to a missing unit transformation. Worth flagging—the raw data is perfectly intact. The interpretation rotted.

'Schema-on-read rewards storage discipline and punishes interpretation laziness. Most teams only discover the difference after a production incident.'

— Platform engineer, industrial IoT deployment post-mortem, 2023

Marketing Event Streams

Marketing teams love schema-on-read because they can fire events without asking permission. A product manager adds 'utm_campaign' one Tuesday, 'experiment_variant' the next, and occasionally 'user_cohort' with a nested object that contains a typo—'converstion_rate' instead of 'conversion_rate'. Wrong order. Wrong casing. Yet the lake accepts everything. Analysts downstream write queries with COALESCE and TRY_CAST, patching holes as they appear. That sounds fine until the VP of Growth asks for a unified funnel report spanning six quarters. Suddenly the query needs twenty fallbacks per column, and nobody remembers which field was introduced in which month. The dreaded three-hour debugging session begins—scanning old event definitions in Slack, comparing cloud storage paths, guessing at nullability semantics.

The pitfall here is subtle: schema-on-read works beautifully for ad-hoc exploration but catastrophically for reproducible reporting. You get speed today, but you pay for it later with cognitive overhead. I have watched a data team spend forty percent of their sprint reconciling event definitions across two marketing platforms—and they still missed the 'source' vs 'source_system' collision. The lake held both; the report lumped them together. That's schema-on-read promising flexibility and delivering confusion. The hard truth? If your event taxonomy changes weekly, you don't need a more permissive storage layer—you need a governance meeting.

Research Data with Unknown Shape

Machine learning researchers hoard raw data like digital dragons. They pull from Reddit dumps, Twitter firehose archives, scraped PDFs, and CSV exports where column names are in Polish but values are in broken English. Schema-on-read lets them land everything in one bucket and figure out the structure later. And sometimes that's the only sane choice—when you genuinely have no prior knowledge of the schema, forcing one upfront kills exploration. But the trap snaps shut when the research transitions into production. That messy ingestion pattern, designed for a single notebook experiment, becomes the foundation for a customer-facing feature. The seams blow out. Queries that worked on ten gigabytes crater on ten terabytes because the partition strategy assumed a schema that never materialised.

Most teams skip this: schema-on-read demands way more metadata management than schema-on-write, not less. You need column-level lineage, type inference audits, and a way to track schema drift over time. Without those, you end up with a lake full of perfectly preserved data that nobody can interpret. I saw a genomics project where the sequencing instrument changed its output format mid-study—schema-on-read accepted both versions silently, and six months of analysis had to be re-run because the 'mean_quality_score' field shifted from integer to float somewhere in week seventeen. The data was there. The meaning was gone.

What People Get Wrong About Schema-on-Read

Confusing It with No Schema at All

The most common mistake I see teams make is treating schema-on-read as a free pass to skip *any* up-front design. They dump raw JSON, Parquet files with mismatched column names, and CSV exports from five different systems—assuming the query engine will just figure it out. It won't. Schema-on-read doesn't mean schema-*never*. It means the schema is applied at query time rather than write time, but someone still has to tell the engine what the data looks like. Without a documented contract—even a lightweight one—you end up with analysts guessing column meanings or writing brittle transformations that break when a source system renames a field.

The tricky bit is that this confusion feels harmless at first. Data lands in the lake, queries return results, nobody complains. Then six months later a new hire runs a simple aggregate and gets garbage—because the 'revenue' column was sometimes a string with dollar signs and sometimes an integer. That's not schema-on-read failing; that's a team that conflated flexibility with anarchy. Worth flagging—the real cost here isn't technical debt; it's trust. Once people stop believing the data in the lake, they build shadow pipelines elsewhere.

'We thought schema-on-read meant we could skip data modeling entirely. Turns out we just moved the modeling problem from the ingestion layer to the analyst's lap—with worse tools.'

— data engineering lead, after a quarter of firefighting broken reports

Assuming Query Engines Can Guess Anything

Another pitfall: teams assume that modern SQL engines (Spark, Trino, DuckDB) can magically infer intent. They can infer types—string vs. integer—but they can't infer *meaning*. A column called 'status_code' might hold HTTP response codes, internal error IDs, or status flags from a CRM. The engine doesn't care; it just casts and moves on. The disaster happens when two datasets are joined on a column that *looks* like a key but contains subtly different values—one side stores 'ACTIVE', the other '1'. No query engine will flag that mismatch. You simply get fewer rows back and nobody notices until a dashboard shows flat sales for three weeks.

What usually breaks first is time-series data. Timestamps in different zones, dates formatted as YYYYMMDD in one file and epoch milliseconds in another—the engine coerces them silently, producing shifted or null values. I have seen a team lose a full day debugging why their hourly aggregated metrics showed a spike at midnight. The cause? One source used UTC, another used Eastern Time, and schema-on-read happily merged them into a single timestamp column. No warning, no error. Just wrong numbers.

Flag this for data: shortcuts cost a day.

Flag this for data: shortcuts cost a day.

That sounds fine until you're presenting those numbers to a stakeholder. The fix isn't more schema—it's *some* schema, enforced at the point where ambiguity enters the lake. A simple YAML file mapping source columns to expected types and timezone rules saves ten times the debugging hours later.

Ignoring Data Quality at Write Time

The worst take I hear: "We'll clean everything in the query layer." This assumes that bad data entering the lake is harmless because you can filter it later. Reality is messier—corrupted records can propagate into downstream tables, cached views, or ML training sets before anyone runs a quality check. By the time you spot the rot, it's already baked into three months of forecasts. Schema-on-read doesn't absolve you from validating at ingestion. You still need bounds checks, null-rate alerts, and type consistency gates.

Most teams skip this because it feels like extra friction. The catch is that deferred quality work becomes *more* expensive—you're now scanning terabytes to find bad rows instead of catching them at the megabyte stage. A concrete pattern I've used: apply a lightweight schema *stub* (column names, expected types, required fields) at write time, then allow richer transformations at read time. That one check eliminates 80% of the silent-failure scenarios without turning the lake into a rigid warehouse. The rest? That's where documentation and governance step in—not as bureaucracy, but as survival gear. Without it, your schema-on-read promise curdles into schema-on-despair faster than you'd think.

Patterns That Actually Work

Schema registry with versioning

The teams that make schema-on-read work don't just dump JSON and pray. They run a schema registry — a service that tracks every field, its type, and when it changed. One team I worked with stored Avro schemas in a central registry and tagged each record batch with a schema ID. Queries could then fetch the exact schema that wrote the data, not a guess at what the data meant. That sounds bureaucratic until you've spent a Tuesday afternoon debugging why a string field suddenly contains integers. The registry doesn't lock you into a rigid structure — it just documents what you actually did.

The tricky bit is that versioning only works if you enforce it at write time. Most teams skip this: they let producers push any shape of data, then wonder why their registry sits unused. Wrong order. You need the schema validated and stored before the data lands in the lake. Cost? A few milliseconds per write. Benefit? Months of saved debugging.

Partitioning by ingestion date

Another pattern that holds up under fire: partition raw data by the date it arrived, not the event timestamp inside the record. Why? Because event timestamps lie — clocks drift, batches replay, and someone always backfills last week's logs. Ingestion date partitions are a physical guarantee: you know exactly where new data lands. One startup I advised partitioned their S3 bucket as year/month/day/hour using the upload clock. Queries against the last 24 hours scanned one folder instead of hunting across 200. That's the difference between a 10-second report and a coffee break.

The trade-off, however, is that analysts want the logical time — "give me all transactions from June." You handle that with a secondary index or a lookup table mapping event dates to ingestion partitions. It's an extra join, but it beats full-table scans. That said, never let ingestion-date partitioning become an excuse to skip cleanup. Partitions pile up; you still need retention policies.

Storing raw + structured copies

Here's the pattern that surprises most newcomers: keep two copies of the same data. One raw — untouched, schema-on-read, JSON blobs with all the warts. Another structured — cleaned, typed, partitioned for query engines. Why double storage? Because raw data is your insurance policy. When the structured copy's schema breaks (and it will), you rebuild from the raw copy without reprocessing the source system. I've seen teams recover from a corrupted Parquet export in under an hour because they had the original NDJSON sitting in a cold storage bucket.

The catch is discipline: you must define how the structured copy is derived from the raw copy. Pipeline code, not ad-hoc scripts. Version that pipeline. Run it on a schedule. Most teams start strong, then let the structured copy drift. After six months, the raw copy is a museum of abandoned formats and the structured copy has columns nobody trusts. That's not a pattern failure — that's maintenance neglect.

'We stored everything in case we needed it. We needed it exactly once. That once paid for the storage for a decade.'

— Data engineer, after a regulator asked for a record that had been 'cleaned' two migrations ago

Anti-Patterns and Why Teams Revert

No schema registry, no evolution plan

Teams love the promise of schema-on-read — just dump JSON, Parquet, or CSV into a bucket and figure it out later. That works for about two sprints. Then someone changes a field name from user_id to userId. Another team adds an optional tags array. A third deletes a column nobody remembers. Suddenly your Spark jobs fail at 2 AM, and the only person who knows the shape of the data took vacation. I have watched four different companies hit this same wall. They had no schema registry, no versioning, no contract between producers and consumers. The result? Queries that worked last week return nulls, joins produce cartesian explosions, and analysts start hardcoding column indices. That's not flexibility — it's a data swamp with a shiny label.

What usually breaks first is the assumption that "we'll just read the schema at query time." Wrong order. Without a central registry and an explicit evolution plan — additive changes only, mandatory deprecation windows, required metadata — every consumer becomes a detective. They grep through Git history, Slack threads, and old ticket comments. Fragile. Slow. The catch is that schema registries feel like overhead during week one, so teams skip them. By month four, the cost of guessing a column's meaning exceeds the cost of ingesting the data itself.

Relying on a single engineer's tribal knowledge

One person holds the mental map of forty data sources. They know that cust_id actually means the Stripe account ID for European orders but the Salesforce lead ID for US transactions. They remember which partition keys are safe and which contain duplicates. Then they leave. Or get promoted. Or just get tired of the same slack DMs. I've seen a data lake freeze for three weeks because the engineer who understood the nested JSON structure of an event stream was on parental leave. That hurts. The lake doesn't care — it stores anything — but the people downstream need someone to translate. Without documentation, without automated validation, without a shared ontology, the lake becomes a black box. Teams revert to schema-on-write not because they love rigid schemas, but because rigidity is predictable. Predictable beats mysterious every time.

'We stored everything just in case. Then we couldn't find anything we actually needed.'

— data engineer at a mid-market fintech, reflecting on six months of lake maintenance

Field note: data plans crack at handoff.

Field note: data plans crack at handoff.

Most teams skip this: write a one-page producer contract before the first byte lands. Define field types, nullable constraints, and what a missing value means. Worth flagging — this isn't about killing flexibility. It's about making flexibility survivable. Without that contract, you don't have schema-on-read. You have schema-on-guesswork.

Mixing data from different sources without normalization

Raw ingestion is seductive. Just land the files, keep the original structure, and normalize later. Later never comes. Instead you get three different timestamp formats — Unix epoch, ISO 8601 without timezone, and a weird MM/DD/YYYY HH:MM string from an old CRM. Joining them requires custom functions and prayer. Currency fields arrive sometimes as integers, sometimes as decimals, sometimes as strings with dollar signs. A single pipeline trying to union these sources produces garbage silently. The anti-pattern is treating the lake as a dumping ground rather than a staging area. Teams revert to schema-on-write because the alternative requires too many transforms, too much glue code, too many meetings to agree on what "customer" even means. The fix isn't rocket science: apply minimal normalization at ingestion — type casting, timezone alignment, deduplication keys — and document the exceptions. Most teams don't. They pay for it in debugging hours, broken dashboards, and the slow realization that their data lake is just a landfill with faster query engines.

Maintenance Drift and Long-Term Costs

Pipeline fragility when upstream data changes

The first time a source system quietly renames a column you pay nothing. The second time a field changes from status_code to status you spend an afternoon debugging. By month six you have six different parsing scripts, each one handling a slightly different version of what was once a simple log line. That's the hidden tax of schema-on-read — every upstream change becomes a downstream detective hunt. I've watched teams burn two days chasing a null-pointer exception only to find out someone's CRM vendor had swapped customer_id for account_id in a nightly export. No schema, no early warning. The seam blows out at query time, not at ingest. And because nobody owns the schema contract, nobody gets paged until the dashboard goes grey.

Storage costs from unmanaged data

Cheap object storage is a lie. It's cheap to store, not cheap to keep. Teams adopt schema-on-read with the assumption that raw Parquet or JSON blobs cost pennies — and they do, initially. But what about the 400 GB of vendor exports that nobody documented? Or the six copies of the same clickstream dump because each analyst wanted their own "working set"? Without a schema to enforce retention rules, data piles up like digital sediment. One startup I worked with paid $1,700 a month for S3 storage they never touched — logs from an API that had been deprecated for two years. The catch is that cleaning it requires someone to read every file, infer what it's, and decide if it's worth keeping. That's exactly the work schema-on-read was supposed to avoid.

"We kept everything because we couldn't prove we didn't need it. Six months later we couldn't find anything."

— data engineer, post-mortem on a failed data lake migration

Time spent on ad-hoc parsing fixes

Wrong order. You write a Spark job to parse CSV files. It works for three weeks. Then someone adds a comma inside a quoted field and your parser throws an error at 2 AM. So you patch it. Then the source system starts escaping quotes differently. Another patch. Each fix looks small — twenty minutes, maybe an hour. But over eighteen months those micro-fixes accumulate into a brittle beast of if-else branches and hard-coded delimiters. That's not maintenance, it's debt with interest. The real cost isn't the compute or the storage, it's the attention tax: every time a senior engineer context-switches to fix a parsing edge case, they're not building something that moves the product forward. I've seen teams where 40% of their sprint capacity vanished into "data quality" tickets that were really just unmanaged schema drift wearing a different name. Schema-on-read doesn't eliminate schema work — it just postpones it, with interest, to the worst possible moment.

When Not to Use Schema-on-Read

Strict regulatory requirements

Schema-on-read is a compliance nightmare when auditors expect a fixed, auditable contract for every column. I watched a fintech startup burn six months trying to retroactively prove that a `price` field had always been numeric—after regulators demanded a schema snapshot for every ingest batch. The problem isn't that you can impose structure later; it's that regulators want the structure declared before data touches storage. Schema-on-write forces that declaration at insertion time. Painful? Yes. But when a compliance officer asks "show me the schema for Q3 trades," you can't answer "we'll figure it out during the query."

Healthcare and insurance data compounds the risk. HIPAA and GDPR both require demonstrable lineage—who touched what, when, and under which schema rules. Schema-on-read leaves lineage gaps because transformations happen ad hoc in notebooks or dashboards. One engineer's "quick regex cleanup" becomes an unlogged mutation. The catch is that schema-on-write demands upfront governance meetings nobody wants to attend. That said, skipping those meetings to avoid friction creates a different cost: legal exposure that a single audit can turn into a seven-figure liability.

"When your data model is a legal document, reading it on the fly is like signing a contract with vanishing ink."

— Senior data architect at a European bank, after a GDPR audit

Real-time processing with low latency

Schema-on-read shines in exploration—it dies under millisecond SLAs. Every time a streaming pipeline touches raw JSON or Parquet, it must parse, infer types, and resolve schema conflicts on the fly. That parsing cost compounds. I've seen a 50-node Flink cluster burn 40% of its CPU just re-inferring column types on every microbatch. The fix? A rigid Avro schema with a schema registry, enforced at write time. Latency dropped by 22 milliseconds per event. That's an eternity in trading systems or fraud detection—yet teams keep choosing flexibility over speed until their production alert pager explodes.

Wrong order: many teams add schema-on-read to a real-time pipeline because "Avro schemas are hard to evolve." But evolution happens rarely; queries happen billions of times. The trade-off is stark—spend two hours planning a schema migration once per quarter, or lose 15% throughput every day. Most underestimate how expensive runtime inference actually is. A single nested JSON field with optional keys can trigger multiple schema versions per minute. That atomicity loss isn't theoretical; it's your latency SLA crumbling under type-coercion overhead.

Small teams with limited data engineering bandwidth

This one hurts because I've lived it. Two-person data team, a mountain of CSV exports, and a CTO who read a blog post about "agile data lakes." We chose schema-on-read for everything. Six months later, every dashboard query ran 4–12 seconds slower than the previous month. The culprit: untyped string columns that forced the query engine to guess between int, float, and timestamp on every scan. A schema-on-write approach—even a simple typed CSV ingest with a JSON schema file—would have prevented that decay. But we were too busy fighting fires to declare columns upfront.

What I learned: small teams should default to schema-on-write for any data that feeds more than one report. The extra 30 minutes per dataset to define a schema pays back tenfold in not debugging why a `revenue` column sometimes contains "N/A" or why a date column mixes `2024-01-15` and `01/15/2024`. Schema-on-read is a tax on future you—and understaffed teams already owe too much technical debt. If you can't afford a schema registry or a data catalog yet, just write a YAML file with column types and validate on ingestion. It's ugly. It works.

Most teams skip this step because it feels like bureaucracy. Then they hit the maintenance drift we described earlier, except they don't have the headcount to dig out. That's not a tooling failure—it's a decision to prioritize short-term speed over survivability. One concrete alternative: a hybrid approach where raw data lands in a staging zone with minimal schema, but any table exposed to analysts gets an enforced schema-on-write layer. You keep the exploration sandbox and protect the production queries. That split doubles the initial setup effort but cuts the long-term cost in half. Try it on your next data source—pick the one that already causes the most "type conversion error" tickets.

Odd bit about data: the dull step fails first.

Odd bit about data: the dull step fails first.

Open Questions and FAQ

Can schema-on-read ever be truly scalable?

Yes—but not in the way most vendors pitch it. I have seen teams pile raw JSON into S3 and call it a day, only to watch query times balloon from seconds to minutes as data crosses a few terabytes. The bottleneck isn't the reading—it's the repeated parsing and type inference on every scan. Without some structural scaffolding, schema-on-read degrades into full-table deserialization hell. The trick is partitioning: not just by date, but by ingestion batch and source system. One team I worked with slapped on Hive-style partitions and saw their ad-hoc queries drop from 45 seconds to under three. Wrong order? They tried adding compute first. That hurts.

What usually breaks first is the metadata layer. When you have a thousand parquet files and each one carries a slightly different schema, the reader has to reconcile them on the fly. Spark spends more time inferring schemas than executing joins. The fix is brutally simple: enforce a canonical schema at write time, then let schema-on-read handle the edge cases. Worth flagging—this means your data producers need discipline. No discipline, no scale.

How do you enforce governance without killing agility?

Most teams skip this step until something goes sideways—a PII leak, a billing report that sums wrong, an auditor asking where a column came from. Then they overcorrect: lock down the lake with rigid ACLs, require schema registration for every new field, and suddenly your data engineers are filling out tickets to add a timestamp. Agility dies. The middle ground exists, but it's uncomfortable.

You govern after ingestion, not before. Tag sensitive columns automatically using pattern matching or a simple classifier—don't ask the producer to label them. Tagging before the fact means tagging never happens. Then wrap your query engine with a view layer that redacts or masks based on role. That way, raw data flows freely (agility preserved), but nobody accidentally queries credit cards in a dashboard. The catch: you need a data catalog that actually tracks lineage, not just a search index. We fixed this by pointing Apache Atlas at our Glue metastore, then adding a custom scanner for nested JSON fields. Three days of work. Saved us from a SOC-2 audit nightmare.

What's the role of data catalogs?

Catalogs are the unsung heroes of schema-on-read—or they're expensive documentation rot. Depends entirely on whether your team treats them as a live contract or an afterthought. A good catalog does three things: it registers schemas at write time, it tracks which consumers depend on which fields, and it warns you when a column type changes. Without that last bit, you get silent truncation in production dashboards.

'Our catalog was a ghost town until we wired it to our CI/CD pipeline. Now every PR that changes a schema triggers a diff report.'

— data engineer, fintech startup

The practical pain point: most catalogs assume you have a schema to catalog. When your data is semi-structured event blobs with optional fields, the catalog either chokes or forces you to flatten everything into a wide table—defeating the whole point. My advice: start with a lightweight tool like Amundsen that doesn't mandate strict schemas, then graduate to something heavier only when you hit compliance requirements. Not yet? Keep it simple. A shared spreadsheet beats a catalog nobody updates.

Next step: pick one dataset in your lake—preferably the messiest one—and manually register its schema in a catalog. Then set a calendar reminder to audit it every two weeks. If you can't keep that up, your governance model needs less process, not more.

Summary and Next Experiments

Key takeaways

Schema-on-read isn't the enemy — the enemy is treating it as a permanent free pass. You get speed early, sure, but that speed evaporates the moment five analysts interpret "revenue" three different ways from the same Parquet file. The real cost isn't compute; it's the hours spent reconciling what each team thought the data meant. Most teams I've worked with hit this wall around month six, when their "flexible" lake starts producing contradictory dashboards.

The core tension is simple: schema-on-read buys you velocity during exploration but charges interest when you need consistency. That sounds fine until you're debugging a pipeline at 2 AM because a new JSON field silently broke downstream joins. You don't need full schema enforcement everywhere — but you need some agreement layer before data reaches consumers. Worth flagging: teams that skip this step rarely revert to schema-on-write; they just accumulate more brittle parsing scripts and call it "data engineering."

Immediate actions to assess your data lake

Start with a single audit. Pick one source — your most-used streaming feed or a critical CSV dump — and trace what happens when a new field arrives. Does it break anything? Get ignored? Silently corrupt aggregations? The answer tells you where your schema debt lives. Next, check your most expensive query patterns. If every analyst rewrites the same CASE statement to handle missing columns, that's a signal, not a feature.

Then run a simple experiment: freeze the schema for that source for one week. Document what breaks. Most teams discover the chaos is narrower than they feared — maybe three dashboards and one export job. That's manageable. The catch is that nobody does the audit because they assume the pain is spread evenly. It rarely is. Usually one or two pipelines carry 80% of the interpretation burden.

“We thought schema-on-read meant zero contracts. Turned out we just had invisible ones — nobody signed, everyone blamed.”

— Data lead at a mid-stage SaaS company, after their third reconciliation sprint

Experiment: implement a schema registry for one source

Pick the data source that causes the most finger-pointing. Not the biggest — the most argued-about. Install Confluent's schema registry or a lightweight alternative like a minimal Python wrapper. Define one version of the schema with explicit nullable fields and default values for missing columns. That's it — no enforcement yet.

Next, route only that source through the registry for one sprint. Keep the old path running in parallel. What you're testing isn't adoption — it's whether the registry clarifies or complicates. I've seen teams discover that 70% of their parsing code just becomes a registry lookup. That's the win. The pitfall: over-engineering the registry with compatibility rules before you know which fields actually change. Start with backward-compatible defaults. You can lock down strictness later, once you understand the actual drift patterns.

Not ready for a registry? Try a lighter version: write a single YAML file that documents the expected structure for that source. Share it in your data catalog. See if it reduces the "what does this column mean?" Slack threads. Even that small constraint surfaces where your schema-on-read is really costing you — and where it's genuinely fine. Most teams find the pain clusters in maybe two or three sources. Fix those, leave the rest loose. That's not compromise; that's prioritization.

Share this article:

Comments (0)

No comments yet. Be the first to comment!