← Openai Interview Insights

Openai·Software Engineer·Onsite - System Design / Architecture·Senior

SeniorPrefer not to say
May 2026

Summary

System design round at OpenAI for a SWE role, focused entirely on building a webhook delivery system at massive scale. The interview went deep on failure handling and retry logic, which I was not fully prepared for.

Questions Asked (6)

Q1

Design a webhook delivery system that handles 1 billion events per day with at-least-once delivery guarantees, retry logic, and failure isolation.

System DesignTechnical Trade-offs
Author's notes

I started with the API surface and database schema which felt safe, but the interviewer kept pushing toward the delivery pipeline.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements and scale (1B events/day ≈ 11.6K events/sec average, with peaks). Then propose a decoupled, partitioned architecture using a message queue for buffering and worker pools for delivery, with per-endpoint isolation and retry queues. Finally, discuss trade-offs around delivery guarantees, retry strategies, and failure handling.

Pro tip: Emphasize idempotency and deduplication on the consumer side, since at-least-once delivery means duplicates are inevitable. Also, mention that you'd use a dead-letter queue for poison messages and monitor retry rates to detect systemic issues.

1. Clarify Requirements and Scale

Ask about event size, peak-to-average ratio, latency expectations, and endpoint diversity. Calculate throughput (e.g., 1B/day ≈ 11.6K/sec average, but peaks could be 10x).

2. High-Level Architecture

Propose an ingestion layer (API/gateway) that writes events to a durable, partitioned log (e.g., Kafka). Then a delivery service consumes from the log, groups by endpoint, and dispatches via HTTP with retries.

3. Delivery Guarantees and Retry Logic

Explain how to achieve at-least-once: persist events before acknowledging, use a retry queue with exponential backoff and jitter, and track delivery attempts. Ensure idempotency keys to handle duplicates.

4. Failure Isolation and Scalability

Isolate failures per endpoint using separate queues/partitions and circuit breakers. Scale horizontally by adding consumers; use sharding to distribute load. Implement dead-letter queues for persistent failures.

5. Monitoring and Trade-offs

Discuss monitoring (retry rates, latency, queue depth), and trade-offs like at-least-once vs exactly-once, synchronous vs asynchronous delivery, and cost vs reliability.

Key Points to Mention

  • Partitioning by endpoint or event key to ensure ordering and isolation
  • Idempotency and deduplication strategies on the consumer side
  • Exponential backoff with jitter for retries, and max retry limits
  • Dead-letter queue for poison messages and manual intervention
  • Circuit breakers to prevent cascading failures to unhealthy endpoints
  • Horizontal scaling of delivery workers and use of a distributed queue like Kafka or SQS

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

How would you design the REST API for registering webhooks and querying delivery history, including filtering and pagination?

API & IntegrationsSystem Design
Author's notes

Pretty straightforward.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements such as event types, delivery guarantees, and expected query patterns. Then design the REST endpoints for webhook registration and delivery history, focusing on resource modeling, filtering, and pagination. Finally, discuss trade-offs and operational considerations like idempotency, security, and scalability.

Pro tip: Emphasize idempotency and security from the start—use idempotency keys for registration and HMAC signatures for payloads. Also, mention cursor-based pagination for delivery history to ensure stable results under high write loads.

1. Clarify Requirements

Ask about event types, delivery guarantees (at-least-once vs. exactly-once), expected volume, and query patterns (e.g., filtering by status, date range).

2. Design Registration Endpoints

Define POST /webhooks for creating a webhook with URL, secret, and event subscriptions. Include GET /webhooks/{id}, PUT/PATCH for updates, and DELETE for removal.

3. Design Delivery History Endpoints

Define GET /webhooks/{id}/deliveries with query parameters for filtering (status, event type, date range) and pagination (cursor-based).

4. Specify Filtering and Pagination

Use query parameters like ?status=failed&event_type=user.created&start_date=...&end_date=...&limit=50&cursor=... for flexible querying.

5. Address Operational Concerns

Discuss idempotency, security (HMAC signatures), rate limiting, retry policies, and monitoring for webhook deliveries.

Key Points to Mention

  • Use idempotency keys for webhook registration to prevent duplicate webhooks.
  • Implement HMAC signatures for payload verification and secure secret storage.
  • Adopt cursor-based pagination for delivery history to handle large datasets and avoid offset inefficiencies.
  • Support filtering by delivery status, event type, and timestamp range.
  • Design for retries with exponential backoff and dead-letter queues for failed deliveries.
  • Consider rate limiting and monitoring to ensure reliability and observability.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

Walk me through your database schema for storing webhooks and delivery records. How do you enforce the one-event-per-user constraint and handle sharding at scale?

Data ModelingSystem Design
Author's notes

The unique constraint on user_id and event_id was easy.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by outlining the core tables (webhooks and delivery records) and their relationships, then explain how you enforce the one-event-per-user constraint using a unique index on (user_id, event_id). Finally, discuss sharding strategies such as sharding by user_id or event_id, and how you handle cross-shard queries and rebalancing.

Pro tip: Mention that you would use a composite unique index on (user_id, event_id) to enforce the constraint at the database level, and consider using a distributed SQL database like CockroachDB or Vitess for automatic sharding to avoid manual rebalancing complexity.

1. Define the schema

Describe the webhooks table (id, user_id, event_type, payload, created_at) and delivery_records table (id, webhook_id, status, attempt_count, last_attempt_at, response_code). Explain the one-to-many relationship.

2. Enforce one-event-per-user

Explain that a unique constraint on (user_id, event_id) in the webhooks table ensures only one webhook per event per user. Mention handling duplicate inserts with upsert or ignoring conflicts.

3. Choose a sharding key

Discuss sharding by user_id to keep a user's data together, or by event_id for even distribution. Explain trade-offs: user_id simplifies per-user queries but may cause hotspots; event_id distributes load but complicates per-user queries.

4. Handle cross-shard operations

Describe how to handle queries that span shards, such as fetching all deliveries for a user. Mention using a global index, scatter-gather, or a separate lookup table.

5. Address scaling and rebalancing

Explain how to add shards (consistent hashing, range-based sharding) and rebalance data. Mention monitoring shard size and using tools like Vitess or Citus for automation.

Key Points to Mention

  • Unique composite index on (user_id, event_id) to enforce one-event-per-user
  • Sharding by user_id vs event_id and their trade-offs
  • Use of distributed SQL databases (e.g., CockroachDB, Vitess) for automatic sharding
  • Handling duplicate webhook deliveries with idempotency keys
  • Cross-shard query strategies: scatter-gather, global secondary indexes
  • Rebalancing and adding shards without downtime

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q4

What would you cache in this system and how would you handle cache invalidation when a webhook is updated or deleted?

System DesignTechnical Trade-offs
Author's notes

Cache the webhook config keyed by event_id, TTL of a few minutes, invalidate on write.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the system's read/write patterns and consistency requirements, then identify cacheable entities like webhook configurations and event payloads. Explain your caching strategy with appropriate TTLs and invalidation mechanisms, emphasizing how you handle updates and deletions to maintain consistency.

Pro tip: Mention that cache invalidation should be event-driven, using the webhook update/delete events themselves to trigger invalidation, and consider using a versioned cache key to avoid stale reads during concurrent updates.

1. Clarify requirements and access patterns

Ask about read/write ratio, consistency needs, and latency requirements to determine what to cache and for how long.

2. Identify cacheable data

List entities such as webhook configurations, event payloads, and authentication tokens that are frequently read and infrequently changed.

3. Choose caching strategy

Decide between write-through, write-behind, or cache-aside, and set TTLs based on data volatility and consistency requirements.

4. Design invalidation on update/delete

Use event-driven invalidation: when a webhook is updated or deleted, publish an event to invalidate or update the cache entry, possibly using a versioned key.

5. Handle edge cases and failures

Address race conditions, cache stampedes, and failure modes like cache unavailability, ensuring graceful degradation.

Key Points to Mention

  • Cache webhook configurations and event payloads with appropriate TTLs
  • Use event-driven invalidation triggered by webhook update/delete events
  • Implement versioned cache keys to avoid stale reads during concurrent updates
  • Consider cache-aside pattern with lazy loading for read-heavy workloads
  • Handle cache stampede with locking or probabilistic early expiration
  • Ensure idempotency and ordering of invalidation events to prevent inconsistencies

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q5

How would you implement retry logic for failed webhook deliveries, including backoff strategy, distinguishing error types, and preventing one slow subscriber from blocking others?

System DesignTechnical Trade-offs
Author's notes

This was the real meat of the interview and where I spent the most time.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Structure your answer around a reliable, scalable webhook delivery system: start by acknowledging the need for retries with exponential backoff and jitter, then explain how to classify errors (transient vs. permanent) to decide retry eligibility, and finally describe an asynchronous, decoupled architecture (e.g., message queues with per-subscriber isolation) to prevent slow subscribers from blocking others. Emphasize trade-offs like retry limits, dead-letter queues, and monitoring.

Pro tip: Show maturity by discussing idempotency and delivery guarantees—mention that retries can cause duplicate deliveries, so you'd include a unique event ID and encourage subscribers to deduplicate. Also, highlight the importance of observability (metrics, logs, alerts) to detect systemic issues and tune retry policies.

1. Clarify requirements and constraints

Ask about expected delivery guarantees (at-least-once vs. exactly-once), scale (events per second, number of subscribers), and latency tolerance. This shows you tailor solutions to context.

2. Design retry mechanism with backoff

Propose exponential backoff with jitter to avoid thundering herd, set a maximum retry count or time window, and use a dead-letter queue for persistent failures. Mention that retries should be asynchronous.

3. Classify errors for retry decisions

Distinguish transient errors (e.g., 5xx, timeouts, network issues) from permanent ones (e.g., 4xx like 400, 401, 404). Only retry transient errors; for permanent errors, log and alert without retrying.

4. Isolate subscribers to prevent blocking

Use a message queue per subscriber or a worker pool with concurrency limits, so a slow subscriber doesn't consume shared resources. Implement circuit breakers to pause delivery to failing subscribers.

5. Ensure idempotency and observability

Include a unique event ID in payloads and document that subscribers should deduplicate. Add metrics (success/failure rates, retry counts), logging, and alerting to monitor system health and adjust policies.

Key Points to Mention

  • Exponential backoff with jitter to avoid synchronized retries
  • Error classification: retry only transient failures (5xx, timeouts), not permanent ones (4xx)
  • Asynchronous processing with message queues (e.g., Kafka, RabbitMQ, SQS) for decoupling
  • Per-subscriber isolation via separate queues or worker pools to prevent head-of-line blocking
  • Dead-letter queue for failed deliveries after max retries
  • Idempotency keys and at-least-once delivery semantics to handle duplicates
  • Circuit breakers and rate limiting to protect the system from slow or failing subscribers
  • Observability: metrics, logging, and alerting for retry attempts and failures

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q6

How do you prevent SSRF attacks when making outbound HTTP requests to user-supplied callback URLs, and how would you implement payload signing for subscribers?

System DesignAPI & Integrations
Author's notes

SSRF came up and I gave the standard answer about blocklisting internal IP ranges and validating URLs before dispatch.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by outlining a defense-in-depth strategy for SSRF: validate and resolve URLs, enforce network-level restrictions, and monitor for anomalies. Then explain how to implement payload signing using HMAC with a shared secret, including timestamping and signature verification on the subscriber side.

Pro tip: Emphasize that SSRF prevention is not just about input validation but also about network segmentation and egress filtering, and that payload signing should include a timestamp to prevent replay attacks.

1. Validate and sanitize callback URLs

Ensure the URL uses HTTPS, has a valid domain, and does not point to internal IPs or metadata endpoints. Use a whitelist of allowed domains if possible.

2. Resolve and inspect the destination IP

Resolve the hostname to an IP and check it against a blocklist of private, loopback, link-local, and reserved IP ranges. Re-resolve after redirects to prevent DNS rebinding.

3. Enforce network-level controls

Use a dedicated egress proxy or firewall to restrict outbound requests to only necessary ports and external IPs. Isolate the service making requests to limit blast radius.

4. Implement payload signing with HMAC

Generate a signature using HMAC-SHA256 over the payload and a timestamp, using a shared secret unique to each subscriber. Include the signature and timestamp in headers.

5. Provide verification guidance and handle failures

Document how subscribers should verify the signature and reject requests with invalid signatures or expired timestamps. Log and alert on verification failures.

Key Points to Mention

  • DNS rebinding and TOCTOU attacks
  • Allowlist vs blocklist for domains and IPs
  • Network segmentation and egress filtering
  • HMAC-SHA256 for signing, with a per-subscriber secret
  • Timestamp inclusion to prevent replay attacks
  • Idempotency keys and retry mechanisms for reliability

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.