Combined vs custom ETL: keep agent answers correct after the first sync
Compare Combined with custom ETL using a runnable replay and recovery drill, Source grants, operating costs, and a Salesforce–Stripe answer contract.
Choose Combined when you want source connections, ingestion, managed storage, and read-only agent access managed together. Choose custom ETL when control over ingestion or deployment serves a concrete requirement and your team wants to operate the stack. Compare the decision with a runnable replay and recovery drill.
Compare ownership after the first successful load
Your agent can answer a business question when the first import works. The more useful test comes next: an invoice changes, a batch repeats, or a worker stops halfway through a load. Does the next answer use the right records?
A custom stack can reuse capable libraries. dlt already provides configured cursor tracking, duplicate handling, and merge strategies, including explicit delete handling. You can assemble useful ingestion without writing every primitive yourself. Its documentation makes the configuration choices concrete: primary keys, cursor semantics, and revision ordering affect what lands in the destination. dlt cursor loading; merge loading.
The decision is who connects those components into the service your agent uses. Somebody owns source changes, failed loads, storage, query access, and incident recovery. Your team also defines customer identity and business metrics in either approach. Combined supplies the managed connection-to-query path, so your developers can concentrate on the agent and the decisions it supports.
Run the replay and recovery drill
Download the self-contained Python drill and expected output into the same writable directory. It uses Python's standard library and SQLite, creates a temporary database beside the script, and removes it afterward. No credentials or package installation are needed.
python3 replay_drill.py --verify expected.jsonThe supplied version passed 29 local cases, including three abrupt child-process exits. Inspect the recorded output and run notes. Its synthetic records start with two USD amounts, $100 and $200. These are tests of the teaching script, not a vendor service.
| Change | Answer or behavior |
|---|---|
| Repeat the delivery or an identical record | Total remains $300. |
| Apply a newer revision, then delete another record | Total becomes $350, then $150. |
| Apply a late update, followed by older revisions | Total becomes $175 and stays there; the deleted record stays deleted. |
| Encounter a conflict after an earlier row in the batch | The entire batch rolls back; total stays $175. |
| Exit after records or checkpoint are written, before commit | Records, revision evidence, receipt, and checkpoint retain their previous committed state. |
| Recover, then lose acknowledgment after a later commit | Recovery reaches $230; the later committed $250 remains unchanged when retried. |
Identity includes source, provider account, entity, and record key. That prevents the same ID in a sandbox, another entity, or another provider from overwriting a production record. Currency totals remain separate. A retained tombstone prevents an older update from resurrecting deleted data; a revision history detects conflicting content even for an older revision.
Carry the contract through to the agent
A correct destination still needs controlled query access. In Combined, a Source is the boundary for a connected provider account, grants, and freshness. Confirm the connector's current Ready status and selected fields, complete the first committed sync, then discover the actual logical datasets. Check the reporting interval separately from the last successful commit timestamp. Source lifecycle and freshness.
Account administration and data authorization are separate. Give the agent explicit Source grants, optionally restricted to selected datasets. Ordinary grants do not automatically acquire future Sources. The agent can inspect schemas and query permitted relations; its SQL surface rejects writes, external-file reads, and relations outside its grants. Access model; SQL policy.
For a custom stack, identify the component enforcing each decision. Record how revocation affects an in-flight answer and how the agent learns that a source is stale. Compare your workload with the effective query bounds; Combined's documented default includes a 256 MiB estimated-input ceiling per query.
Evaluate a business answer across Salesforce and Stripe
Open the Salesforce–Stripe plan and use the opportunities and invoices workflow. It includes a separate DuckDB SQL fixture and expected result.
Map scoped Stripe customers to Salesforce accounts. Aggregate opportunities and invoices separately before joining, so multiple opportunities cannot duplicate invoice totals. Define current open pipeline, paid invoices within June 12 inclusive to September 10 exclusive, 2026 UTC, and current outstanding balances. The fixture's overdue cutoff is September 10 at 00:00 UTC. The paid-invoice metric excludes partial payments on invoices that remain open.
In this USD fixture, Atlas has $20,000 open pipeline, $3,000 paid in the window, and $700 outstanding: $500 overdue and $200 without a due date. Birch has $6,000 pipeline and zero qualifying invoice amounts. These numbers give either implementation a checkable answer contract.
Discover the granted Salesforce and Stripe datasets. Validate the
customer/account map, source freshness and reporting coverage.
Calculate current open pipeline and paid-invoice amounts in
[2026-06-12, 2026-09-10), UTC. Aggregate each side before joining.
Keep currencies separate and outstanding, overdue and undated
balances distinct. Use 2026-09-10 00:00 UTC as the overdue cutoff.
Return supporting IDs, time bounds and SQL.Adapt the teaching relations to your discovered schema. Keep identity exceptions visible and calculate across complete eligible inputs before limiting the displayed accounts.
Price the work you will actually own
Use the platform evaluation worksheet to compare your starting point and these inputs:
| Cost or responsibility | Record for each approach |
|---|---|
| Initial implementation | Additional setup hours, owner, and components already available. |
| Operations | Connector repairs, failed-load recovery, and expected maintenance hours. |
| Infrastructure | Storage, query compute, scheduling, and monitoring charges. |
| Product or service usage | Applicable ingestion, connector, or query charges at your volume. |
| Application definitions | Ownership of mappings, metrics, and access decisions. |
Amortize observed build effort over your chosen period and include ongoing work. Existing infrastructure changes the incremental comparison. Combined starts with 5 million MAR without a card; its public rate after the trial is $5 per million MAR. Use the documented changed-record definition and query budgets when estimating usage. Pricing; usage rules.
Questions to settle before choosing
Does every provider have these revision and checkpoint guarantees?
The synthetic feed supplies contiguous positions and a monotone revision order per record, although delivery can arrive out of order. Real providers may offer different guarantees. Adapt the source contract using the drill's documented assumptions.
Does the drill establish production service guarantees?
It verifies local SQLite transactions and supplied records. It does not test Combined or another service, upstream completeness, or distributed commits. Use it to inspect the pattern, then evaluate your actual source and destination boundaries.
When should we keep our custom stack?
Choose the custom stack when its control serves a concrete requirement and your team wants to operate it. Choose Combined when you want managed business data behind the agent you already use. Start with two sources and one recurring question, then use the plan to make your first answer inspectable.
Sources and further reading
Explore the documentation behind this guide. Product details checked on September 11, 2026.
- Combined MCP tools and Source grants
- Combined SQL interface
- Combined connector availability
- Combined pricing and MAR
- dlt cursor-based incremental loading
- dlt merge, ordering, and delete handling
- Combined Source lifecycle and freshness
- Combined access and Source grants
- Combined usage and query budgets
- Replay drill assumptions and observed results