Recent Metrics by Name and Tags
Reported by candidates from Vercel's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Vercel's September 2026 OA hands you a tiny in-memory metrics database and calls it a day. Read past the wrapper and it's a filter, a sort, and a string formatter. No clever algorithm, just careful bookkeeping. With 100 operations max, nobody is grading you on speed. They're grading whether you catch the tie-break rule and the tag sorting. If you blank on the structure, StealthCoder can run as a safety net during the live assessment. But the whole thing is short enough to build from scratch in your head tonight.
The problem
Implement an in-memory metrics database. Process the rows of operations in order, starting with an empty database. ["RECORD", name, timestamp, value, tag1,...] stores one metric. Each tag is written as key=value. ["SEARCH", name, n, tag1,...] returns the most recent matching metrics. A stored metric matches when its name is equal and it contains every query tag with the same value; it may contain additional tags. For each operation, append one row to the result. A RECORD row produces ["null"]. A SEARCH row contains up to n matching metrics ordered by descending timestamp, with later RECORD operations first when timestamps tie. Encode each returned metric as name|timestamp|value|tags. In that encoding, sort its key=value tags lexicographically and join them with commas. A metric with no tags has an empty suffix after the final |. If fewer than n metrics match, return all of them; if none match or n is zero, return an empty row. Function processMetrics(operations: String[][]) → String[][] Examples Example 1 operations = [["RECORD","cpu","10","7","host=a","zone=west"],["RECORD","cpu","12","9","host=a"],["SEARCH","cpu","2","host=a"]] return = [["null"],["null"],["cpu|12|9|host=a","cpu|10|7|host=a,zone=west"]] Both stored CPU metrics contain host=a. Timestamp 12 comes first, and the older metric may have the additional zone tag. Example 2 operations = [["RECORD","latency","20","4","region=us"],["RECORD","latency","20","8","region=us","tier=api"],["SEARCH","latency","5","region=us"]] return = [["null"],["null"],["latency|20|8|region=us,tier=api","latency|20|4|region=us"]] The two matching metrics have equal timestamps, so the metric recorded later is returned first. Its tags are sorted in the encoded record. Example 3 operations = [["RECORD","cpu","1","5","host=a"],["SEARCH","memory","3","host=a"],["SEARCH","cpu","0"]] return = [["null"],[],[]] The name memory has no stored metrics, and a limit of zero also returns an empty result row. Constraints 1 <= operations.length <= 100. Every operation begins with RECORD or SEARCH and follows the row shape in the statement. Names, tag keys, and tag values contain 1 to 20 lowercase English letters, digits, or underscores. Each row contains at most 20 tags with distinct keys. 0 <= timestamp <= 10^9 and -10^9 <= value <= 10^9. 0 <= n <= 100.
Reported by candidates. Source: FastPrep
Pattern and pitfall
Here's what it reduces to: store every RECORD in a list with an insertion index, then on SEARCH, scan the list, keep entries where the name matches and every query tag key=value is present, sort by timestamp descending then insertion index descending, and take the first n. Parse each stored metric's tags into a set or map so the subset check is clean. Encode as name|timestamp|value|tags with tags sorted lexicographically and comma-joined. The pitfalls are all small. Ties go to the later record. A metric with no tags ends with a bare pipe. n of zero or no matches returns an empty row, not ["null"]. Don't compare timestamps as strings. Parse them as integers. If you freeze on the details during the live OA, StealthCoder can catch you, but the logic is simple enough to write cold.
StealthCoder is the hedge for the one pattern you didn't drill. It runs invisibly during the screen share.
You can drill Recent Metrics by Name and Tags 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. If you're reading this with an OA window open, you're who this was built for.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Vercel's OA.
Vercel reuses patterns across OAs. If you're reading this with an OA window open, you're who this was built for. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Recent Metrics by Name and Tags FAQ
How hard is the Vercel Recent Metrics by Name and Tags question really?+
Easy to medium. There's no hard algorithm. With at most 100 operations, brute force is fine. The difficulty is in the spec details: tie-breaking by record order, sorting tags before encoding, and returning an empty row instead of null for empty searches.
What's the trick to the tie-break on equal timestamps?+
Store an insertion counter with every metric. When sorting search results, order by timestamp descending, then by insertion counter descending. Example 2 shows this: two metrics at timestamp 20, and the later recorded one comes first. Python's sort with a tuple key handles it neatly.
How do I match tags correctly?+
Parse each stored metric's tags into a map of key to value. For a search, every query tag must exist in that map with the same value. Extra tags on the stored metric are fine. Splitting on the first equals sign keeps parsing safe.
What are the edge cases that fail hidden tests?+
A metric with no tags needs the trailing pipe with an empty suffix. A search with n equal to zero returns an empty row. A name with no stored data returns an empty row. Negative values must print as-is. RECORD rows return a row containing the string null.
How do I prepare for this in 48 hours?+
Write this exact problem once from scratch. Practice a few similar design-style simulation problems with filtering, custom sorting, and string formatting. Focus on reading specs line by line and testing the three examples by hand. You don't need advanced data structures for this one.