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.
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.
Explain pull-based and push-based data ingestion models. For each, give concrete examples (polling a REST API or periodic file fetch versus webhooks or event streams), and compare latency, throughput, operational complexity, load on the source, error and retry behavior, and typical failure modes in production.
Sample Answer
Direct answer
Pull is you initiating contact with the source on your own schedule, for example polling a REST API or fetching a file drop; push is the source initiating contact with you, for example a webhook call or a message it publishes to a stream you subscribe to. Pull gives you full control over pacing and load on the source, at the cost of built-in latency between when something happens and when you notice. Push gives you near-real-time delivery, at the cost of needing to be reliably available to receive it and coordinate with whatever retry behavior the source uses when you are not.
Structured elaboration
Pull
- Concrete examples: polling a REST endpoint every N minutes, fetching a nightly file drop via SFTP (SSH File Transfer Protocol) or from S3, running a scheduled SQL query against a source database.
- Latency: bounded below by your polling interval; a change occurring right after a poll will not be seen until the next one.
- Throughput and source load: you control the request rate directly, which is good for respecting a source's capacity, but a poorly tuned interval can either waste calls when nothing changed or lag badly when a lot changed.
- Operational complexity: you own scheduling, checkpoint tracking, and retry logic; the source does not need to know or care about you.
- Failure modes: a missed poll (your job did not run) simply gets caught on the next poll if your extraction is incremental; the risk is a silent scheduler failure going unnoticed for a while.
Push
- Concrete examples: an inbound webhook call from a payment processor, a message a source publishes to a queue or event stream you consume.
- Latency: near-real-time, since the source notifies you the moment something happens rather than you having to ask.
- Throughput and source load: the source decides the rate, which can spike unpredictably; you need to be able to absorb bursts without falling over.
- Operational complexity: you must run a reliably-available receiver (an endpoint or a consumer), and you inherit whatever the source's own retry and ordering guarantees are, or are not.
- Failure modes: if your receiver is down when a push arrives, you depend entirely on the source retrying it; some sources retry aggressively, some drop the event, and a few offer no redelivery at all.
How to choose
- Freshness requirement: sub-minute or real-time needs generally rule out pure polling.
- Source support: you cannot choose push if the source does not offer it; not every system has webhooks or a stream to subscribe to.
- Control versus availability: pull lets you throttle yourself to protect a fragile source; push demands your receiver be highly available, since you cannot control when the source sends.
- Operational maturity: a small team with no on-call receiver infrastructure may be better served starting with pull, even at some freshness cost, and moving specific sources to push as reliability matures.
Worked example
A team gathering training data for a model has three needs: (a) a large historical backfill of past user actions, (b) online feature updates that must reflect a user's most recent action within seconds, and (c) periodic collection of new human feedback labels. For (a), pull is the only sensible choice: there is no "event" to push, it is a bulk historical extraction, typically against an API or a warehouse export. For (b), push is close to mandatory, since seconds-level freshness is well below what any reasonable polling interval could deliver without hammering the source. For (c), pull on a modest schedule (hourly or daily) is usually sufficient, since new labels do not need to reach the training pipeline instantly, and a scheduled pull is far simpler to operate than standing up a webhook receiver just for this.
Trade-offs & pitfalls
- A common mistake is polling far too aggressively "to reduce latency," which just moves the bottleneck onto the source's rate limits without meaningfully improving freshness once you are polling faster than data actually changes.
- Push without idempotent handling on your side is a duplicate-processing incident waiting to happen, since almost every push-based source will retry a delivery it believes may have failed, even when you actually received and processed it.
- Do not assume push is strictly better because it sounds more modern; a source with unreliable delivery and no replay mechanism can lose data silently in a way a well-designed poll with checkpointing cannot.
- Micro-batching (short, frequent pulls, seconds to low minutes) is a real middle ground worth naming explicitly: it gets you most of push's freshness without needing a highly-available receiver.
A new source system supports both webhooks and a polling API. Walk through the trade-offs of using webhooks versus periodic API polling for ingesting from it: reliability, retry handling, back-pressure, security, and the operational monitoring each approach requires.
Sample Answer
Direct answer
Webhooks give you near-real-time delivery at the cost of needing a reliably-available receiver and inheriting whatever retry behavior the source implements; polling gives you full control over pacing and a simpler operational model at the cost of latency bounded by your polling interval. When the source supports webhooks, prefer them for anything with a real freshness requirement, but keep a periodic reconciliation poll running alongside as a safety net, since even a well-implemented webhook sender can silently fail to deliver.
Structured elaboration
Reliability
- A webhook depends entirely on the source's own retry policy for delivery; some sources retry aggressively with backoff over hours, some retry a few times and give up, and a few offer no redelivery at all, so "reliability" here is really a question about the SOURCE, not something you control.
- A poll is self-healing by construction: if one poll fails or is missed, the next scheduled poll picks up everything that changed since the last successful checkpoint, with no dependency on the source retrying anything.
Retry handling
- For webhooks, your receiver has to be idempotent, since the source's retries mean you will occasionally receive the same event twice; deduplicate on the event's own ID before processing.
- For polling, retries are entirely under your control: a failed poll is simply retried by your own scheduler with your own backoff policy.
Back-pressure
- A webhook sender pushes at whatever rate events occur, which can spike unpredictably (a bulk operation on the source side, for example); your receiver has to absorb bursts without falling over, typically by accepting quickly and queuing for async processing rather than processing synchronously in the request handler.
- Polling gives you back-pressure for free: you simply do not ask for more until you are ready.
Security
- A webhook receiver is a public-facing endpoint, so it needs signature verification (an HMAC, a hash-based message authentication code, that the source includes, checked against a shared secret) to confirm a request genuinely came from the source and was not forged.
- Polling has no equivalent public-surface risk, since you are the one initiating every request, but it does still need the outbound credentials properly secured.
Operational monitoring
- For webhooks, monitor for SILENCE, not just errors: a source that has quietly stopped sending events (a misconfiguration on their side, a subscription that expired) produces no errors at all on your end, only an absence of expected traffic, which is much harder to notice than an explicit failure.
- For polling, monitor the poll's own success rate and the volume of records returned per poll, watching for an unexpected drop that would suggest the source-side query or filter has broken.
Worked example
A source offers both a webhook and a polling API for the same event type. Freshness matters (downstream alerts should fire within seconds), so the primary path is the webhook: the receiver verifies the HMAC signature, deduplicates on event ID against a short-TTL store, and queues the event for async processing so a burst of webhooks does not block the HTTP response. Running alongside, a lightweight poll every 15 minutes checks for any records the webhook path might have missed, comparing against the same downstream store; any record present in the source's poll response but absent downstream triggers a targeted backfill of just that gap, which is far cheaper than either abandoning webhooks (losing real-time freshness) or trusting them blindly (risking silent, undetected gaps).
Trade-offs & pitfalls
- If the source offers no webhook at all, the framing is not really "webhook versus polling," it becomes "how tight a poll interval can we sustain without exceeding the source's rate limit," and any real-time expectation needs to be reset against that constraint honestly rather than pretending polling can match webhook latency.
- A webhook receiver that is down even briefly can lose events permanently if the source does not retry, or does not retry for long enough to cover your downtime; know the source's specific retry window before relying on it as your only path.
- Signature verification is frequently skipped in early implementations "to get something working" and then never added later; treat it as non-negotiable for any public-facing receiver, not an enhancement to add eventually.
- The reconciliation-poll safety net is cheap insurance against silent webhook failures, but only if someone is actually watching its output; an unmonitored reconciliation job that has been silently finding and ignoring gaps for months is barely better than having no safety net at all.
You are integrating three SaaS systems into your warehouse. One emits events, one only supports paginated reads, and one exports a file every night. The business wants a daily dashboard now and near-real-time alerts from one of the sources later. How would you choose the integration pattern for each source, and keep the overall design maintainable as the requirements evolve?
Sample Answer
Direct answer
Match the integration pattern to what each source can actually do, not to a single company-wide standard: the event-emitting source becomes a subscriber, the paginated-read-only source becomes a scheduled poll, and the nightly-file-export source becomes a scheduled file pickup. The design stays maintainable as requirements evolve by landing all three into the same normalized raw layer with a consistent schema and metadata, so a later change (adding near-real-time alerts from one source) only touches that one source's ingestion path, not the shared downstream model.
Structured elaboration
Matching pattern to source capability
- The event-emitting source: subscribe to its events (a webhook or a stream), land each event as it arrives; this is the only one of the three sources that can support the future near-real-time alert requirement without a redesign.
- The paginated-read-only source: a scheduled poll walking every page since the last checkpoint, on whatever interval balances freshness against the source's rate limit.
- The nightly-file-export source: a scheduled pickup job (SFTP, meaning SSH File Transfer Protocol, cloud storage, or however the export is delivered) that runs shortly after the export is expected, with a check that the file has actually landed before processing it.
Keeping the design maintainable
- Land all three into a common raw/landing layer with a consistent envelope (source name, ingestion timestamp, and the original payload), so downstream consumers work against one shape regardless of which pattern produced the data.
- Keep each source's connector isolated: a change to how the file-export source is polled should never require touching the event-subscriber's code.
- Make the freshness characteristics of each source visible downstream (a "last updated" or "as of" indicator per source) rather than presenting all three as if they were equally fresh, since silently blending a nightly-batch source with a real-time one can mislead a dashboard's audience about how current the numbers actually are.
Building in room for the requirement to evolve
- Today's ask is a daily dashboard, which the paginated and file-export sources already satisfy on their existing schedules; the event source's daily aggregation is just a rollup of its already-landed real-time stream, so no rework is needed there either.
- The stated future need (near-real-time alerts from one source) should specifically inform WHICH source you architect for streaming from day one, even if you are not yet building the alerting logic; retrofitting an already-batch-oriented connector into a streaming one later is a much larger project than building it as a subscriber from the start when you already know that is where it is headed.
Worked example
The event-driven source publishes order-status-change events; land each event onto a raw topic or table immediately as it arrives, since this is the source flagged for a future near-real-time alert. The paginated-read-only source (a support-ticketing API) is polled every 30 minutes using cursor-based pagination and a persisted checkpoint, comfortably supporting the daily dashboard's freshness need without over-polling a source that has no true real-time signal to offer anyway. The nightly-file-export source (a partner's inventory feed) is picked up by a job scheduled 30 minutes after the partner's documented export window, with a presence check before processing so a late or missing file triggers an alert rather than the job silently processing yesterday's stale file again. All three land into the same raw schema (source, ingested_at, payload), and the daily dashboard is built from a view over all three, each contributing at its own natural freshness. When the near-real-time alert requirement actually arrives, only the event source's already-real-time data needs a new consumer built against it: neither the poll-based nor the file-based ingestion paths need to change at all.
Trade-offs & pitfalls
- The most common mistake is trying to force all three sources into ONE integration pattern for "consistency," typically by wrapping the event source in a batch poll of its own API instead of subscribing directly, which throws away the one capability (real-time delivery) that source actually offers and that the stated future requirement will need.
- A file-pickup job with no presence check is a classic silent-staleness bug: if the partner's export is late or fails, a naive job that just re-reads "the file at this path" will happily reprocess yesterday's data with no error at all.
- Landing all three sources into a shared raw schema is good for maintainability, but resist the temptation to also force them into the SAME refresh cadence in that shared layer; an artificial "we refresh everything hourly" schedule either wastes effort re-polling a nightly file source or under-serves the event source's real freshness.
- Do not let "keep it maintainable" become an excuse to over-engineer a generic pluggable-connector framework for just three sources; isolating each connector's code is enough, a fully abstracted framework is a cost worth paying only once you have many more sources than three.
Walk through the trade-offs between using a managed connector platform (for example Fivetran or Stitch) and building a custom connector for a source system. Cover maintenance burden, SLA guarantees, feature flexibility, observability, cost, security, and how quickly you can onboard a new source with each option.
Sample Answer
Direct answer
A managed connector platform trades money and some flexibility for speed and reduced operational ownership: you get a source live in hours, someone else watches it for schema drift and API changes, and you pay per row or per connector. A custom-built connector trades that speed for control: you can implement exactly the extraction semantics, retry policy, and enrichment your source needs, at the cost of building and then owning that code forever. The decision usually turns on how standard the source is, how differentiated your requirements are, and whether the team has the bandwidth to be a long-term connector maintainer.
Structured elaboration
When a managed platform wins
- The source is a common, well-supported SaaS system (a CRM, an ad platform, a payment processor); the vendor has almost certainly already solved pagination, rate limits, and incremental sync for it.
- Time-to-value matters more than customization: a managed connector can often be live same-day, versus days or weeks to build and test a custom one.
- The team does not want to be paged when the vendor changes an API version; that becomes the platform's problem, covered by their service-level agreement (SLA).
- Observability is built in (sync history, row counts, failure alerts) rather than something you instrument yourself.
When building your own wins
- The source is proprietary, internal, or unusual enough that no vendor supports it.
- You need extraction logic a generic connector cannot express: a specific incremental key, in-flight enrichment, or a non-standard authentication flow.
- Per-row or per-connector pricing becomes expensive at your volume, and you have the engineering capacity to absorb the ongoing maintenance cost instead.
- You need tighter control over exactly when and how retries happen, for example to coordinate with a downstream system's own rate limits.
Security
- A managed platform holds your source credentials (API keys, OAuth tokens) inside its own infrastructure: you are trusting its security posture, breach history, and compliance certifications (SOC 2, ISO 27001) rather than controlling storage yourself, and a breach on the vendor's side can expose every customer's credentials at once, not just yours.
- A custom connector puts credential storage and rotation entirely in your own hands: you control exactly where secrets live and who can access them, but you also own getting it right, and a quickly-built connector with a hardcoded API key or an over-scoped database user is a common, self-inflicted vulnerability.
- Vendor access is itself a security surface worth evaluating: a managed platform typically needs broad read access to the source system to support every customer's use case, so check what scope it actually requests, not just whether the connection to it is encrypted.
What "total cost of ownership" actually includes
- Managed: subscription or usage-based fees, which usually scale with data volume or row count and can become the dominant line item as you grow.
- Custom: engineer time to build, test, and then maintain the connector indefinitely, including reacting every time the source's API changes, which the vendor would otherwise absorb for you.
- Both: someone has to own incident response when the sync silently stops; a managed platform's SLA defines a target for how fast THEY notice and fix it, while a custom connector's on-call rotation is your own.
Worked example
A 40-person startup needs to pull from Salesforce, Stripe, and a home-grown inventory service into its warehouse. Salesforce and Stripe are both extremely well-trodden managed-connector sources with mature incremental-sync support, so building custom connectors for those two would mostly be reinventing pagination and rate-limit handling the vendor already solved; a managed platform is the clear choice there. The inventory service has no public connector because it is internal, so there is no "managed" option to compare against: it has to be a custom connector regardless of preference. The decision is not really "managed versus custom" as a blanket policy, it is a per-source decision, and most real integration platforms end up as a mix of both.
Trade-offs & pitfalls
- Vendor lock-in is real: switching platforms later means re-validating every connector's field mappings and historical sync behavior, not just flipping a config flag.
- A managed connector's incremental-sync logic is usually a black box; when a sync silently drops rows, you are debugging through the vendor's support queue rather than reading your own code.
- Building custom "to save money" without counting the ongoing maintenance burden is a common and expensive mistake: the true cost is the sum of every future hour spent reacting to the source's API changes, not just the initial build.
- Watch for hidden coupling: a custom connector built by one engineer who then leaves becomes an unmaintained single point of failure faster than most teams expect.
Unlock Full Question Bank
Get access to all 9 Data Ingestion and Source System Integration interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.