Katkat

Design an Ad Impression Reconciliation and Aggregation Service

MicrosoftSoftware Engineer · Technical Screen

Last updated

This problem tests the ability to design a distributed, idempotent pipeline that reconciles inconsistent event streams into a consistent, aggregated state for billing and analytics.

Problem Statement

Design a reconciliation and aggregation service for an online advertising platform. You receive two streams of data:

  1. Impression Logs: High-volume, raw logs from distributed ad servers. These are prone to duplicates, out-of-order delivery, and occasional missing events.
  2. Authoritative Ledger: A reliable, secondary source (e.g., billing logs) that contains the ground truth of billable impressions, arriving with a latency of 1-4 hours.

Your task is to produce a daily aggregate report per advertiser that counts valid impressions. The system must handle late-arriving data, ensure exactly-once processing semantics for billing, and allow for auditability.

Requirements

  • Deduplication: Raw logs contain duplicates; the system must identify and discard these before aggregation.
  • Reconciliation: If an impression exists in the logs but is not in the ledger, it should be flagged as unverified. If it exists in both, it is confirmed.
  • Idempotency: The service should be safely re-runnable; if a job fails mid-process, re-processing the same window must not lead to double-counting.
  • Scale: The system handles 100k events/second. Storage must account for long-term audit logs.

Output

Describe the high-level architecture. Address:

  • Data ingestion flow and storage choice.
  • The state management strategy for deduplication (e.g., Bloom filters, key-value stores).
  • How the system handles late-arriving data while maintaining accuracy in time-bucketed aggregates.
  • API or messaging interface between the reconciliation and the aggregation services.

Hints

Hint 1

Use a unique `impression_id` generated at the ad-client level to perform deduplication via a distributed key-value store or a persistent log index.

Hint 2

Implement a 'watermark' strategy where the system keeps the processing window open for a grace period (e.g., 6 hours) to accommodate out-of-order events before finalizing a daily bucket.

Hint 3

Consider a Lambda architecture approach where a fast layer provides approximate counts and a batch layer provides the verified, reconciled totals.

Follow-up questions

  • How would you modify the system if the ledger arrived in real-time rather than with a multi-hour delay?
  • What specific database schema or storage format (e.g., Parquet, RocksDB) would you choose to optimize for both read-heavy aggregate queries and high-write ingestion?
  • How do you handle a scenario where an upstream change in the ad-serving logic causes all previous `impression_id` formats to become invalid?