PracHub
QuestionsLearningGuidesInterview Prep
|Home/System Design/eBay

Design an Ad Assignment API

Last updated: Jun 17, 2026

Quick Overview

This question evaluates a candidate's skill in designing stateful, production-grade HTTP APIs and reasoning about distributed-systems concerns such as idempotency, concurrency control, per-user state management, and observability.

  • medium
  • eBay
  • System Design
  • Software Engineer

Design an Ad Assignment API

Company: eBay

Role: Software Engineer

Category: System Design

Difficulty: medium

Interview Round: Technical Screen

Design an HTTP API that exposes an **ad-assignment function** as a production service. The underlying function is given a user, a list of browser **positions** (page slots such as `top`, `sidebar`, `bottom`), and a set of **candidate ads**. It must **randomly** assign eligible ads to positions so that, when there are enough ads, no ad repeats across positions and no ad exceeds its configured **per-user display limit** (frequency cap). The function returns the assignment and updates the user's per-ad display-count state. Your task is to turn this function into a real HTTP service: define the contract (endpoint, method, URL, schemas), decide where the per-user display state lives, make concurrent updates for the same user correct, and make the service reliable, observable, and maintainable. You do **not** need to write the assignment algorithm itself — focus on the API and the system around it. Concretely, address: 1. What endpoint(s) you expose, and whether you use REST, RPC/gRPC, or another protocol — with the reason. 2. Which HTTP method generates an assignment, and what the URL design looks like. 3. The request and response schemas (including how unfilled positions are represented). 4. Where per-user, per-ad display state is stored, and why that store fits an ad-serving workload. 5. How you keep frequency-cap enforcement correct under concurrent requests for the same user. 6. How you make retries safe given that assignment mutates state. 7. The error surface the API exposes to clients. 8. How you make the service reliable, observable, and maintainable. ```hint Frame the operation first Before choosing any verb or store, settle one question: is this fundamentally a read or a write? Look at what the call *does* to the world and whether calling it twice with identical input is guaranteed to behave the same way. How you answer this shapes the HTTP method, the retry story, and the concurrency design — so reason it through before moving on. ``` ```hint Method and URL A *safe* or *idempotent* verb fits operations that don't change state or that converge to the same result on repeat. Ask which of those properties this operation actually has, and which it lacks. Then think about how a client can still retry safely after a timeout without you weakening the verb's meaning. ``` ```hint Concurrency correctness Two concurrent requests can both read `count = limit - 1`, both decide the ad is under cap, and both assign it — pushing it to `limit + 1`. The bug is that the *check* and the *write* are separable steps that can interleave. What would let the store treat "verify it's under cap, then bump it" as one uninterruptible operation? Weigh that against coarser approaches (serializing a user's requests, or grouping the writes) and what each costs in latency and hot-key contention. ``` ```hint State store choice The hot path needs a fast lookup of "how many times has *this* user seen *this* ad," cheap increments, and ideally automatic expiry so caps can reset over a window. Think about what shape of lookup key that implies, and which class of store gives you that access pattern plus horizontal scale at ad-serving QPS. ``` ### Constraints & Assumptions State the assumptions you are designing against; reasonable defaults (confirm with your interviewer): - **Candidate ads are supplied per request** by an upstream targeting/ranking system; your service does not rank them, it only assigns and caps. - **Per-user, per-ad display limit** must be enforced exactly — exceeding a cap is a correctness bug, not just a quality issue. - A single user can have **multiple in-flight requests** (multiple tabs / fast reloads / client retries). - Assume web and backend clients both call the service; treat it as a high-QPS ad-serving path where read/write latency on the state store matters. ### Clarifying Questions to Ask - Are candidate ads always passed in the request, or should the service fetch them from an internal candidate service given only context? - Over what window does the per-user display limit apply — lifetime, per day, per session — and does that imply a TTL? - If no eligible ad exists for a position, should that position be left empty (partial assignment) or should the whole request fail? - What are the latency/QPS targets, and is this an externally exposed endpoint or an internal service-to-service call? - Who calls the API — trusted internal services or untrusted external clients? That changes whether you accept `candidateAds`/limits from the body at all. - Do downstream systems (billing, analytics, fraud) need a durable record of every impression, or is the response enough? ### What a Strong Answer Covers - Correctly classifies the operation as a non-idempotent, side-effecting write and chooses the HTTP method to match. - A clean, consistent resource/URL design with a self-contained or user-scoped path, justified rather than asserted. - Request/response schemas that are explicit, including a clear representation for **unfilled** positions (not a silent omission). - A state model (key design, store class, TTL) suited to high-QPS frequency capping, with the reasoning for the store choice. - A concurrency story that actually prevents cap violations (atomic conditional increment vs. transaction vs. lock) with trade-offs named. - An idempotency mechanism so retries don't double-count impressions. - A pragmatic error taxonomy that separates transport/auth/validation errors from business outcomes like "no eligible ad." - Observability and reliability: metrics, structured logging, durable impression events, and graceful degradation when the store is unavailable. ### Follow-up Questions - How do you enforce a *time-windowed* cap (e.g. "max 3 impressions per day") rather than a lifetime count? What changes in the store and the increment? - The state store goes down on the hot path. Do you fail closed (no ads), fail open (serve and reconcile later), or degrade — and how do you avoid double-counting when it recovers? - A single very active user becomes a hot key/partition. How do you keep their requests fast without serializing them all? - How do you guarantee billing and analytics see exactly the impressions that were actually served, even across retries and partial failures?

Quick Answer: This question evaluates a candidate's skill in designing stateful, production-grade HTTP APIs and reasoning about distributed-systems concerns such as idempotency, concurrency control, per-user state management, and observability.

Related Interview Questions

  • Design a Relational-to-DynamoDB Migration System - eBay (medium)
  • Design a Top-K trending service - eBay (medium)
  • Design an online marketplace for buying and selling - eBay (hard)
  • Handle cache-update conflicts in distributed services - eBay (hard)
|Home/System Design/eBay

Design an Ad Assignment API

eBay logo
eBay
Apr 13, 2026, 12:00 AM
mediumSoftware EngineerTechnical ScreenSystem Design
29
0

Design an HTTP API that exposes an ad-assignment function as a production service.

The underlying function is given a user, a list of browser positions (page slots such as top, sidebar, bottom), and a set of candidate ads. It must randomly assign eligible ads to positions so that, when there are enough ads, no ad repeats across positions and no ad exceeds its configured per-user display limit (frequency cap). The function returns the assignment and updates the user's per-ad display-count state.

Your task is to turn this function into a real HTTP service: define the contract (endpoint, method, URL, schemas), decide where the per-user display state lives, make concurrent updates for the same user correct, and make the service reliable, observable, and maintainable. You do not need to write the assignment algorithm itself — focus on the API and the system around it. Concretely, address:

  1. What endpoint(s) you expose, and whether you use REST, RPC/gRPC, or another protocol — with the reason.
  2. Which HTTP method generates an assignment, and what the URL design looks like.
  3. The request and response schemas (including how unfilled positions are represented).
  4. Where per-user, per-ad display state is stored, and why that store fits an ad-serving workload.
  5. How you keep frequency-cap enforcement correct under concurrent requests for the same user.
  6. How you make retries safe given that assignment mutates state.
  7. The error surface the API exposes to clients.
  8. How you make the service reliable, observable, and maintainable.

Constraints & Assumptions

State the assumptions you are designing against; reasonable defaults (confirm with your interviewer):

  • Candidate ads are supplied per request by an upstream targeting/ranking system; your service does not rank them, it only assigns and caps.
  • Per-user, per-ad display limit must be enforced exactly — exceeding a cap is a correctness bug, not just a quality issue.
  • A single user can have multiple in-flight requests (multiple tabs / fast reloads / client retries).
  • Assume web and backend clients both call the service; treat it as a high-QPS ad-serving path where read/write latency on the state store matters.

Clarifying Questions to Ask Guidance

  • Are candidate ads always passed in the request, or should the service fetch them from an internal candidate service given only context?
  • Over what window does the per-user display limit apply — lifetime, per day, per session — and does that imply a TTL?
  • If no eligible ad exists for a position, should that position be left empty (partial assignment) or should the whole request fail?
  • What are the latency/QPS targets, and is this an externally exposed endpoint or an internal service-to-service call?
  • Who calls the API — trusted internal services or untrusted external clients? That changes whether you accept candidateAds /limits from the body at all.
  • Do downstream systems (billing, analytics, fraud) need a durable record of every impression, or is the response enough?

What a Strong Answer Covers Guidance

  • Correctly classifies the operation as a non-idempotent, side-effecting write and chooses the HTTP method to match.
  • A clean, consistent resource/URL design with a self-contained or user-scoped path, justified rather than asserted.
  • Request/response schemas that are explicit, including a clear representation for unfilled positions (not a silent omission).
  • A state model (key design, store class, TTL) suited to high-QPS frequency capping, with the reasoning for the store choice.
  • A concurrency story that actually prevents cap violations (atomic conditional increment vs. transaction vs. lock) with trade-offs named.
  • An idempotency mechanism so retries don't double-count impressions.
  • A pragmatic error taxonomy that separates transport/auth/validation errors from business outcomes like "no eligible ad."
  • Observability and reliability: metrics, structured logging, durable impression events, and graceful degradation when the store is unavailable.

Follow-up Questions Guidance

  • How do you enforce a time-windowed cap (e.g. "max 3 impressions per day") rather than a lifetime count? What changes in the store and the increment?
  • The state store goes down on the hot path. Do you fail closed (no ads), fail open (serve and reconcile later), or degrade — and how do you avoid double-counting when it recovers?
  • A single very active user becomes a hot key/partition. How do you keep their requests fast without serializing them all?
  • How do you guarantee billing and analytics see exactly the impressions that were actually served, even across retries and partial failures?

Submit Your Answer to Earn 20XP

Sign in to leave a comment

Loading comments...

Browse More Questions

More System Design•More eBay•More Software Engineer•eBay Software Engineer•eBay System Design•Software Engineer System Design

Your design canvas — auto-saved

PracHub

Master your tech interviews with 8,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.