Katkat

Design an async API with idempotency

AirtableSoftware Engineer · Onsite

Last updated

This question tests the ability to design a distributed asynchronous processing system that ensures idempotency, data consistency, and reliable task execution under high concurrency.

System Design: Async Data Processing API

Design a service that allows users to trigger long-running data transformation jobs (e.g., resizing large images or generating complex reports) via an HTTP API.

Functional Requirements

  1. POST /jobs: Submit a task. The API should return a 202 Accepted status with a job_id immediately.
  2. GET /jobs/{job_id}: Retrieve the current status (pending, processing, completed, failed) and the result if finished.
  3. Idempotency: If a client sends the same request multiple times due to network retries, the system must ensure only one job is created and processed.

Non-Functional Requirements

  • The system must handle up to 1,000 requests per second.
  • Jobs are long-running (seconds to minutes).
  • The system must be resilient to worker failures and service restarts.

Deliverables

  • Describe the API contract and data model.
  • Outline the flow of a request from submission to final state update.
  • Explain the mechanism used to guarantee idempotency.
  • Detail how you handle worker failures and retries without causing duplicate side effects.
  • Discuss the storage strategy for job metadata and status updates.

Hints

Hint 1

Consider using an idempotency key sent by the client in the request header to uniquely identify operations.

Hint 2

Decouple the API layer from the processing layer using a distributed message queue (e.g., Kafka or RabbitMQ) to manage job distribution.

Hint 3

Use a transactional pattern in your database (like a 'status' check-and-set or a unique index on the idempotency key) to prevent race conditions during job submission.

Follow-up questions

  • How would you handle a scenario where a worker crashes midway through a job?
  • How would you implement a cleanup process for old job records to prevent the database from growing indefinitely?
  • What changes would be required if the processing order of jobs mattered (e.g., sequential execution per user)?