Thumbtack · Software Engineer
Updated · 2026-09-24

Thumbtack Software Engineer
Interview Guide

THE 60-SECOND BRIEF

Thumbtack runs a two-sided local services marketplace that connects customers with local service professionals (pros) across many categories, from home remodeling to personal training. Engineering work in the role spans matching customers with pros, search and discovery, messaging, and booking and transaction flows. Several reported interview questions come from that domain: lead matching, pro search by proximity and rating, scheduling without overlaps, and notifications at high volume.

This guide covers the Software Engineer loop as candidates describe it: a recruiter call, a technical assessment (an online assessment or a take-home, often the in-memory database challenge), one or two technical phone screens, and a virtual onsite with several technical and behavioral panels. It groups the reported questions by category (coding, object-oriented and practical design, system design, behavioral), explains what each round checks, and gives a 7-day plan built around runnable code, the in-memory database task, practical design and behavioral stories.

Thumbtack candidates report 4 rounds · ≈ 3-5 weeks. The stages below are what candidates describe, not a published process.

Make offer acceptance idempotent under expiry racesEnforce a single active assignment per providerIndex provider locations for bounded proximity queries

38 min read

Practice 15 Software Engineer prompts
2Candidate experiences ↗Read their reports
15Practice promptsAcross five skill areas
3With worked solutionsIncluded in the practice prompts

Thumbtack is a two-sided marketplace for local services that connects customers with local service professionals (pros) across many categories, from home remodeling to personal training. Software Engineers work on the systems behind that exchange: matching customer requests with available pros, search and discovery, messaging, and booking and transaction flows, across backend services, search ranking, web and mobile.

The interview questions candidates report follow the same domain. Coding prompts include flattening a nested list with an iterator, building and traversing a service-category tree, parsing search queries into structured filters, and routing a pro between several job sites. The practical design prompts are a calendar with no overlapping events for a pro, a key-value store with BEGIN, COMMIT and ROLLBACK, and a rolling-window rate limiter. The system design prompts are real-time lead matching, a notification service for push, SMS and email with guaranteed delivery and rate limiting, and a pro search system that weighs proximity, availability and ratings.

Plan for code that runs. Candidates describe writing code in a shared editor that has to compile and pass test cases in the phone screens and the onsite coding rounds, not pseudocode. Candidates often report that the technical assessment is an in-memory database with nested transactions. Treat that submission as code someone will review: keep it readable, modular, tested and object-oriented. Prepare for correct, tested and readable code first, then work on algorithm speed.

01

Recruiter Call

reported

Candidates describe a first call with a recruiter about your background, career goals and team alignment. It is also your best chance to learn how the rest of the loop is set up. Candidates report that the next stage is either an online assessment or a take-home challenge, and that the phone-screen stage is one or two interviews. Ask which applies to you, which language and environment you will code in, and whether design comes up before the onsite. The answers tell you whether to spend your first week on the in-memory database task, timed algorithm practice or design.

What to demonstrate

  • Whether you can summarise your background briefly and link it to the kind of team you want, since team alignment is one of the reported topics of this call
  • Whether your career goals are concrete enough for the recruiter to match you to a team, rather than a general wish to grow
  • Whether you ask about the format of the next stages instead of guessing

How to prepare

  • Write a short spoken summary of your background that ends on the kind of systems you want to work on next, such as marketplace matching, search, messaging or payments
  • Prepare questions: online assessment or take-home, which coding platform and language, one or two phone screens, and where system design comes in
  • Write down your constraints (start date, location, any competing timeline) so you can state them plainly if asked
PracHub interview research
02

Technical Assessment

reported

Candidates report an online technical assessment or a take-home coding challenge, and a recurring version of it is the in-memory database task. You parse and run commands such as GET, SET, UNSET and NUMEQUALTO, and support nested transaction blocks with BEGIN, COMMIT and ROLLBACK. It can be timed or take-home. Treat the submission as code someone will review: keep it readable, modular, tested and object-oriented. Output that passes the samples but sits in one long function is a weak submission. Build the design so that rollback does not copy the whole store and NUMEQUALTO does not scan every key.

What to demonstrate

  • Correct behavior of nested transactions: a ROLLBACK undoes only the innermost open block, and values that were absent before the block become absent again
  • Separation between command parsing, the storage layer and transaction bookkeeping, so each can be read and tested on its own
  • Tests you wrote yourself, covering nested rollback, commit, rollback with no open transaction, and NUMEQUALTO after unsets
  • Efficiency: rollback costs are proportional to the keys changed in the block, and value counts are maintained incrementally

How to prepare

  • Implement the in-memory database from scratch once, in the language you will use, with a stack of per-transaction undo logs that record each key's prior value, including 'was absent'
  • Maintain a value-to-count map updated on every SET, UNSET and rollback so NUMEQUALTO is a lookup, then write a test that proves the count survives a nested rollback
  • Decide and document what COMMIT and ROLLBACK do when no transaction is open, and what COMMIT does with nested blocks, then test exactly that
  • If it is a take-home, add a short README with how to run it, the assumptions you made and the complexity of each command
PracHub interview research
03

Technical Phone Screens

reported

Candidates describe one or two technical phone screens with senior engineers. Prepare to write code in a shared editor (CoderPad and HackerRank are named as examples) that compiles and runs against test cases. Reported coding prompts include a nested-list iterator, building and traversing a category tree from parent-child pairs, parsing search queries into structured filters, and graph routing between job sites. Those reports do not say which of them come up in the screens rather than the onsite. Ask clarifying questions, discuss edge cases and give the complexity before you write code, and treat those steps as part of the answer.

What to demonstrate

  • Whether your code actually runs and passes tests, including ones you add, rather than looking plausible
  • Whether you clarify the input and discuss edge cases (empty input, nulls, malformed data, extreme values) before coding
  • Whether you state time and space complexity and choose data structures for a reason
  • Whether you keep talking while you debug, so the interviewer can follow your reasoning

How to prepare

  • Practise in a plain shared editor without autocomplete: write the function, then a small main that runs three or four cases and prints expected against actual
  • Drill the reported shapes: a lazy nested-list iterator with a stack, a tree built from parent-child pairs with cycle and orphan checks, and a query parser that tokenizes before it maps tokens to filters
  • For routing, know BFS for unweighted edges and Dijkstra for weighted ones, and say which the prompt needs before you write either
  • Get a simple correct version running first, then optimise; avoid over-engineering early
PracHub interview research
04

Virtual Onsite Interview

reported

The final stage is described as a virtual onsite with several technical and behavioral panels. Plan to be ready for both live coding and system design by this point, and hold your onsite coding to the same runnable-code standard as the phone screens. The reported design questions (see the questions section) come with no stated round, so prepare all of them before the onsite rather than assuming which one you will get. In design discussions, focus on practical trade-offs: storage choice, caching, queues and API protocols, measured against latency, consistency and network partitions. For the behavioral panels, prepare stories about project ownership, collaboration and empathy for both customers and pros.

What to demonstrate

  • In coding panels, the same standard as the phone screens: code that runs, with edge cases and tests you raise yourself
  • In design panels, whether you define API contracts and a data model, then justify storage, caching and queueing choices with concrete trade-offs
  • Whether you name failure modes, such as a lost notification, a stale availability read or a hot geographic area, and describe how the design recovers
  • In behavioral panels, whether your stories show ownership from design through launch and monitoring, and decisions made with the end user in mind

How to prepare

  • Work through each reported system design prompt end to end: requirements, API, schema, the main read and write paths, then scaling and failure handling
  • For practical design prompts, write working code: an interval store that rejects overlaps on add and edit, and a sliding-window limiter with a per-user timestamp queue
  • Prepare one fact sheet per project story (scale, team, timeline, what broke) so the numbers stay the same if a later panel asks about the same project
  • Run at least one mock that combines a coding problem you must execute with a design discussion
PracHub interview research

2 candidate reports. Individual accounts describe a particular role and hiring cycle.

PracHub editorial advice for the preparation topics above.

01

Writing code in the phone screen or onsite that you never run

Candidates describe live coding rounds where code has to compile and pass test cases, so prepare as if pseudocode or an untested function counts as unfinished. Run a small version early, add your own cases for empty input, a single element and the tricky boundary, and fix what breaks while you explain it. Practise in an editor with no autocomplete so syntax slips do not use up your time.

02

Treating the in-memory database assessment as a script with one global map and a full-copy rollback

Treat the submission as code someone will review: readable, modular, tested and object-oriented. Keep command parsing, storage and transactions in separate parts. Implement ROLLBACK with a per-block undo log that records each key's prior value, including absence, instead of snapshotting the whole store. Keep a value-to-count map so NUMEQUALTO does not scan every key. Ship tests for nested rollback and for commit and rollback with no open transaction.

03

Calendar and interval logic that fails on touching events or on edits

For the reported calendar prompt (no overlapping events for a pro), say up front whether intervals are half-open [start, end), so back-to-back jobs do not conflict. Remember that an edit has to exclude the event being edited from its own conflict check. Keep events sorted, or in a tree keyed by start time, so a conflict check only looks at neighbours. Mention time zones, and test adjacent, contained and identical intervals.

04

Saying 'guaranteed delivery' or 'real-time matching' without defining what the system does on failure

For the notification prompt, state the delivery semantics (at-least-once with a deduplication key is the usual honest answer). Add retries with backoff, a dead-letter path, and rate limits per user and per provider channel. For lead matching and pro search, say where availability data can be stale, how the geographic index is partitioned, and what happens in a dense area. Tie each storage, cache and queue choice to its effect on latency, consistency or partition behaviour.

05

A deadline or disagreement story that ends with 'I worked harder' or 'we agreed'

The reported behavioral prompts ask about a project you led from inception to launch, a strong technical disagreement, and a deadline you realised you would miss. For each, name when you noticed the problem, who you told and how early, what evidence settled the disagreement, and what scope or quality trade-off you chose. Fix the numbers for each project in advance so they match if the same project comes up in a design panel.

Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.

12 technical prompts3 include a worked solution

Given a list of service categories and their parent-child relationship…

medium
data structures and algorithms

Given a list of service categories and their parent-child relationships, write a function to construct and traverse the category tree.

Approach
  1. Restate the input: its shape, its size, and what is guaranteed about it.
  2. Name the brute-force solution and its complexity before improving on it.
  3. Walk one small example through your approach before writing the whole thing.
Follow-up
  • How does this change if the input no longer fits in memory?
  • Which test case would catch an off-by-one here?

Implement an iterator that can traverse a nested list of integers, fla…

medium
data structures and algorithms

Implement an iterator that can traverse a nested list of integers, flattening the structure on the fly.

Approach
  1. State the target complexity and say which constraint rules the naive version out.
  2. Choose the data structure from the access pattern, not from familiarity.
  3. Name the brute-force solution and its complexity before improving on it.
Follow-up
  • How does this change if the input no longer fits in memory?
  • Which test case would catch an off-by-one here?

Solve a string parsing and manipulation problem to format user search …

medium
data structures and algorithms

Solve a string parsing and manipulation problem to format user search queries into structured filters.

Approach
  1. Name the brute-force solution and its complexity before improving on it.
  2. Restate the input: its shape, its size, and what is guaranteed about it.
  3. State the target complexity and say which constraint rules the naive version out.
Follow-up
  • Which test case would catch an off-by-one here?
  • What is the worst case, and how likely is it on real data?

Validate a booking state machine for dead ends

mediumWorked solution
graph traversalstate machinereachability

You are given a booking state machine as a list of states, each flagged terminal or not, and a list of directed (from_state, to_state) transitions; at most 40 states and 400 transitions. Report three things: states unreachable from 'accepted'; declared terminal states that still have an outgoing transition; and non-terminal states from which no terminal state is reachable. Then validate a batch of observed transition sequences, up to 10 million transitions in total, against the graph. State the complexity of each part separately.

Approach
  1. Build both the adjacency map and its transpose as hash maps of sets, in O(V + E). The transpose is what makes the third question cheap, so build it up front rather than deriving it per query.
  2. Unreachable states: one BFS or DFS from 'accepted' over the forward graph; anything unvisited is unreachable, O(V + E). In production an unreachable state is usually a rename that was applied in code but not in the data.
  3. Terminal violations, as the prompt defines them: a declared terminal state with out-degree > 0. One scan of out-degrees against the flags answers it, O(V + E). Report the converse — a state with out-degree 0 that nobody declared terminal — as its own separately named list rather than folding it into this count. They are different defects: a terminal with out-edges is a wrong graph, an unlabelled sink is a missing flag. Every unlabelled sink is also, by construction, a dead end under the third check, so those two lists overlap and their sizes must never be added together.
  4. Dead ends: run one multi-source BFS seeded with every terminal state at once over the transpose. Any non-terminal state not reached can never terminate, which in production is a booking that holds a provider and an authorisation indefinitely. O(V + E). Seeding with a single terminal state gives a wrong answer for states that can only reach a different terminal.
  5. Sequence validation: check each consecutive pair against the adjacency set at O(1) per pair, O(L) for L transitions across the batch. Separately reject any sequence that continues after a terminal state — that is the out-of-order-event bug, not a graph defect, and conflating the two hides it.
  6. Note the sizes deliberately. V and E are tiny, so none of the first three answers is about speed; the complexity argument matters only on the 10-million-transition validation pass, where an O(V) linear scan of the edge list per pair would be the accidental quadratic.
Worked solution 25 min
  1. Take the states accepted, en_route, arrived, in_progress, completed, cancelled, disputed, with completed and cancelled declared terminal.
  2. Take the transitions: accepted to en_route and to cancelled; en_route to arrived and to cancelled; arrived to in_progress and to cancelled; in_progress to completed and to cancelled; completed to disputed.
  3. BFS forward from accepted and note which states are visited.
  4. Scan out-degrees against the terminal flags, producing two separate lists: declared terminals that still have an out-edge, and out-degree-0 states carrying no terminal flag.
  5. Multi-source BFS from {completed, cancelled} over the transpose and list the non-terminal states it fails to reach.
  6. Add a disputed-to-completed edge and re-run every check, naming which lists move and which do not.
EXPECTED RESULTNo unreachable states, since disputed is reached through completed. One terminal violation: completed is declared terminal but has an edge to disputed. One unlabelled sink: disputed, out-degree 0 and no terminal flag. One dead end: disputed again, the same state, because no terminal is reachable from it. Adding the disputed-to-completed edge empties both the unlabelled-sink list and the dead-end list; the unreachable list stays empty and the terminal-violation list still holds completed, whose edge to disputed is untouched.
Follow-up
  • A 'started' event arrives after 'completed' for the same booking — where in a running service is that rejected, and what does the caller see?
  • How do you version the transition table so that a deploy mid-saga does not invalidate bookings already in flight under the old table?
  • Which of these transitions move money, and what does marking them add to this validation?

For a candidate senior enough that the loop turns on design and judgement rather than on whether the coding round gets finished. Five days build one system properly and then stress it; coding gets a single maintenance day, on the assumption that the risk at this level is an unexamined tradeoff rather than a missed algorithm.

Small steps. Visible outcomes.0 / 7 completed
ONE WEEK · YOUR PACE

Prepare, practise & reflect

One practical outcome each day. Spend longer where you need it.

0 / 7 done
01Recruiter questions and a runnable-code setup
  • Prepare the recruiter call: a short background summary, your career goals, and questions about whether the assessment is an online test or a take-home, which platform and language, and whether there are one or two phone screens
  • Set up plain-editor practice in your interview language with no autocomplete, plus a tiny test harness pattern: a main that runs cases and prints expected against actual
  • Solve two easy problems end to end in that setup, such as an array scan that returns the indices of values below a threshold and a token frequency count, running every case you write

Deliverable: A written list of recruiter questions and two solved problems that run with their own test cases.

Practice prompt ↗Practice prompt ↗Practice prompt ↗Worked solution ↗
02Technical assessment: the in-memory database
  • Implement GET, SET, UNSET and NUMEQUALTO with separate command parsing and storage
  • Add BEGIN, ROLLBACK and COMMIT using a stack of undo logs that record prior values, including 'was absent', and keep NUMEQUALTO counts correct through rollback
  • Write tests for nested rollback, commit with nested blocks, rollback and commit with no open transaction, and NUMEQUALTO after unset
  • Add a short README with the assumptions and the complexity of each command, as you would for a take-home

Deliverable: A working, tested in-memory database with transactions and a README of assumptions and complexity.

Practice prompt ↗Practice prompt ↗
03Coding: iterators, trees and parsing
  • Implement the reported nested-list iterator lazily with a stack, and test empty sublists, deep nesting and hasNext called twice
  • Build a category tree from parent-child pairs, traverse it, and handle a missing parent and a cycle explicitly
  • Write a search-query parser that tokenizes first and then maps tokens to structured filters, and test extra spaces, unknown tokens and empty input
  • Evaluate a postfix expression with a stack and state its complexity

Deliverable: Three runnable solutions with edge-case tests and a stated complexity for each.

Practice prompt ↗Practice prompt ↗
04Coding: graphs, ordering and state
  • Solve the reported routing prompt for a pro travelling between job sites: say whether edges are weighted, then implement BFS or Dijkstra accordingly
  • Practise a dependency-order check with topological sort and cycle detection
  • Work through the worked exercise 'Validate a booking state machine for dead ends' and check your reachability lists against its expected result
  • Compute a streaming mean and median over a bounded integer range with frequency counts

Deliverable: Graph solutions that run, plus the state-machine exercise checked against its stated result.

Practice prompt ↗Practice prompt ↗Worked solution ↗
05Object-oriented and practical design, in code
  • Implement the reported calendar for one pro: add, edit and delete with no overlaps, half-open intervals, and an edit that excludes itself from the conflict check
  • Implement a rolling-window rate limiter per user with a timestamp queue, then describe the memory trade-off against a counter-based approximation
  • Revisit the key-value store with transactions from day 2 and refactor anything you would not want a reviewer to read

Deliverable: Tested calendar and rate-limiter classes with a short note on the design choices.

Practice prompt ↗Practice prompt ↗
06System design
  • Design the reported notification service: channels (push, SMS, email), delivery semantics, retries, dead letters and per-user rate limits
  • Design pro search by proximity, availability and rating: a geographic index, where availability can be stale, and caching of results
  • Design real-time lead matching, then work through the worked exercises 'Redesign an offer-accept endpoint whose retry cannot read its own result' and 'Resolve accept-versus-expire races with a guarded conditional update'
  • For each design, write the API, the schema, and one justified choice each for storage, cache and queue

Deliverable: Three designs, each with API, schema and named failure modes, plus both concurrency exercises compared against their expected results.

Practice prompt ↗Practice prompt ↗
07Behavioral stories and a full mock
  • Write stories for the reported prompts: a project you led from inception to launch, a strong technical disagreement, and a deadline you saw you would miss
  • For each story, fix the figures (scale, team, timeline) and name the trade-off, the evidence and what you would change
  • Run a mock with a coding problem you must execute in a shared editor, followed by one design prompt from day 6
  • Review the mock: note any code that did not run on the first try and any design choice you could not justify

Deliverable: Three behavioral stories with fixed figures and written notes from one combined coding and design mock.

Practice prompt ↗Practice prompt ↗Worked solution ↗

Expand any day for tasks and deliverables. Your progress is saved on this device.

Prepare stories around three themes: owning a feature from design through launch and monitoring, collaborating (mentoring, giving and taking feedback, resolving disagreements), and empathy for both sides of the marketplace, customers and pros. For each story, give the decision you made, the evidence behind it and the result, and keep the figures the same if the project comes up again in a design panel.

Design a calendar scheduling system with functionalities to add, edit,…

medium
behavioural and engineering judgement

Design a calendar scheduling system with functionalities to add, edit, delete, and update events, ensuring no overlapping conflicts for a service pro.

Approach
  1. Close with what you would do differently, concretely.
  2. Give the blast radius: what could have broken, and what you measured.
  3. Name the disagreement and how you resolved it with evidence.
Follow-up
  • What would you do differently if you ran that again?
  • How did you know your change caused the improvement?

Tell me about a time when you had a strong technical disagreement with…

medium
behavioural and engineering judgement

Tell me about a time when you had a strong technical disagreement with a teammate or manager. How did you resolve it?

Approach
  1. State the situation in two sentences and spend the rest on the reasoning.
  2. Give the blast radius: what could have broken, and what you measured.
  3. Name the disagreement and how you resolved it with evidence.
Follow-up
  • What would you do differently if you ran that again?
  • How did you know your change caused the improvement?

Estimating work in a system you had never touched

hard
estimationuncertaintyplanning

You are asked for a date on work you have never done: moving live provider positions out of the transactional database into a spatial index with TTL semantics, or rebuilding payouts on append-only double-entry postings. You have two days before the estimate is due. Describe how you built it - what you decomposed, what you spiked, what you refused to estimate at all - and the uncertainty you attached. State the estimate you gave and its shape: a range with a confidence, or a first milestone with a named checkpoint. Then say what it turned out to be, and what you would change about the method.

Approach
  1. Split the work into done-before, analogous, and genuinely unknown. Only the third bucket needs a spike, and estimating that bucket without one is a guess wearing a number.
  2. Spend the two days buying information about the largest unknown rather than the largest task. For a store migration the unknowns are almost never the new code - they are the backfill, the set of consumers reading the old shape, and how you will prove the new path is equivalent under live traffic.
  3. Give the estimate a shape that survives being wrong: a range with an explicit confidence, or a first milestone with a date plus a checkpoint at which everything after it is re-estimated. A single number covering six weeks of novel work is a promise whose failure is already scheduled.
  4. Attach assumptions as a numbered list. A written assumption converts a later slip from a broken commitment into a discovered fact, which is the only mechanism that keeps estimates honest over a long project.
  5. Compare estimate to actual and attribute the variance to one cause - a consumer nobody knew about, review latency, an unowned dependency, or scope growth. The correction differs for each, and naming the wrong one means repeating the miss.
Follow-up
  • Which assumption broke first, and how long before you noticed?
  • Knowing what you know now, what would you have spiked instead?
  • How do you answer when the person asking wants a single date and will not accept a range?
  • 01

    Describe a challenging technical project you led from inception to launch. What trade-offs did you make, and what did you learn?

  • 02

    Tell me about a time you had a strong technical disagreement with a teammate or manager. How did you resolve it?

  • 03

    How do you handle a situation where you realise a project you are working on will not meet its deadline?

  • 04

    Tell me about a delivery you led that had measurable business impact: how you prioritised and kept stakeholders aligned.

  • 05

    Describe a technical decision where thinking about the end user changed what you built.

PracHub interview preparation framework
Is this an official Thumbtack interview guide?

No. It is PracHub's own research and practice material for the Software Engineer role at Thumbtack. Rounds and questions reflect what candidates have reported, not a process Thumbtack has published, and they change over time. Confirm the current format and scope with your recruiter.

PracHub interview research
What rounds does the Thumbtack Software Engineer process include?

Candidates report four stages: a recruiter call about background, goals and team alignment; a technical assessment, either an online assessment or a take-home challenge; one or two technical phone screens with senior engineers; and a virtual onsite with several technical and behavioral panels. Candidate reports put the whole process at roughly three to five weeks. Ask your recruiter which assessment format and how many phone screens apply to you.

PracHub Software Engineer practice
Does my code need to compile and run during the live interviews?

Candidates describe writing code in a shared editor that must compile and pass test cases, in the phone screens and in the onsite coding rounds. Prepare for that: practise in your chosen language without autocomplete, know its standard library well, and get used to writing and running your own test cases while you talk through them.

PracHub interview research
What is the in-memory database assessment?

Candidates report it as a common form of the technical assessment, given as a timed online test or a take-home. You build a command-driven key-value store supporting commands such as GET, SET, UNSET and NUMEQUALTO, with nested transactions through BEGIN, COMMIT and ROLLBACK. Treat the submission as code someone will review: keep it readable, modular, tested and object-oriented, alongside producing correct output.

PracHub Software Engineer practice
What kinds of coding and design questions are reported?

Coding reports include a nested-list iterator, building and traversing a category tree, parsing search queries into filters, and graph routing between job sites. Practical design reports include a calendar with no overlapping events, a key-value store with transactions, and a rolling-window rate limiter. System design reports include real-time lead matching, a high-volume notification service with guaranteed delivery and rate limiting, and pro search by proximity, availability and ratings. The reports do not tie these to specific rounds.

PracHub Software Engineer practice
How should I prepare for the behavioral panels?

Prepare stories for the reported prompts: a project you led from inception to launch, a strong technical disagreement, and a deadline you realised you would miss. Build them around ownership, collaboration and empathy for customers and pros. In each story, name the decision, the evidence and the outcome, and keep your project figures the same across panels.

PracHub Software Engineer practice
Sources & methodology 3 sources ↗

Official role evidence, timestamped platform data and clearly labeled preparation advice.