The pitch is hard to argue with: point AWS at your operational database, and the data shows up in your warehouse without a pipeline. No Spark job, no orchestration DAG, no CDC plumbing to page someone at 3am. That part is true. The part worth examining is what the word zero is doing.
- Business problem
- Teams adopt zero-ETL expecting the analytics platform to become somebody else’s operational problem, then discover that the replication was the cheapest part of the work. The integration arrives, the data lands, and the questions that actually block reporting — what does this field mean, is this number current, why did the totals move — are all still open.
- Why it matters
- A managed integration is a delivery guarantee, not a data contract. AWS documents that data is replicated as-is with no transformation, that the destination database is read-only, that tables without a primary key are not replicated at all, and that ordinary operations such as a cluster resize can silently trigger a full resynchronization. None of that is hidden — but none of it is visible from a slide that says zero.
- Architecture response
- Draw the boundary explicitly and early. Decide where conformance, typing, history, and quality gates live, given that they cannot live in the landing database. Instrument integration state as a first-class signal rather than trusting that a queryable table is a current one. Treat the source schema as an interface you now depend on, because replication has made it one.
- What Databright Cloud Solutions does
- We run the source-suitability assessment, design the target architecture and the modeling layer that sits beside the read-only landing database, build the reconciliation and observability that tells you replication is healthy and correct, and write down the division of responsibility so that the boundary is a decision rather than a discovery.
What the name actually removes
Be precise about the thing being replaced, because it is genuinely valuable. Before zero-ETL, moving operational data into an analytical store meant owning an extraction mechanism, a change-capture mechanism, a schedule, a failure-handling strategy, a backfill path, and the compute that ran all of it. That was real work, it broke in real ways, and it consumed senior engineering time that produced no analytical insight whatsoever.
Zero-ETL integrations take that layer over. As of September 2026, AWS handles the initial full load and the ongoing synchronization of source changes into the analytical destination, along with the infrastructure that runs it and the monitoring signals it emits.1 The integration recovers from transient issues on its own. You do not size it, patch it, or schedule it.
That is a large and legitimate reduction in operational surface. The mistake is reading it as a reduction in architectural surface. The pipeline was never the point; it was the mechanism. The point was producing data that a person could trust enough to make a decision with, and that job did not move.
That third box is the one nobody budgets for. Removing a pipeline does not leave a gap; it leaves a different set of failure modes, and they are less familiar than the ones you retired.
A delivery guarantee is not a data contract
The integration promises that a row written in the source will appear in the destination. It makes no claim about whether the resulting table is fit to query. Those are different guarantees, and conflating them is where most disappointment starts.
AWS is explicit on the point: zero-ETL integration does not support transformations while replicating, and data is replicated as-is from the source database.2 Every mapping decision, every unit normalization, every enum translation, every join that turns three operational tables into one analytical concept — all of it still has to happen. It happens after the landing rather than in flight, which is a genuinely reasonable design, but it is not fewer decisions. It is the same decisions in a different place.
Zero-ETL is not ETL minus the T. It is EL now, T later, on your side of the boundary. Teams that plan for the first reading are surprised; teams that plan for the second are not.
This matters most where the source is an operational schema that was never designed to be read analytically. Normalized transactional models optimize for write integrity, not for comprehension. Replicating one faithfully gives you a faithful copy of something that was never meant to answer business questions directly. The semantic layer that translates it is still your problem — and building that layer before pointing a model or a dashboard at the result remains the difference between fluent answers and correct ones.3
The source schema is now an interface you depend on
Here is the constraint that most often surfaces during implementation rather than planning: tables in the integration source must have a primary key, or they cannot be replicated to the target at all.2 Not replicated slowly, not replicated with caveats — not replicated.
Operational databases accumulate tables without primary keys for entirely ordinary reasons: append-only event logs, staging tables, junction tables built before anyone enforced a convention, tables created by an ORM that was configured casually years ago. None of that was a problem while the table only served the application. It becomes a problem the moment analytics depends on replication.
The consequence is a coupling that did not exist before. Adding a primary key to a busy production table is a schema change on the operational system, with its own review, its own maintenance window, and its own risk appetite. The analytics roadmap now has a dependency on the application team’s release calendar. That is a real organizational cost, and it belongs in the assessment rather than in week three of delivery.
Every table in scope, checked against the source catalog. The ones missing a key are schedule risk owned by another team, not by yours.
As of September 2026, a Redshift target supports up to 50 zero-ETL integrations, and Aurora PostgreSQL sources support a maximum of 100 databases, each replicating independently.2 Generous for most estates, but a real limit for a fleet of per-tenant databases.
Data filtering lets you include or exclude tables rather than replicating everything.4 Replicating the whole source because it is easy is how the destination becomes as hard to reason about as the origin.
The landing database is read-only, and that shapes everything downstream
The destination database created by a zero-ETL integration is read-only. You cannot create tables, views, or materialized views inside it.2 Materialized views are supported when used in cross-database queries, and you can build them on other tables in the target warehouse — but the modeling layer has to live somewhere that is not the landing database.
This is a sound design. A writable landing area would invite exactly the thing that destroys trust in replicated data: someone correcting a value in the copy instead of the system of record, producing a warehouse that disagrees with the application and no way to tell which one is lying. The read-only constraint enforces a discipline worth having.
It also means the architecture question cannot be deferred. You need a second layer — a modeling schema, a curated database, a lakehouse zone — where conformed tables live, and you need a mechanism that maintains it from the landing data. That mechanism has a refresh cadence, a failure mode, a cost, and an owner. If it sounds a little like a pipeline, that is because the transformation work has to run somewhere, and the managed integration explicitly does not run it.
Collation, case, and results that quietly differ
Two prerequisites on the target look like configuration trivia and are not. The destination warehouse must have case sensitivity enabled, and Amazon Redshift accepts only UTF-8 characters, so it might not honor the collation defined in your source.2 AWS states the consequence plainly: sorting and comparison rules might be different, which can ultimately change query results.
Sit with that. The same logical predicate, run against the source and against the replica, can return different rows. Not because replication dropped anything — every row arrived — but because the two engines disagree about whether two strings are equal or which one sorts first. A case-insensitive source collation that treated ACME and Acme as one customer will hand you two customers in the warehouse.
Nothing alerts on this. The integration is healthy, row counts reconcile, and the aggregate is wrong in a way that only someone who knows the business will notice — usually in a meeting. The defense is a reconciliation layer that compares business-meaningful aggregates between source and target rather than row counts, and a test suite that asserts on the grain of your entities: one customer per identifier, not two that differ by capitalization.
Where values change shape in transit
Type mapping between engines is never lossless, and the edges are documented specifically enough to design against. The maximum length of a Redshift VARCHAR is 65,535 bytes. When content from the source does not fit, replication does not proceed and the table is put into a failed state.2
The remedy AWS offers is a database parameter, TRUNCATECOLUMNS, which truncates content to fit the column. Read that as the trade it is: the choice is between a table that stops replicating and a table that silently holds shortened values. Both are defensible. Neither is a default you want discovered by a downstream consumer six weeks later. A free-text notes field, a serialized JSON blob, an audit payload — these are exactly the columns that grow past a limit nobody checked.
Numeric precision has a similar edge. For DynamoDB sources, partition and sort keys carry a maximum precision and scale of (38,18), while the default decimal precision and scale on Redshift is (38,10) — which means scale values can be truncated.2 For a financial or measurement column, truncated scale is not a formatting nuisance; it is a wrong number that looks entirely plausible.
Enumerate the columns where the source type is wider than the destination type, and decide explicitly — per column, in writing — whether the answer is fail loudly or truncate quietly. A parameter set globally makes that decision for every column at once, usually without anyone noticing it was made.
A table you can query is not necessarily a table that is current
By default you can only query tables in the target that are in the Synced state, and the database parameter QUERY_ALL_STATES set to TRUE lifts that restriction.2 The default is the safe one, and it is worth understanding why before anyone changes it to make a dashboard stop erroring.
A table that is resynchronizing holds data that may be stale or partial. With the default, queries against it fail — loudly, visibly, in a way that gets investigated. With QUERY_ALL_STATES enabled, they succeed and return data that AWS notes might be stale until resynchronization completes. The error was doing useful work. Trading it for availability is a legitimate choice for some workloads and a serious mistake for a regulated report.
The same shape appears in a more consequential place. If you delete a source that is an authorized integration source, all associated integrations go into the FAILED state — and any previously replicated data remains in your Redshift database and can be queried.2
That is failure that presents as success. The dashboard renders. The numbers are the numbers from whenever replication stopped. Nothing in the query path indicates that the data behind it is frozen. Unless somebody is monitoring integration state as a first-class signal, the only detection mechanism is a human noticing that a figure has not moved — which, for a slow-moving metric, can take a very long time.
SVV_INTEGRATION_TABLE_STATE exposes per-table integration state.5 Alert on anything that is not Synced, and alert on the integration entering FAILED or NEEDS_ATTENTION independently of any data-volume check.
Every served table carries a documented tolerance, and a check that fails when the newest record is older than it. A frozen replica violates this within one cycle; a row-count check never will.
QUERY_ALL_STATES per workloadAvailability during resync for an operational dashboard is reasonable. For a report someone signs, the default failure is the feature.
Routine operations that trigger a full resynchronization
Resynchronization is not an exceptional event reserved for disasters. It is triggered by ordinary platform maintenance, and the triggers are worth knowing before you schedule that maintenance.
On a provisioned cluster, an elastic resize that changes only the node count leaves integrations synchronized, but an elastic resize that changes the node type causes all tables in zero-ETL integrations on the cluster to resynchronize — and any classic resize does the same. AWS explains why: those operations temporarily change the distribution style of tables while data is redistributed. Resynchronization can take 20–25 minutes or more depending on the size of the source database, and while a table is resynchronizing you cannot query it unless QUERY_ALL_STATES was set beforehand.2
Restores carry their own rules. Restoring a Redshift Serverless namespace from a snapshot to the same namespace maintains the integrations and then performs a full resync; restoring to a different namespace does not maintain them at all. An integration created after the snapshot was taken enters NEEDS_ATTENTION after the restore, because the corresponding database does not exist in the snapshot. Snapshot restores on provisioned clusters do not maintain integrations.2
Scaling the warehouse and restoring the warehouse are now data-availability events for every downstream consumer, not just infrastructure changes. That belongs in the change-management process and the consumer-facing SLO — written down before the first resize, not discovered during one.
History mode answers one temporal question, not all of them
Plain replication gives you current state. The moment a row is updated at the source, the previous value is gone from the replica, which makes the warehouse unable to answer the most common analytical question there is: what did this look like before it changed?
History mode addresses this, and it is the most analytically significant option in the feature set. It maintains record versions with tracking columns — _record_is_active and _record_delete_time among them — so that superseded versions remain queryable.6 Its edges are specific and worth internalizing:
When you drop a table on the source, the target table is not dropped; it changes to DroppedSource state and you remove it deliberately. Deletion at the source does not silently destroy history.
Truncating at the source runs deletes on the target — records have _record_is_active changed to false rather than vanishing. Inactive rows become deletable after roughly a ten-minute delay.
After a snapshot restore, record versions from the time the snapshot was taken until the full resync completes are not captured. History resumes afterward — with a hole in it that nothing in the data announces.
Turning history mode off for a table saves historical data to <schema>.<table>_historical_<timestamp> while the original is refreshed. Anything querying history needs to know that happened.
Notice what history mode gives you and what it does not. It records when the warehouse learned about a change. It says nothing about when the change became true in the real world, or when the source system recorded it. Those are different clocks, and conflating them produces historical analytics that look rigorous and are wrong at exactly the moments that matter — corrections, backdated entries, late-arriving facts.7 If your decisions depend on reconstructing what was known at a point in time, history mode is a useful input to that model, not a substitute for it.
“Near real time” has a floor, and it differs by source
Latency is a property of the specific source-and-destination pairing rather than a single figure for the feature. As of September 2026, the minimum latency for a DynamoDB zero-ETL integration is 15 minutes, and the minimum for an integration with application sources such as Salesforce, SAP, ServiceNow, and Zendesk is one hour.2 A REFRESH_INTERVAL parameter lets you lengthen the interval deliberately; it does not let you go below the floor.
These are perfectly workable numbers for analytics. They are not workable for a use case someone described as real time in a planning meeting without checking. The gap between near real time as a marketing phrase and one hour minimum as a documented floor is the kind of thing that reshapes a roadmap after commitments have been made.
Deliberately lengthening the interval is underrated. Replication frequency has a cost, and a table feeding a weekly report does not need continuous synchronization. Setting refresh intervals per integration according to what actually consumes the data is straightforward cost control that most implementations never revisit after launch.
The boundaries that were always yours
Beneath the data questions sit the platform questions, and none of them are absorbed by the managed integration.
As of September 2026, the target must be Redshift Serverless or a provisioned cluster of an RA3 or RG node type, encrypted if provisioned, with case sensitivity enabled.2 An older cluster is a migration before it is an integration.
The integration runs in Redshift using the credentials of the user who created the database from the integration.2 If that is a personal account, you have coupled a production data flow to one person’s lifecycle. Service identities exist for this.
KMS keys and their policies, VPC subnets and security groups, resource policies authorizing the source, and the grants that decide who reads the landing database. All still designed, reviewed, and audited by you.
Destination support is source-specific and keeps widening. Managed AWS databases and supported applications can target Redshift — provisioned or Serverless — or SageMaker Lakehouse, while the self-managed pathway runs through AWS DMS and requires a provisioned Redshift cluster.8 Check the matrix for your source at design time rather than generalizing from the overview page.
Replication is not free, and the bill is distributed across the source service, the target warehouse, and the integration itself. Without deliberate tagging, nobody can answer what a given dataset costs to keep current.
Write the division down before the first integration
The single most useful artifact in a zero-ETL adoption is unglamorous: a document naming who owns what. Not because the boundary is ambiguous in the documentation — it is quite clear — but because organizations infer boundaries from product names, and this product name implies an unusually large claim.
Put names against the right-hand box. Who decides whether a column truncates or fails. Who owns the modeling layer that exists because the landing database is read-only. Who is paged when an integration enters FAILED while the dashboards keep rendering old numbers. Who signs off when the application team wants to alter a replicated table.
That last question is the one that tends to be unowned, and it is the one that causes the most damage. A schema change at the source is now a change to an analytical interface. Before replication it was an application decision. After replication it is a shared one, and the team making it usually has no idea that changed.
What this buys, honestly stated
Zero-ETL is a real advance and worth adopting where the pathway fits. It removes a category of undifferentiated engineering that consumed senior time and produced no insight. Teams that adopt it deliberately get to spend that time on modeling, quality, and the semantic work that actually determines whether anyone trusts the output.
What it does not do is make the analytical platform somebody else’s responsibility. The integration guarantees that rows arrive. Everything that turns arrived rows into a number a person will act on — conformance, typing, history, reconciliation, contracts, the observability that distinguishes healthy from correct — sits on your side of a boundary that the product name does not advertise.
Adopt zero-ETL for what it genuinely removes: the pipeline. Staff for what it genuinely does not: the meaning. A project planned against the first and resourced against the second lands well. One planned against the name does not.
Sources and industry references
- AWS — Zero-ETL integrations with Amazon Redshift: supported sources, target data warehouse definition, and managed replication
- AWS — Considerations when using zero-ETL integrations with Amazon Redshift: prerequisites, primary-key requirement, read-only destination, no in-flight transformation, collation and UTF-8 behavior, VARCHAR and precision limits, table states, resize and restore resynchronization, integration quotas, and latency floors
- Databright Cloud Solutions — Don’t Point the Model at the Warehouse: why raw data plus a capable model produces fluent answers rather than correct ones
- AWS — Data filtering for Aurora zero-ETL integrations with Amazon Redshift: scoping replication with include and exclude filters
- AWS — SVV_INTEGRATION_TABLE_STATE: per-table integration state for monitoring
- AWS — History mode for zero-ETL integrations: record versioning, tracking columns, and behavior on drop, truncate, and resync
- Databright Cloud Solutions — The Temporal Truth Problem: separating when a change became effective from when a source recorded it and when a platform received it
- AWS — Zero-ETL integration for self-managed database sources: the DMS pathway, its prerequisites, and the provisioned-cluster requirement
This article provides architecture perspectives, not implementation guidance for a specific environment. Cloud service capabilities, quotas, supported sources and destinations, latency floors, and pricing change; the behaviors described here reflect AWS documentation as of September 2026. Validate the current compatibility matrix, service limits, and supported Regions for your own sources before committing to a production design.