Reported July 2026
Airbnbdesign

Recipe Management System

Reported by candidates from Airbnb's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.

Get StealthCoderRuns invisibly during the live Airbnb OA. Under 2s to a working solution.
Founder's read

Airbnb reportedly served this Recipe Management System OA in July 2026, and it's a design problem dressed up as a parsing exercise. Up to 10^4 operations, each touching recipes with up to 100 ingredients, so a naive scan on every call gets slow fast. You're building a small in-memory store with eight opcodes, case-insensitive name rules, and sorted listings. Nothing here is hard algorithmically. It's easy to lose points on tiny details. If you blank mid-assessment, StealthCoder runs invisibly on your desktop and can hand you a clean structure while the proctor sees nothing.

The problem

Process an ordered sequence of recipe and user operations. Recipe IDs are assigned monotonically as recipe1, recipe2, and so on, and deleted IDs are never reused.
Each operation is a string array with one of these forms:
["ADD_RECIPE", name, ingredientsCsv, stepsCsv] adds a recipe when no existing recipe has the same name case-insensitively. It returns [recipeId], or an empty list on a name conflict.
["GET_RECIPE", recipeId] returns [name, ingredientsCsv, stepsCsv], or an empty list when the ID is missing.
["UPDATE_RECIPE", recipeId, name, ingredientsCsv, stepsCsv] replaces all recipe fields. It returns ["true"] on success and ["false"] for a missing ID or case-insensitive name conflict.
["DELETE_RECIPE", recipeId] removes the recipe and returns a lowercase boolean string.
["SEARCH_INGREDIENT", ingredient] returns IDs of recipes containing an exact case-insensitive ingredient. Order them by ingredient count ascending, then numeric recipe ID ascending.
["LIST_RECIPES", sortBy] returns every recipe ID. For ingredient_count, sort by ingredient count ascending and then numeric ID. Otherwise, including an unsupported value, sort by case-insensitive name ascending and then numeric ID.
["ADD_USER", username] returns ["true"] after adding a new case-sensitive username and ["false"] for a duplicate.
["EDIT_RECIPE", username, recipeId, name, ingredientsCsv, stepsCsv] lets any existing user replace an existing recipe, subject to the same name rule, and returns a lowercase boolean string.
Return one string-list result for every operation in input order.

Function
manageRecipes(operations: String[][]) → String[][]

Examples
Example 1
operations = [["ADD_RECIPE","Pancakes","Flour,Egg,Milk","Mix,Cook"],["ADD_RECIPE","Salad","Lettuce,Tomato","Chop,Toss"],["GET_RECIPE","recipe1"],["SEARCH_INGREDIENT","egg"],["LIST_RECIPES","name"]]
return = [["recipe1"],["recipe2"],["Pancakes","Flour,Egg,Milk","Mix,Cook"],["recipe1"],["recipe1","recipe2"]]
The ingredient lookup is case-insensitive, so egg finds recipe1. Name order places Pancakes before Salad.
Example 2
operations = [["ADD_RECIPE","Soup","Water,Carrot","Boil,Serve"],["ADD_RECIPE","sOuP","Stock","Heat"],["UPDATE_RECIPE","recipe1","Stew","Potato,Beef,Carrot","Brown,Simmer"],["GET_RECIPE","recipe1"],["DELETE_RECIPE","recipe9"],["DELETE_RECIPE","recipe1"],["GET_RECIPE","recipe1"]]
return = [["recipe1"],[],["true"],["Stew","Potato,Beef,Carrot","Brown,Simmer"],["false"],["true"],[]]
The second add conflicts with Soup case-insensitively. Updating changes every stored field; deletion releases the name but never reuses the ID.
Example 3
operations = [["ADD_RECIPE","Beta","X,Y","One,Two"],["ADD_RECIPE","Alpha","Z","Only"],["ADD_USER","chef"],["ADD_USER","chef"],["EDIT_RECIPE","missing","recipe1","Nope","X","Only"],["EDIT_RECIPE","chef","recipe1","Gamma","X","Only"],["LIST_RECIPES","ingredient_count"],["LIST_RECIPES","unsupported"]]
return = [["recipe1"],["recipe2"],["true"],["false"],["false"],["true"],["recipe1","recipe2"],["recipe2","recipe1"]]
Only an existing user can edit. After the edit, both recipes have one ingredient, so numeric ID breaks that tie. The unsupported sort key defaults to name order.

Constraints
1 <= operations.length <= 10^4.
Every operation has a supported opcode and the exact arity shown in the statement.
Names, usernames, ingredients, and steps contain printable ASCII characters; names and usernames are non-empty.
Ingredient and step elements are non-empty, contain no commas, have length at most 100, and each CSV contains at most 100 elements.
Recipe-name equality and ordering and ingredient matching are case-insensitive; usernames are case-sensitive.

Reported by candidates. Source: FastPrep

Pattern and pitfall

The trick is picking the right indexes up front. Keep a map from recipe ID to a record, a map from lowercase name to ID for conflict checks, and a map from lowercase ingredient to a set of IDs for SEARCH_INGREDIENT. Keep a separate user set, case-sensitive. Store an ingredient count on each record. Sorting at query time is fine at 10^4 operations: sort by count then numeric ID, or by lowercased name then numeric ID. The pitfalls are all small. Compare IDs numerically, not as strings, or recipe10 lands before recipe2. On UPDATE and EDIT, a name conflict must ignore the recipe's own current name. Remove the old name and ingredient index entries before inserting new ones. Never reuse deleted IDs, so keep a separate counter. Unknown sort keys fall back to name order. If the details blur under pressure, StealthCoder is the hedge for the live OA.

If this hits your live OA and you blank, StealthCoder solves it in seconds, invisible to the proctor.

If this hits your live OA

You can drill Recipe Management System 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 would have shipped this the night before his JPMorgan OA if he'd had it.

Get StealthCoder

Related leaked OAs

⏵ The honest play

You've seen the question. Make sure you actually pass Airbnb's OA.

Airbnb reuses patterns across OAs. Built by an Amazon engineer who would have shipped this the night before his JPMorgan OA if he'd had it. Works on HackerRank, CodeSignal, CoderPad, and Karat.

Recipe Management System FAQ

How hard is the Airbnb Recipe Management System OA really?+

Easy to medium. No clever algorithm is needed. The difficulty is eight opcodes and many edge cases: case-insensitive names, tie-breaking, deleted IDs, and update conflicts. Candidates lose points on details, not on complexity. Read every rule twice before coding.

What's the trick to passing all the hidden tests?+

Maintain consistent indexes. Update the ID map, name map, and ingredient index together on add, update, edit, and delete. Most failures come from stale entries left behind after an update or delete, which cause false name conflicts or ghost search results.

How should I sort recipe IDs correctly?+

Parse the numeric part of the ID and compare it as an integer. String comparison puts recipe10 before recipe2. For name sorting, lowercase the name first, then break ties by numeric ID. Unsupported sort keys use the name order.

Can an update keep the same name?+

Yes. The conflict check should exclude the recipe being updated, so renaming a recipe to its own name, even with different casing, succeeds. Only a different recipe holding that name case-insensitively causes a false result.

How do I prepare for this in 48 hours?+

Write the class once from scratch with the three maps and a counter, then run the three examples. Test deletion followed by re-adding the same name, and confirm the new ID is higher. Design-style OAs reward clean structure more than speed.

Problem reported by candidates from a real Online Assessment. Sourced from a publicly-available candidate-aggregated repository. Not affiliated with Airbnb.

OA at Airbnb?
Invisible during screen share
Get it