Globally Versioned Key-Value Store
Reported by candidates from Lyft's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Lyft's September 2026 OA hands you a versioned key-value store, and the constraint that matters is 100000 operations. A naive scan of every past write for every GET_AT turns into a quadratic mess that times out. The real pattern is a hash map from key to a list of (version, value) pairs, plus binary search on each read. If you've seen LeetCode's time-based key-value store, you've basically seen this. If you blank under the clock, StealthCoder is the silent safety net running invisibly during the live OA.
The problem
Implement a versioned key-value store by processing the finite array operations from left to right. The store starts empty, and its global version starts at 0. Each operation has one of these forms: SET key value: increment the global version by one, then store value for key at that new version. GET key: return the latest value stored for key, or NULL when the key has no value. GET_AT key version: return the value stored for key at the greatest global version less than or equal to version, or NULL when no such value exists. Return one string for every GET or GET_AT operation, in command order. SET operations do not produce output. Function runVersionedStore(operations: String[]) → String[] Examples Example 1 operations = ["SET color red","SET size small","SET color blue","GET_AT color 2","GET_AT size 1","GET color","GET_AT color 3"] return = ["red","NULL","blue","blue"] The writes receive global versions 1, 2, and 3. At version 2, color still has value red; size did not yet exist at version 1. Example 2 operations = ["SET a one","SET b two","SET b three","SET a four","GET_AT a 3","GET_AT b 4","GET_AT c 10"] return = ["one","three","NULL"] Key a has history entries only at global versions 1 and 4, so its read at version 3 returns one. Constraints 1 <= operations.length <= 100000. Every operation is exactly one documented command with single spaces between tokens. Keys and values contain 1 to 100 ASCII letters, digits, underscores, or hyphens. A stored value is never the reserved token NULL. Every requested historical version is an integer in [0, 10^9]. At least one operation is GET or GET_AT.
Reported by candidates. Source: FastPrep
Pattern and pitfall
Keep one global counter and a hash map where each key maps to an ordered list of (version, value). Every SET bumps the counter and appends to that key's list. Versions only increase, so each list is already sorted and you never need to re-sort. GET reads the last element of the list, or returns NULL if the key is missing. GET_AT binary searches for the greatest version less than or equal to the query, returning NULL if none qualifies. That's O(1) per write and O(log n) per read. Pitfalls: the counter is global, not per key, so example 1 gives size version 2 even though it's the key's first write. Another trap is the version 0 query, which always returns NULL. Split each command on spaces and watch the token counts. Parse carefully and return strings only for reads. If the search logic slips live, StealthCoder can hand you a clean solution as a hedge.
The honest play: practice the pattern, and have StealthCoder ready for the one you didn't see coming.
You can drill Globally Versioned 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 for the candidate who saw this exact problem leak two days before his OA and wondered if anyone had a play.
Get StealthCoderRelated leaked OAs
This OA pattern shows up on LeetCode as time based key value store. If you have time before the OA, drill that.
You've seen the question.
Make sure you actually pass Lyft's OA.
Lyft reuses patterns across OAs. Built for the candidate who saw this exact problem leak two days before his OA and wondered if anyone had a play. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Globally Versioned Key-Value Store FAQ
What's the trick in the Lyft versioned key-value store problem?+
Store a per-key list of (version, value) pairs in a hash map, then binary search on GET_AT. Because the global version only increases, each list is naturally sorted by version. That gives O(log n) reads and O(1) writes instead of scanning history.
Why does brute force fail here?+
With up to 100000 operations, scanning a key's full history on every GET_AT can approach quadratic time. If most operations are SETs on one key followed by many reads, you do billions of comparisons. Binary search keeps each read logarithmic.
Is the version counter per key or global?+
Global. Every SET increments it once, regardless of the key. In example 1, size gets version 2 because color was set first. Mixing this up with a per-key counter is the most common wrong answer.
What should GET_AT return for edge cases?+
Return NULL if the key doesn't exist or if every stored version for that key is greater than the query. A query of version 0 always returns NULL since the first write is version 1. Queries above the current version just return the latest value.
How do I prepare for this in 48 hours?+
Write the solution once from scratch: parse commands, hash map of lists, and a hand-written upper-bound binary search. Test it against both examples. Then practice the same shape on a time-based key-value store so the search boundary feels automatic.