← Openai Interview Insights

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

Senior
May 2026

Summary

System design round at OpenAI for a software engineering role. The whole thing was basically one long deep-dive into a key-value store, starting from a simple single-file design and getting progressively messier with multi-file storage, concurrency, and crash recovery. Pretty intense but not unfair.

Questions Asked (6)

Q1

You have a basic persistent key-value store with put, get, and delete operations backed by a single append-only file and an in-memory index. Extend it to support multiple size-capped data files with rollover.

System DesignTechnical Trade-offs
Author's notes

This is where most of the time went.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements and constraints (file size cap, rollover policy, read/write patterns). Then describe the design: maintain an in-memory index mapping keys to (file_id, offset), write to the active file until it reaches the cap, then roll over to a new file. Explain how reads, deletes, and compaction work across multiple files, and discuss trade-offs like index size, file management, and recovery.

Pro tip: Emphasize that the in-memory index must track file IDs and offsets, and that deletes can be handled with tombstones or by removing index entries; also mention that compaction is essential to reclaim space from stale data.

1. Clarify requirements and constraints

Ask about expected workload (read/write ratio, key size, value size), file size cap, durability guarantees, and whether concurrent access is needed. This shows you think before designing.

2. Design the file rollover mechanism

Describe how to track the active file size and switch to a new file when the cap is reached. Ensure atomicity: write to the new file first, then update the active file pointer, and handle crashes during rollover.

3. Extend the in-memory index

Modify the index to store file ID and offset for each key. For deletes, either remove the index entry (if no compaction) or write a tombstone and mark the key as deleted.

4. Handle reads and deletes across files

For get, look up the index to find the file and offset, then read the value. For delete, update the index and optionally write a tombstone to the active file for durability.

5. Discuss compaction and recovery

Explain how to merge files to remove stale data and reclaim space, and how to rebuild the index on startup by scanning all files. Mention trade-offs like compaction frequency and impact on performance.

Key Points to Mention

  • In-memory index must map keys to (file_id, offset) to locate values across multiple files.
  • Rollover policy: when active file reaches size cap, close it and open a new file for writes.
  • Deletes can be handled with tombstones or by removing index entries; tombstones ensure durability but require compaction.
  • Compaction merges files, removes stale data, and updates the index; it can be done in the background to avoid blocking.
  • Crash recovery: on startup, scan all files to rebuild the in-memory index, ignoring tombstones for deleted keys.
  • Trade-offs: more files increase index size and file handle usage; compaction improves read performance but consumes I/O.

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

Q2

How would you handle compaction across multiple files in this design?

System DesignTechnical Trade-offs
Author's notes

Talked about scanning old immutable files, dropping tombstoned and overwritten keys, and writing surviving records into a new compacted file.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the context: what system is this (e.g., LSM-tree, data lake, distributed storage), what are the files, and what are the compaction goals (read/write amplification, latency, cost). Then outline a strategy that balances trade-offs, such as tiered vs. leveled compaction, and discuss how to coordinate across files (e.g., using manifests, background jobs, and concurrency control).

Pro tip: Emphasize that compaction is not just a background task but a critical part of the system's performance and reliability; discuss how you would monitor and tune it based on workload patterns, and mention real-world examples like RocksDB or Delta Lake to show practical knowledge.

1. Clarify the System and Requirements

Ask questions to understand the system architecture, file formats, and compaction goals (e.g., reduce read amplification, reclaim space, improve query performance). Identify constraints like latency SLAs, throughput, and cost.

2. Choose a Compaction Strategy

Discuss common strategies (e.g., size-tiered, leveled, time-windowed) and justify your choice based on the workload. Explain how the strategy handles multiple files, such as merging overlapping ranges or consolidating small files.

3. Design the Compaction Process

Describe how compaction is triggered (e.g., file count, size thresholds), how files are selected, and how the merge is executed (e.g., streaming, multi-threaded). Address concurrency: how to avoid conflicts with reads/writes and ensure atomicity.

4. Handle Metadata and Consistency

Explain how to update metadata (e.g., manifests, catalogs) atomically after compaction, and how to handle failures (e.g., rollback, retries). Ensure that readers see a consistent view during and after compaction.

5. Monitor and Tune

Discuss metrics to track (e.g., compaction latency, write amplification, space amplification) and how to tune parameters (e.g., fan-out, thresholds) based on observed performance. Mention the importance of adaptive strategies.

Key Points to Mention

  • Trade-offs between read, write, and space amplification
  • Tiered vs. leveled compaction and when to use each
  • Concurrency control and isolation during compaction
  • Atomic metadata updates and crash recovery
  • Impact on query performance and latency
  • Real-world systems like RocksDB, LevelDB, or Delta Lake

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

Q3

Make the store safe for concurrent reads and writes. What locking strategy would you use?

System DesignTechnical Trade-offs
Author's notes

RWMutex felt obvious and I said so pretty quickly.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the store's characteristics (in-memory vs. persistent, read/write ratio, data size) and the consistency requirements. Then propose a locking strategy that balances concurrency and correctness, such as reader-writer locks with fine-grained sharding, and discuss trade-offs like contention, scalability, and deadlock avoidance.

Pro tip: Demonstrate awareness of lock-free or optimistic concurrency techniques (e.g., MVCC, CAS) as alternatives when contention is high, and mention that the best choice depends on the specific workload and performance goals.

1. Clarify requirements and constraints

Ask about the store's data structure, read/write ratio, latency requirements, and consistency model to tailor the locking strategy.

2. Identify concurrency challenges

Discuss potential issues like race conditions, deadlocks, and contention hotspots that any locking strategy must address.

3. Propose a locking strategy

Recommend a specific approach, such as reader-writer locks, sharded locks, or optimistic concurrency, and explain how it handles concurrent reads and writes.

4. Analyze trade-offs

Compare the proposed strategy with alternatives in terms of performance, scalability, complexity, and fairness.

5. Summarize and justify

Conclude with the recommended strategy, justifying it based on the clarified requirements and trade-off analysis.

Key Points to Mention

  • Reader-writer locks allow multiple concurrent readers but exclusive writers, improving read-heavy workloads.
  • Fine-grained locking (e.g., per-bucket or per-key locks) reduces contention compared to a single global lock.
  • Optimistic concurrency control (e.g., versioning, CAS) can avoid locks entirely for low-contention scenarios.
  • Lock-free data structures (e.g., using atomic operations) offer high scalability but are complex to implement correctly.
  • Deadlock prevention techniques: lock ordering, timeouts, or try-lock patterns.
  • Consider using existing concurrent data structures (e.g., ConcurrentHashMap in Java, sync.Map in Go) to avoid reinventing the wheel.

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

Q4

How do you make the in-memory index durable across restarts? What are the tradeoffs between rebuilding from scratch versus persisting a snapshot?

System DesignTechnical Trade-offs
Author's notes

Full rebuild by scanning all files is simple but slow if you have a lot of data.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the requirements: index size, update frequency, acceptable recovery time, and consistency needs. Then compare rebuilding from scratch versus persisting snapshots, discussing tradeoffs in recovery time, resource usage, and complexity. Conclude with a hybrid approach that balances these factors, such as periodic snapshots plus incremental logs.

Pro tip: Quantify the tradeoffs with concrete numbers (e.g., 'rebuilding a 10GB index takes 30 minutes, while loading a snapshot takes 2 minutes') to show you think in terms of real-world impact. Also, mention that the choice depends on the specific use case and SLAs.

1. Clarify requirements and constraints

Ask about index size, update rate, acceptable downtime, consistency requirements, and available storage. This ensures your answer is tailored to the scenario.

2. Explain rebuilding from scratch

Describe how the index can be rebuilt from the source of truth (e.g., database, logs) on startup. Highlight pros: simplicity, no extra storage, always up-to-date. Cons: slow recovery, high resource usage during rebuild, potential impact on source system.

3. Explain persisting a snapshot

Describe periodically serializing the index to disk (or object storage) and loading it on restart. Highlight pros: fast recovery, low startup cost. Cons: storage overhead, snapshot staleness, need for consistency mechanisms (e.g., write-ahead log) to capture updates since last snapshot.

4. Compare tradeoffs and propose a hybrid approach

Discuss tradeoffs in terms of recovery time, resource usage, complexity, and consistency. Propose a hybrid: periodic snapshots plus incremental updates (e.g., WAL) to balance recovery speed and freshness.

5. Address operational concerns

Mention monitoring, snapshot validation, versioning, and handling failures during snapshot/load. Also consider incremental snapshots and compression to reduce overhead.

Key Points to Mention

  • Recovery Time Objective (RTO) and Recovery Point Objective (RPO) to frame tradeoffs
  • Snapshot frequency and incremental snapshots to reduce storage and time
  • Write-ahead logging (WAL) or change data capture (CDC) to capture updates between snapshots
  • Consistency guarantees: atomic snapshot creation, point-in-time recovery
  • Resource utilization: CPU, memory, I/O during rebuild vs. snapshot load
  • Operational complexity: automation, monitoring, and failure recovery

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

Q5

How should the compactor run without blocking readers, and how do you safely swap in the new compacted file?

System DesignAdaptability & Ambiguity
Author's notes

Said the compactor runs as a background goroutine, reads only from immutable files so it doesn't need a write lock for most of its work.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the system context—what kind of storage engine, file format, and reader/writer concurrency model you're dealing with. Then describe a design that separates the compactor's write path from readers (e.g., append-only segments, immutable files, or MVCC) and explain an atomic swap mechanism (e.g., atomic rename, versioned manifests, or reference counting) that ensures readers never see a partially compacted state. Finally, discuss trade-offs like space amplification, latency, and failure recovery.

Pro tip: Emphasize that the swap must be atomic and crash-safe—use a compare-and-swap on a metadata pointer or an atomic rename, and ensure old files are only deleted after all readers have drained. Mentioning real-world systems like LSM-trees or Delta Lake shows practical depth.

1. Clarify the system and constraints

Ask about the storage layer (e.g., LSM-tree, columnar files), read/write patterns, and consistency requirements. This shows you avoid assumptions and tailor the solution.

2. Design non-blocking compaction

Explain how the compactor writes new files without touching files currently being read—e.g., using immutable segments, a copy-on-write approach, or writing to a separate location. Readers continue using the old snapshot.

3. Implement atomic swap

Describe how to atomically switch readers to the new compacted file: e.g., atomic rename, updating a versioned manifest, or a compare-and-swap on a metadata pointer. Ensure the swap is crash-safe and visible to new readers immediately.

4. Handle in-flight readers and cleanup

Explain how to safely retire old files: use reference counting, epoch-based reclamation, or a grace period. Old files are deleted only after all readers that started before the swap have finished.

5. Discuss trade-offs and failure modes

Cover space amplification (old + new files coexist), latency spikes, and recovery if the compactor crashes mid-swap. Mention monitoring and backpressure to avoid unbounded file accumulation.

Key Points to Mention

  • Immutable files and copy-on-write to avoid blocking readers
  • Atomic metadata update (e.g., atomic rename, versioned manifest, CAS pointer)
  • Reference counting or epoch-based reclamation for safe deletion of old files
  • Crash consistency: write-ahead log or atomic directory operations
  • Space amplification and the need for a grace period before cleanup
  • Real-world examples: LSM-tree compaction, Delta Lake, or Iceberg

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

Q6

How do you detect and recover from a partial write at the tail of a file after a crash?

System DesignTechnical Trade-offs
Author's notes

Length-prefix approach: if the declared length doesn't match the actual bytes remaining, you know the last record is incomplete.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the file system and durability guarantees (e.g., fsync, atomicity), then explain detection mechanisms like checksums or length prefixes, and finally describe recovery strategies such as truncation or rollback. Emphasize trade-offs between performance, complexity, and data loss tolerance.

Pro tip: Mention that many systems use a write-ahead log (WAL) or journal to avoid partial writes altogether, and that the tail problem is often solved by writing a commit record after the data is fully written.

1. Clarify assumptions and requirements

Ask about the file system, storage medium, and durability requirements (e.g., fsync behavior, atomicity of writes). This sets the context for detection and recovery.

2. Explain detection mechanisms

Describe how to detect a partial write, such as using checksums, length prefixes, or sentinel values at the end of each record. Mention that the OS may not guarantee atomicity for writes larger than a sector.

3. Describe recovery strategies

Outline recovery options: truncate the file to the last valid record, roll back to a previous checkpoint, or use a journal/WAL to replay or undo incomplete writes.

4. Discuss trade-offs

Compare approaches in terms of performance overhead, complexity, and data loss. For example, checksums add CPU cost but enable detection; WAL adds write amplification but ensures atomicity.

5. Provide a concrete example

Walk through a simple scenario, such as appending records with a CRC and length, and show how recovery would truncate the partial record.

Key Points to Mention

  • Atomicity of writes: most file systems do not guarantee atomic writes larger than a sector, so partial writes can occur.
  • Checksums (e.g., CRC32) or hashes to detect corruption or incompleteness.
  • Length prefixes or sentinel values to know where a valid record ends.
  • fsync and its role in ensuring data is persisted before acknowledging.
  • Write-ahead logging (WAL) or journaling to avoid partial writes by writing data elsewhere first.
  • Recovery by truncation to the last valid offset, or replaying/undoing from a log.

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