Data Ingestion and Source System Integration Questions
Getting data out of heterogeneous source systems and landing it reliably: APIs, operational databases, file drops, webhooks, message queues and third-party SaaS. Covers connector selection and design (managed platforms versus Debezium, DMS or Kafka Connect versus building your own), pull versus push and polling versus webhook patterns, incremental extraction and high-watermark strategy including what to do when a source offers no native change capture, authentication and credential rotation against third-party APIs, source-side rate limits and quotas, schema drift and contract breakage at the source boundary, backfill and replay of history, ingestion-time data-quality gates, reconciliation after a source outage, and negotiating with source-system owners. The scope stops at the boundary: once data has landed, transforming it, the architecture of the pipeline that carries it, stream-processing mechanics, and pipeline monitoring are all covered separately.
Tell me about a time you worked directly with the owners of a source system to reduce the operational impact your ingestion pipeline had on them, for example cutting the lock contention or CPU load your extraction was putting on their transactional database. What was the situation, what did you propose, what actually changed, and what did you learn about working with a team that owns data you depend on but do not control?
Sample Answer
Direct answer
I once inherited an hourly extraction job pulling from a transactional order database that, on close inspection, was holding row locks for several seconds per batch during business hours, occasionally causing brief but visible latency spikes for the application team's own customer-facing checkout flow. I worked with the application team to move the extraction to a read replica and switch from a naive full-table scan to a keyset-based incremental query, which eliminated the lock contention entirely, and the collaboration itself taught me that a source team's trust, once damaged, is much harder to rebuild than the technical fix itself.
Structured elaboration
The situation
- The application team flagged intermittent checkout latency spikes that correlated, timing-wise, with our hourly extraction job, though nobody on either team had proven the connection yet.
- Investigating the extraction query showed it was doing a full-table scan with an implicit lock-heavy read pattern, on the primary database, during business hours, not the off-peak window it had originally been designed for years earlier.
What I proposed
- Move extraction to the existing read replica, so the query's I/O and lock impact would no longer touch the primary at all.
- Rewrite the query from a full-table scan to a keyset-based incremental pull (using the same reliable timestamp column already available), which reduced the actual amount of data read per run dramatically on top of removing it from the primary entirely.
- I proposed this jointly, in a working session with the application team's on-call engineer, rather than unilaterally deciding and just informing them afterward, specifically because they were the ones who would bear the risk if my read-replica assumption about staleness turned out to be wrong for their use case.
What actually changed
- The extraction now runs against the replica on the same hourly schedule, with the incremental rewrite cutting the query's own runtime by roughly 80% as a side benefit.
- The application team's own monitoring confirmed the checkout latency spikes disappeared entirely once the change shipped, giving both teams independent confirmation rather than just my own before-and-after measurement.
What I learned
- The technical fix (read replica plus a better query) was genuinely the easy part; the harder part was that the application team had, reasonably, become somewhat guarded about any request touching "their" database after a previous unrelated incident, and earning enough trust to even get time on their calendar to discuss the problem took more deliberate relationship-building than the fix itself.
- I now default to proactively asking a new source team what their own operational constraints and pain points are BEFORE building an extraction against their system, rather than waiting for a problem to surface and then reacting to it, since that first framing sets the tone for the whole ongoing relationship.
Worked example
A structurally similar situation, negotiating an event contract with an application team before ingestion even began, followed the same underlying pattern: rather than reverse-engineering their event schema from whatever happened to be emitted, I asked for sample payloads, the expected field set and types, and realistic volume estimates up front, in a short working session before any pipeline code was written. When the application team later needed to add a field mid-project, having already established that channel meant they proactively looped me in on the schema change before shipping it, rather than my discovering it after the fact from a broken downstream job, which is the outcome the same underlying discipline, treating the source-owning team as an ongoing partner rather than a one-time data tap, was meant to produce.
Trade-offs & pitfalls
- Proposing a technically superior fix without first understanding why the source team might be cautious about changes to their system, given their own history and incidents, risks the proposal being received as tone-deaf even when it is technically correct.
- Moving extraction to a read replica is not free: it introduces a small amount of replication lag that has to be an acceptable trade-off for the specific freshness needs of the pipeline, and that trade-off should be made explicitly with the consuming team, not silently assumed.
- A single successful negotiation does not guarantee the relationship stays healthy; ongoing communication (a shared channel, a habit of flagging planned changes ahead of time) matters more over the long run than any one well-handled incident.
- Do not treat "the source team agreed" as the end of the story; verify the fix's actual effect independently (their own monitoring, in this case) rather than relying solely on your own before-and-after measurement, which can be subject to the same blind spots that missed the original problem.
Describe the API-polling ingestion pattern for a third-party REST API that has a strict rate limit and a paginated history endpoint. Outline a robust polling strategy: incremental polling against a checkpoint, exponential backoff when you hit the rate limit, pagination handling, retries, and how you minimize duplicate data across runs.
Sample Answer
Direct answer
A robust polling strategy against a rate-limited, paginated API has four pieces working together: an incremental filter so you only ask for what changed since the last successful run, a persisted checkpoint (a cursor or timestamp) so a restart resumes rather than re-pulling everything, exponential backoff so hitting the rate limit slows you down instead of hammering the API, and pagination handling that walks every page of a given pull before advancing the checkpoint. Get any one of the four wrong and you either miss data, duplicate it, or get your access revoked.
Structured elaboration
Incremental filtering
- Ask the API for only records changed since your last successful checkpoint, typically via a query parameter like
updated_sinceor a cursor token the API itself issues. - If the API has no incremental filter at all, you are forced into a full pull every run, which is far more expensive and is itself a strong argument for negotiating a better API contract or reconsidering the source.
Checkpointing
- Two related but distinct states are involved here, and the worked example below uses both precisely: a per-page in-progress cursor that advances after each page within the current pull succeeds (so a mid-pull crash does not restart from page 1), and a separate durable checkpoint, representing "the last fully completed pull," which only advances once every page in that pull has succeeded.
- Persist the checkpoint (last successful cursor or timestamp) to durable storage, not just in-memory, after each page is fully processed (this per-page persistence is what updates the in-progress cursor described above, not yet the durable checkpoint), so a crash mid-run resumes from the last completed page rather than from zero.
- The checkpoint should only advance after the corresponding data is durably written on your side (this is the durable checkpoint: it only moves once the whole multi-page pull is done); advancing it too early risks losing data on a crash between the API call and your write.
Rate-limit handling and backoff
- On a 429 or a documented rate-limit response, back off exponentially (for example doubling the wait each time, with a cap) rather than retrying immediately, and respect a
Retry-Afterheader when the API provides one. - Add jitter to the backoff so multiple workers hitting the same limit do not all retry in lockstep and re-trigger the limit together.
Pagination
- Walk every page for the current pull before moving the checkpoint forward; stopping partway through a multi-page pull and advancing the checkpoint anyway silently drops the unpulled pages.
- Cursor-based pagination (an opaque token the API returns) is generally more reliable under concurrent writes than offset-based pagination, which can skip or duplicate rows if the underlying data changes between page requests.
Minimizing duplicates
- Even with a correct checkpoint, some overlap at the boundary is common (a record updated in the same second as your cursor); load destination writes as idempotent upserts keyed on the record's own ID so a duplicate pull is harmless rather than a duplicate row.
Worked example
A connector pulls a third-party ticketing API rate-limited to 60 requests/minute, with 100 records per page. On a run where 850 records changed since the last checkpoint, that is 9 pages. The connector requests page 1, gets a 200, upserts the 100 rows, and does NOT yet advance the checkpoint (only the in-progress cursor moves). On page 4, the API returns a 429. The connector backs off for roughly 2 seconds, retries, succeeds, and continues. After page 9 returns with no further cursor, the connector advances the DURABLE checkpoint to the value the API returned after the last page, so the next run picks up cleanly from there. If the process had crashed after page 6 instead, the next run resumes at the in-progress pagination cursor saved after page 5 (a separate, per-page-persisted value from the durable checkpoint described above, which would still hold whatever it was before this pull started, since this pull never reached page 9), re-pulling page 6 at worst, which the idempotent upsert absorbs without creating duplicate rows.
Trade-offs & pitfalls
- The most common real bug is advancing the checkpoint to "now" instead of to the cursor value the API actually returned; if a record was still being written when you polled, "now" can silently skip it on the next run.
- Backing off without a cap turns a transient rate-limit blip into an effectively-stalled connector; always cap the maximum wait.
- Cursor-based pagination is not universally available; when an API only offers offset pagination, document explicitly that concurrent source writes during a pull can cause rare skips or duplicates, and rely on the idempotent upsert as the real safety net rather than the pagination scheme itself.
- Treat a persistent 429 (backoff maxed out and still failing) as an alerting condition, not just a retry loop; it usually means the polling interval itself needs to be widened, not just retried harder.
Describe how you would secure ingestion pipelines that span multiple cloud services and on-prem sources. Cover authentication and authorization for connectors (mTLS, IAM roles, service accounts), encryption at rest and in transit, secret management, auditing, and how you enforce least privilege for producers and consumers on both sides of a connector.
Sample Answer
Direct answer
Securing an ingestion pipeline that spans multiple clouds and on-prem sources means treating every connector as a distinct trust boundary: authenticate it with the strongest mechanism the source and target both support, encrypt data both in transit and at rest, keep every secret in a managed secrets store with rotation, log enough to reconstruct who touched what and when, and grant each connector only the specific permissions it needs, never a broad standing credential.
Structured elaboration
Authentication and authorization
- Prefer mutual TLS (mTLS) for connector-to-connector traffic where both ends support it, since it authenticates both parties, not just the client to the server.
- Use cloud-native IAM (Identity and Access Management) roles or service accounts for connectors talking to a cloud provider's own services, rather than long-lived static keys; a role can be scoped narrowly and its usage is natively auditable.
- For on-prem sources with neither mTLS nor cloud IAM available, a short-lived, narrowly-scoped service account credential is the fallback, still avoiding a single shared "integration user" account used by every connector.
Encryption
- In transit: TLS for every hop, including internal ones between a connector and an internal message bus; do not assume "internal network" means encryption is unnecessary.
- At rest: envelope encryption via a key management service (KMS), so data is encrypted with a data key that is itself encrypted by a master key the KMS controls, giving you centralized key rotation and revocation without re-encrypting all your data on every rotation.
Secret management
- Every credential, API key, database password, and certificate lives in a secrets manager, never in connector configuration files, environment variables checked into source control, or container images.
- Automate rotation where the source supports it; where it does not, at minimum track credential age and alert on staleness so rotation happens on a schedule rather than never.
Auditing
- Log every authentication event, every credential access, and every connector's data-access pattern (which source, how much data, when) in a way that is queryable after the fact, not just written to an ephemeral log that rotates away in days.
- Treat audit logs as themselves sensitive: they can reveal a lot about your data flows and access patterns, so restrict who can read them.
Least privilege for producers and consumers
- A connector reading from a source should have read-only access to exactly the tables, topics, or endpoints it needs, never blanket access to the whole source system.
- A connector writing to a target should be scoped to write only to its designated landing location, not broad write access across the destination platform.
- Review these scopes periodically; connector permissions tend to accumulate over time as requirements evolve, and nobody circles back to remove access that is no longer needed.
Worked example
A connector reads from an on-prem PostgreSQL database (via a VPN tunnel with TLS) and writes to a cloud data warehouse. The read side authenticates with a database service account scoped to SELECT on exactly the three tables the connector needs, credentials stored in the cloud secrets manager and fetched at connector startup rather than baked into its container image. The write side authenticates via a cloud IAM role scoped to write only into the specific landing schema this connector owns, with no access to any other team's tables. Both the credential fetch and every batch write are logged with a timestamp, source, and row count, so a security review six months later can answer "what did this connector actually access and when" without needing to reconstruct it from memory.
Trade-offs & pitfalls
- The most common real-world shortcut is a single shared "integration" database user with broad access used by every connector "to keep things simple"; this collapses your entire audit trail (you cannot tell which connector did what) and turns one leaked credential into access to everything.
- mTLS is not always available on legacy on-prem systems; do not let its absence become an excuse to skip TLS entirely, a one-way TLS connection is still meaningfully better than plaintext.
- Rotating secrets automatically is only safe if the connector can pick up a rotated credential without a manual restart; verify this before relying on automated rotation, or a rotation event becomes an unplanned outage.
- Least-privilege scopes decay over time as requirements shift; without a periodic review, "least privilege at launch" quietly becomes "broad privilege nobody remembers granting" within a year or two.
List and describe the main data sources a large consumer product ingests to support its product, personalization, and operations functions. For each source (for example client behavioral events, CDN or infrastructure logs, billing or membership events, catalog or content metadata, and partner-reported measurement), explain typical event-volume characteristics, cardinality, and who consumes it immediately downstream.
Sample Answer
Direct answer
A consumer product at real scale typically ingests five recognizably different kinds of source: high-volume client behavioral events, infrastructure and CDN logs, lower-volume but business-critical transactional events (billing, membership), relatively small and slow-changing catalog or content metadata, and partner-reported measurement data whose format you do not control. Each has a distinct volume profile, cardinality, and downstream audience, and conflating them under one ingestion design is where a lot of real pipelines go wrong.
Structured elaboration
Client behavioral events
- Volume: the highest-volume source by a wide margin, often billions of events per day at real scale, generated continuously by every user session.
- Cardinality: very high on dimensions like user ID and session ID, moderate on event type (a bounded, known vocabulary of action names).
- Downstream consumers: personalization and recommendation systems needing near-real-time signal, plus analytics and experimentation platforms consuming it in batch.
CDN and infrastructure logs
- Volume: also very high, driven by request volume rather than user actions, and often noisier and less structured than application-level events.
- Cardinality: high on request-level dimensions (IP, URL, timestamp), but the record shape itself is usually simpler and more uniform than a rich behavioral event.
- Downstream consumers: operations and reliability teams for real-time monitoring, plus security teams for anomaly and abuse detection.
Billing and membership events
- Volume: orders of magnitude lower than behavioral events, since they correspond to discrete business transactions rather than continuous activity.
- Cardinality: lower on most dimensions, but each individual record carries much higher business stakes than a single behavioral event does.
- Downstream consumers: finance and revenue reporting, customer support (for account status lookups), and fraud detection.
Catalog or content metadata
- Volume: the lowest-volume and slowest-changing source of the group, updated on the order of the catalog's own size and change rate, not user activity.
- Cardinality: bounded by the size of the catalog itself, typically far smaller than any of the event-volume sources.
- Downstream consumers: the personalization and search systems that join it against behavioral events, plus the product surfaces that render it directly.
Partner-reported measurement
- Volume: modest and typically batch-delivered on the partner's own schedule (daily or weekly files), not continuously streamed.
- Cardinality: depends heavily on the specific partner and measurement type, but the defining trait is that its format and delivery schedule are entirely outside your control.
- Downstream consumers: business reporting, revenue reconciliation, and any feature that specifically depends on that partner's data.
Worked example
A large streaming platform's product, personalization, and operations functions draw on exactly this mix: playback and interaction events from every viewing session (the highest-volume behavioral source, feeding both real-time personalization and batch analytics), CDN delivery logs (feeding operational dashboards and anomaly detection for stream quality issues), billing and subscription events (lower volume, high business stakes, feeding revenue reporting), catalog and content metadata (title, genre, cast, availability windows, feeding search and recommendation), and partner-reported measurement from advertising or co-production partners (batch-delivered, feeding revenue-share reconciliation). A team designing ingestion for this platform that treated all five as "just events to ingest" with one uniform pipeline would badly under-serve the billing source's correctness requirements while badly over-engineering the catalog source's freshness needs, since the two have almost nothing in common except both technically being "data."
Trade-offs & pitfalls
- The biggest real mistake is applying one uniform service-level agreement (SLA) and one uniform pipeline design across all five source types; a design tuned for the highest-volume behavioral stream is usually the wrong shape for the lowest-volume, highest-stakes billing stream, and vice versa.
- Cardinality is easy to underestimate for behavioral data specifically; a naive schema or index design that works fine at prototype scale can fail badly once real user-ID and session-ID cardinality is at production volume.
- Partner-reported measurement is the source most likely to have unannounced format drift, precisely because you have the least influence over the partner's own release process; it deserves proportionally more ingestion-time validation than its modest volume alone would suggest.
- Do not assume "downstream consumer" is singular for any of these; behavioral events in particular routinely feed both a real-time system (personalization) and a batch system (analytics) with genuinely different freshness needs from the same underlying stream.
When you are choosing a connector for the source or sink side of an ingestion pipeline, what do you actually evaluate? Walk through reliability, offset/checkpoint management, schema support, latency and throughput, security, and operational maturity, and explain how the calculus differs between a managed connector, a cloud-native connector, and something you build yourself.
Sample Answer
Direct answer
Choosing a connector, on either the source or the sink side, comes down to six things: how reliably it delivers data, how it tracks and persists progress (its offset or checkpoint model), how well it understands and communicates the source or target's schema, whether its latency and throughput fit your freshness needs, how it handles authentication and secrets, and how mature it is to actually operate day to day. A managed connector, a cloud-native one, and something you build yourself trade these off differently, and the right choice depends on which of the six actually matters most for this particular integration.
Structured elaboration
Reliability
- What delivery guarantee does it actually provide: at-least-once, at-most-once, or something closer to exactly-once via idempotent writes (writes that produce the same end result even if the same write is accidentally repeated, for example because a retry re-sends a call that actually succeeded the first time, so a retry never creates a duplicate)? Most connectors are honestly at-least-once; treat any "exactly-once" claim skeptically until you have seen how it is implemented.
- How does it behave on a transient failure: does it retry automatically, or does it require manual intervention to resume?
Offset and checkpoint management
- Does the connector track its own progress durably (so a restart resumes cleanly), and can you inspect or manually adjust that state if something needs to be replayed?
- For a source connector, this is usually a cursor or timestamp; for a sink connector, it is usually the last successfully-committed offset from the upstream topic or queue.
Schema support
- Does it understand the source or target's schema well enough to detect a breaking change, or does it treat every record as an opaque blob?
- For structured targets (a warehouse table, a typed sink), does the connector handle schema evolution (a new column, a type change) gracefully, or does it require manual reconfiguration on every source-side change?
Latency and throughput
- Is the connector fundamentally a polling design (batch-oriented, with latency bounded by the poll interval) or a streaming design (event-driven, near-real-time)? This is often the single biggest constraint on what freshness service-level agreement (SLA) you can promise.
- What is its realistic sustained throughput ceiling, and does that comfortably clear your actual data volume with headroom for growth?
Security
- How does it store and rotate credentials: a secrets manager integration, or configuration files that are easy to leak?
- Does it support the authentication model the source or target actually requires (OAuth2 with refresh tokens, mutual TLS, or cloud IAM (Identity and Access Management) roles), or only a simpler scheme that will not work for a security-conscious source?
Operational maturity
- How much observability does it expose out of the box: lag metrics, error rates, a dead-letter mechanism for records it cannot process?
- How is it upgraded, and what happens to in-flight work during that upgrade?
How the calculus differs by connector type
- A managed connector (Fivetran-style) tends to score well on operational maturity and reliability out of the box, at the cost of less visibility into exactly how it tracks offsets or handles schema changes internally.
- A cloud-native connector (a first-party AWS/GCP service) usually integrates cleanly with the platform's own IAM and secrets model, at the cost of being locked to sources and targets that specific cloud vendor supports well.
- A custom-built connector gives you full control over every one of the six dimensions, at the cost of having to implement and then operate all of them yourself, including the parts (idempotent retries, checkpoint persistence, schema-change detection) that are easy to get subtly wrong.
Worked example
A team choosing between three sink connectors for the same Kafka topic (a managed Snowflake sink, a cloud-native Kinesis Firehose-to-S3 delivery, and a custom Python consumer) needs sub-minute freshness and exactly-once-in-practice writes via a natural key. The managed Snowflake sink turns out to support exactly this pattern (a MERGE-based idempotent write keyed on a record ID) as a documented configuration option, so it wins on both fit and lowest operational burden. If the same team instead needed a target with no managed connector available at all, a proprietary internal service, the custom-build path would be forced regardless of preference, and the evaluation shifts to "how much of these six dimensions can we realistically implement well," not whether to build.
Trade-offs & pitfalls
- Do not evaluate a connector purely on throughput numbers from its marketing page; ask specifically how it behaves on failure, since that is where most real incidents originate.
- "It supports schema evolution" can mean anything from "handles a new nullable column automatically" to "requires you to manually update a mapping file"; get the specific behavior, not just the checkbox.
- A connector's offset model matters more than it looks: one that cannot be manually rewound makes recovering from a bad batch far harder than one that exposes and lets you adjust its checkpoint.
- Security is the dimension teams most often under-weight during evaluation and most regret later, particularly credential rotation, which a "quick proof of concept" connector rarely handles well from day one.
Unlock Full Question Bank
Get access to all 19 Data Ingestion and Source System Integration interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.