Durable String Key-Value Store
Reported by candidates from OpenAI's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
OpenAI reported this one in July 2026, and the first-attempt killer is sitting right in the format spec. It's a durable string key-value store, a string parsing problem dressed up as systems design. You process PUT, GET, SERIALIZE, DESERIALIZE and RECOVER against a map plus an append-only log. If you're taking this OA in the next day or two, the logic is easy and the bugs are sneaky. Length-prefixed encoding means keys can hold colons and digits, so naive splitting fails. StealthCoder is the safety net if you blank on the parser mid-assessment, but the whole thing is under 60 lines once you see it.
The problem
Implement a durable string key-value store by processing an ordered array of commands. The store starts with an empty in-memory map and an empty durable log file. Each command produces exactly one string result: ["PUT", key, value]: atomically store value under key, overwriting any earlier value, and append one durable log record for this write. Return OK. ["GET", key]: return VALUE: followed by the current value, or NOT_FOUND when the key is absent. ["SERIALIZE"]: return one deterministic snapshot of the current map. ["DESERIALIZE", snapshot]: replace the current map with snapshot, rewrite the durable log to represent exactly that loaded state, and return OK. ["RECOVER"]: discard the in-memory map, replay the complete durable log in order, and return OK. Record and Snapshot Format Encode one key/value pair as <keyLength>:<key><valueLength>:<value>, where each length is a base-10 integer and the key and value follow their lengths without extra separators. For example, key user with value bob becomes 4:user3:bob. Length prefixes allow keys and values to contain digits and colons. Every PUT appends one record in that format to the log. Recovery replays records from first to last, so later records for the same key win. A snapshot concatenates one record for each current key in lexicographic key order; the empty map serializes to the empty string. Every DESERIALIZE input is a valid snapshot produced by this format. Deserialization replaces both memory and the log, recording the decoded pairs in snapshot order so a later recovery reconstructs the loaded state. Return the result of every command in the same order as operations. Function processStore(operations: String[][]) → String[] Examples Example 1 operations = [["PUT","user","alice"],["GET","user"],["PUT","user","bob"],["RECOVER"],["GET","user"],["SERIALIZE"]] return = ["OK","VALUE:alice","OK","OK","VALUE:bob","4:user3:bob"] The second PUT overwrites the in-memory value and appends a later log record. Recovery replays both records, so the later value bob wins. The final snapshot contains the one current pair. Example 2 operations = [["PUT","b","two"],["PUT","a","one"],["SERIALIZE"],["DESERIALIZE","1:a3:one1:c5:three"],["GET","b"],["GET","c"],["RECOVER"],["SERIALIZE"]] return = ["OK","OK","1:a3:one1:b3:two","OK","NOT_FOUND","VALUE:three","OK","1:a3:one1:c5:three"] Serialization sorts keys, so a precedes b. Deserialization replaces the old state, making b absent, and rewrites the log so recovery preserves exactly the loaded a and c pairs. Example 3 operations = [["PUT","x:y",""],["SERIALIZE"],["RECOVER"],["GET","x:y"],["GET","missing"]] return = ["OK","3:x:y0:","OK","VALUE:","NOT_FOUND"] The length-prefixed format safely stores a colon in the key and an empty value. The tagged VALUE: result distinguishes that stored empty value from a missing key. Constraints 1 <= operations.length <= 2000 Each command has exactly the fields described above. 1 <= key.length <= 100. 0 <= value.length <= 1000. Keys and values contain printable ASCII characters. Every snapshot passed to DESERIALIZE is a valid output of the specified snapshot format. The total number of characters across all commands is at most 2 * 10^5.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is to keep two structures: a hash map for live state and a list of log records. PUT updates the map and appends an encoded record. RECOVER clears the map and replays the log in order, so later records win. SERIALIZE sorts keys and concatenates records. The pitfall is decoding. Never split on colons. Read digits until the first colon, parse that as the length, then slice exactly that many characters for the key, and repeat for the value. Empty values have length 0, so handle that without off-by-one errors. The second pitfall is DESERIALIZE: it must replace the log too, not just the map, or RECOVER brings back old keys. Return VALUE: with an empty string for empty values, and NOT_FOUND only for absent keys. If the parser trips you up live, StealthCoder can hand you a clean decode loop as a hedge.
If you see this problem in your OA tomorrow, the play is to recognize the pattern in 30 seconds. StealthCoder buys you that recognition.
You can drill Durable String Key-Value Store cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Built by an Amazon engineer who passed his OA cold and still thinks the filter is broken.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass OpenAI's OA.
OpenAI reuses patterns across OAs. Built by an Amazon engineer who passed his OA cold and still thinks the filter is broken. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Durable String Key-Value Store FAQ
What's the main trick in the OpenAI durable key-value store problem?+
Parse with length prefixes, not delimiters. Read digits up to the colon, convert to an integer, then slice exactly that many characters. Splitting on colons breaks as soon as a key like x:y shows up, which the examples include on purpose.
How hard is this OA really?+
Easy on algorithms, medium on care. There's no clever data structure beyond a map and a list. Most failures come from decoding bugs, empty values, or forgetting that DESERIALIZE must rewrite the log. Expect a straightforward simulation with edge cases.
What happens to the log on DESERIALIZE?+
It gets replaced entirely. Clear the log, decode the snapshot in order, set each pair in the map, and append one record per pair to the new log. If you skip this, a later RECOVER resurrects old data and your output is wrong.
How should SERIALIZE order keys?+
Lexicographic key order, one record per current key, concatenated. The empty map returns an empty string. Sort the map's keys with a plain string comparison, then encode each as keyLength:key valueLength:value without separators.
How do I prepare for this in 48 hours?+
Write the encoder and decoder from scratch once, then run the three examples by hand. Test a colon in a key, an empty value, and a PUT overwrite followed by RECOVER. That covers nearly every way this problem goes wrong.