Liftoff · Software Engineer
Updated · 2026-09-24

Liftoff Software Engineer
Interview Guide

THE 60-SECOND BRIEF

As a Software Engineer at Liftoff, you are at the core of a high-scale, data-intensive platform that powers mobile marketing and retargeting campaigns. You are not just writing code; you are building systems that process billions of events daily, optimizing bidding algorithms, and ensuring that mobile advertisements reach the right users at the right time. Your work directly impacts the revenue and growth of the world’s leading mobile apps.

Seniority moves the scope further than the words in the title do. An earlier-career loop mostly checks that you implement something correctly and can reason about its cost, while a senior loop checks that you can pick between two defensible designs and say what you gave up.

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

Budget per-tick simulation, serialization and bandwidthPrevent negative balances with conditional single-statement debitsAudit item supply from append-only ledgers

35 min read

Practice 14 Software Engineer prompts
5Company bank questionsSnapshot · Sep 27, 2026 PT
14Practice promptsAcross five skill areas
3With worked solutionsIncluded in the practice prompts

As a Software Engineer at Liftoff, you are at the core of a high-scale, data-intensive platform that powers mobile marketing and retargeting campaigns. You are not just writing code; you are building systems that process billions of events daily, optimizing bidding algorithms, and ensuring that mobile advertisements reach the right users at the right time. Your work directly impacts the revenue and growth of the world’s leading mobile apps.

This role is both technically demanding and strategically significant. You will often work on problems related to distributed systems, real-time data processing, and large-scale infrastructure. Whether you are optimizing a backend service for lower latency or building a new feature to enhance campaign performance, you are expected to operate with high autonomy. Liftoff values engineers who can balance the need for robust, scalable design with the agility required to move fast in a competitive adtech market.

Liftoff places a high premium on candidates who demonstrate practical problem-solving skills over purely theoretical knowledge. Be prepared to show how your code handles real-world constraints.

01

Technical Screens

reported

Input bounds are the part of the prompt most often skimmed, and they usually contain the answer. They tell you which complexity class is admissible, which narrows the search before you have thought about the problem itself. As a rough planning figure, a compiled language does on the order of 10^8 simple operations per second and an interpreted one roughly an order of magnitude less. So n up to about twenty admits enumerating subsets, a few thousand admits a quadratic pass, and a million admits neither: you need near-linear, or linear with a log factor. If the bounds are missing, ask for them.

What to demonstrate

  • Whether the approach is justified by the stated input size rather than by whichever pattern you recognised first
  • Whether you ask about the properties that change the algorithm: whether the input arrives sorted, whether duplicates occur, whether values are bounded integers, whether it all fits in memory
  • Whether you can name the bottleneck in your own solution and what would remove it, even when you deliberately leave it in place
  • Whether a claimed speedup is real, since memoising a recursion only helps when subproblems genuinely overlap and the state can be keyed cheaply

How to prepare

  • For each algorithm you rely on, write down the largest n it handles in roughly a second, then check two of those figures by timing them in the language you will actually type in
  • For two weeks, write one line naming your target complexity and the bound that justifies it before you write any code, then compare that line with what you ended up submitting
  • Practise the conversion backwards: given a required O(n log n), list the mechanisms that get you there (sorting, a heap, an ordered map, divide and conquer) and choose by what the problem needs to query, not by what you used last
PracHub interview research ↗
02

Super Day

reported

A day like this is several different games in a row, and the expensive mistake is carrying the previous one into the next room. Coding rewards narrow precision and finishing inside a timer. Design rewards breadth, stated assumptions and naming what you are deliberately not building. Behavioural rewards specificity about people and decisions. Candidates who over-engineer a coding problem they were supposed to finish, or who start sketching class hierarchies before anyone has agreed what the system has to do, are usually still playing the last round. Between rooms, name out loud which game the next one is.

What to demonstrate

  • Whether the coding round ends with something that runs and has been traced against a degenerate input, rather than an extensible design that was never finished
  • Whether a design discussion opens by agreeing on traffic shape, read-to-write ratio and what is allowed to be stale, instead of proceeding from an architecture you arrived with
  • Whether a behavioural answer names a person, a disagreement and what you did about it, rather than describing the system the story happened inside
  • Whether the opening habits still appear late in the day: restating the problem, asking for constraints, saying the plan before typing

How to prepare

  • Book three mocks of different types back to back on one afternoon and ask each interviewer afterwards which round you answered in the wrong mode
  • Write a three-line opening script per round type — coding: restate, name the approach and its cost, then type; design: ask for scale, read-write mix and what must not break; behavioural: name the person, the stakes and the decision — and run it off a card so the switch is mechanical rather than remembered
  • Practise coding with a timer you do not extend, stopping when it stops, so the trained reflex is to finish a correct solution rather than to keep improving one
PracHub interview research ↗
03

Coding Project

reported

The same problem is scored by two different mechanisms depending on the format, and preparing for one does not cover the other. With a person watching, partial progress is visible and a hint is a correction you can absorb; silence is the expensive failure, because nobody can read a half-written function. With an automated grader there is no partial credit for what you were about to do, nobody to ask, and the worked examples in the prompt are the entire specification. Read them as a contract, down to whether an empty result should be an empty list or no output at all.

What to demonstrate

  • In a live session, whether your commentary tracks what your hands are doing, and whether a hint redirects you or gets defended against
  • In an automated one, whether you cover the cases the examples do not show, since the hidden cases are where the score moves
  • Whether you manage the clock on purpose: abandoning an approach that is not converging while there is still time to write something simpler that finishes

How to prepare

  • Have someone hand you a problem and feed you one deliberately wrong hint. Practise testing it against a concrete case instead of accepting or rejecting it on authority.
  • Do one timed run a week in a plain browser editor with autocomplete, linting and your own snippets switched off, which is closer to what these environments give you
  • For the automated format, write the harness before the solution: a main that feeds the worked examples plus an empty and a single-element case and prints expected against actual, so a wrong submission is caught by you first
PracHub interview research ↗
04

Feedback Loop

reported

Where the day includes a partner from product, design or data, that conversation is weighted like the technical ones and prepared for least. They are deciding one thing: whether having you in the room makes their decisions cheaper. That means options with costs attached, not implementation detail and not "it depends". An estimate someone can plan against — a range, the assumption that would push it to the high end, and what you would drop to hit the low one — is worth more than a confident single number, which everyone present already knows is wrong.

What to demonstrate

  • Whether an estimate comes as a range with the assumption most likely to break it, and states what a specific scope cut would actually buy
  • Whether a technical constraint is handed over as a choice with consequences on their side, rather than as a verdict they have no standing to argue with
  • Whether you establish what decision is on the table before proposing anything
  • Whether risk is raised while it can still change the plan, with the trigger that would confirm it, instead of reported afterwards as a slip

How to prepare

  • Take a project that shipped late and write the two-sentence warning you could have given three weeks earlier, naming what you would have needed decided at that point
  • Rehearse one estimate out loud until it arrives in three parts: the range, the single assumption that would blow it, and the smallest thing you would cut to protect the date
  • Rewrite an objection you have actually made — the "we can't do that" version — as two options with their costs, so the choice ends up with the person who owns it
PracHub interview research ↗

PracHub editorial advice for the preparation topics above.

01

Representing prices and balances as floating point, or storing a display currency amount instead of integer minor units plus a currency code.

Binary floating point cannot represent most decimal fractions exactly, so repeated credits and debits accumulate drift that only surfaces when reconciliation compares the ledger sum against the cached balance and finds them a fraction apart. Regional price books make it worse: the same SKU has different minor-unit scales across currencies, and a currency with no minor unit breaks any code that assumes two decimal places.

02

Caching inventory or entitlement at the edge or in the client without a version token, so a spend is validated against a stale copy.

Cache invalidation races the spend directly: a player with two sessions can spend the same stack twice inside the TTL, and a revoked entitlement stays usable until it expires. The symptom looks like a duplication bug in the inventory service, so investigation starts in the wrong place. Serving the token (a row version or ETag) and requiring the client to present it on the mutating call turns a stale read into a rejected write instead of a double spend.

03

Choosing a schema before the access patterns are known

Write the queries first, with their filters, sort orders, cardinalities and which ones sit on the latency-critical path, then design tables and indexes to serve them. An index nothing queries still costs write throughput and storage, and a hot query with no supporting index becomes a full scan that only hurts once the table is big.

04

Abandoning working code to chase the optimal solution

Get the straightforward version correct, state its complexity, and only then optimise, keeping the working version until the faster one passes the same cases. A correct quadratic solution with a stated path to linear beats a half-written optimal one that never ran.

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

11 technical prompts3 include a worked solution

Write a function to manipulate a matrix (e.g., printing or transformin…

medium
data structures and algorithms

Write a function to manipulate a matrix (e.g., printing or transforming).

Approach
  1. Name the brute-force solution and its complexity before improving on it.
  2. State the target complexity and say which constraint rules the naive version out.
  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?
  • What is the worst case, and how likely is it on real data?

Can you implement a solution for a graph traversal problem?

medium
data structures and algorithms

Can you implement a solution for a graph traversal problem?

Approach
  1. Walk one small example through your approach before writing the whole thing.
  2. Choose the data structure from the access pattern, not from familiarity.
  3. Restate the input: its shape, its size, and what is guaranteed about it.
Follow-up
  • How does this change if the input no longer fits in memory?
  • What is the worst case, and how likely is it on real data?

Build a functional application (e.g., a game or a utility) given a spe…

medium
data structures and algorithms

Build a functional application (e.g., a game or a utility) given a specific set of requirements.

Approach
  1. Name the brute-force solution and its complexity before improving on it.
  2. State the target complexity and say which constraint rules the naive version out.
  3. Restate the input: its shape, its size, and what is guaranteed about it.
Follow-up
  • Which test case would catch an off-by-one here?
  • How does this change if the input no longer fits in memory?

How would you approach a problem involving string manipulation and cha…

medium
data structures and algorithms

How would you approach a problem involving string manipulation and character counts?

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

Detect grant bursts with an exact sliding window per account

mediumWorked solution
sliding windowstreamingabuse detection

grant_receipt rows stream in at roughly 350 per second as (account_id, grant_id, source_type, source_ref_id, created_at), with non-decreasing timestamps. Raise an alert the first time any account accumulates 4 or more grants of the same source_type inside any 10-minute window, and include the offending grant ids. Memory must be bounded and one burst must not alert repeatedly. Give the amortised per-event cost, the expected number of live entries, and state precisely what a 10-minute tumbling-bucket counter would miss.

Approach
  1. Hash map from (account_id, source_type) to a deque of timestamps. Per event: push the new timestamp, pop from the front while front <= now - 600s, then test the deque length. Each timestamp is pushed once and popped once, so the cost is O(1) amortised per event even though a single event can pop many.
  2. Do the arithmetic before reaching for an approximation: 350 events per second times a 600-second window is about 210,000 live timestamps, single-digit megabytes. An exact window is affordable here, so a probabilistic counter would trade accuracy away for nothing.
  3. Bound memory against key explosion rather than against the window: drop a (account, source_type) key when its deque empties, and cap each deque at the threshold. Keeping only the last 4 timestamps is exactly sufficient, because the tightest set of 4 ending at the current event is the last 4; if those span more than 600s, no set of 4 fits the window ending now.
  4. Suppress repeat alerts explicitly. Record the newest timestamp at fire time and stay quiet until the deque has drained past it, or apply a fixed refractory period. Without this a sustained burst alerts on every subsequent event and the alert channel becomes unreadable at exactly the moment it matters.
  5. Quantify the tumbling-bucket failure rather than asserting it: with buckets of width W and threshold t, an adversary places t-1 events in each of two adjacent buckets, so 2t-2 events can occur inside a span shorter than W with neither bucket tripping.
Worked solution 20 min
  1. Take one account and one source_type with grants at minutes 8, 9, 11 and 12, threshold 4 in any 10-minute window.
  2. Walk the deque event by event, recording its contents and the front-eviction test each time.
  3. Score the same four events through 10-minute tumbling buckets [0,10) and [10,20).
  4. Replay the sliding-window version with every timestamp shifted forward by 3 minutes and compare.
EXPECTED RESULTExactly one alert, fired on the event at minute 12, naming the four grant ids at minutes 8, 9, 11 and 12, whose span is 4 minutes. The deque never exceeds 4 entries. The tumbling version counts 2 and 2 and never alerts.
Follow-up
  • Two producers clock-skew and timestamps stop being non-decreasing. What breaks in the deque invariant, and what do you do about it without buffering the whole stream?
  • Change the rule to 4 grants sharing one source_ref_id across different accounts, which is a duplication signal rather than a velocity one. What changes in the key, and what changes in the memory bound?

Day one measures instead of guessing, under a fixed rubric, and the remaining hours are allocated in proportion to the gaps before any studying begins. The allocation is deliberately not renegotiated midweek, because the area that feels worst on day three is usually the one that is moving.

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
01Diagnostic, scored before you study anything
  • Sit a 110-minute diagnostic in four blocks: forty-five minutes on two coding problems, twenty-five on one design prompt taken to interface and data model, twenty of short-answer fundamentals, and twenty delivering two behavioural answers aloud.
  • Score each block from 0 to 3 on a fixed rubric where 3 is correct and fluent, 2 is correct but slow or prompted, 1 is partially correct and 0 is stuck, grading the artifact rather than how the attempt felt.
  • Allocate days two to five in proportion to 3 minus each block's score, write the allocation down, and commit to leaving it alone.

Deliverable: A scored rubric and a fixed hour allocation for the rest of the week.

Practice prompt ↗Practice prompt ↗Worked solution ↗
02Largest gap: find the boundary rather than the subject
  • Split the weakest area into named sub-skills and rate each separately. For coding those are restating the problem, choosing the structure, stating the invariant, turning the invariant into loop bounds, handling empty and single-element input, and accounting for complexity out loud.
  • Attempt three items positioned just above where the rating drops off, and for each write the first move you failed to make.
  • Re-attempt one of them from blank four hours later with nothing open.

Deliverable: A sub-skill map with the two blocking sub-skills circled.

Practice prompt ↗Practice prompt ↗
03Drill the blocking sub-skill by repeating the shape
  • Do eight short repetitions of the same shape rather than eight different problems, so what gets practised is the pattern and not the puzzle.
  • State the rule you now hold in one sentence, then test it against a case built to break it, a sliding window over an array containing negative values, or a cache-aside read path whose invalidation message is dropped.
  • Have someone else read your one-sentence rule and find the precondition you left out.

Deliverable: One rule statement with its preconditions attached and one counterexample that would have caught the incomplete version.

Practice prompt ↗Practice prompt ↗
04Second gap, plus maintenance on the strongest area
  • Run the same sub-skill decomposition on the second-largest gap in half the time.
  • Spend twenty-five timed minutes on the block you scored highest, choosing the hardest item you can still finish rather than a warm-up.
  • Write whether each area fails you on recall, on setup, or on execution, and set the fix accordingly: repetition for recall, a written checklist for setup, timed work for execution.

Deliverable: A second sub-skill map plus a one-line failure diagnosis for each area.

Practice prompt ↗Practice prompt ↗Worked solution ↗
05The gap that is not a skill
  • Record one technical and one behavioural answer, then count two things in the playback: seconds before your first clarifying question, and sentences you began without knowing where they would end.
  • Practise saying that you do not know, followed by how you would find out, without letting it soften into a guess, and practise stating a complexity or an estimate before being asked for it.
  • Redeliver one answer under a hard ninety-second cap, which forces structure ahead of detail.

Deliverable: Two recordings with a counted reduction in time-to-first-question.

Practice prompt ↗Practice prompt ↗
06Retest under day-one conditions
  • Sit the same 110-minute structure with new prompts of comparable difficulty and score it on the identical rubric.
  • For any block that did not move, change the method rather than adding hours: a block stuck at 1 usually means the practice was too varied, not too short.
  • Write down which single block you would still lose the offer on.

Deliverable: A second scored rubric placed beside the first, with one named remaining risk.

Practice prompt ↗Practice prompt ↗
07Full loop under interview conditions
  • Run a sixty-minute mock over the two blocks that moved least, with an interviewer briefed to interrupt and change direction mid-answer.
  • Write the recovery script for going blank: restate the question, state your assumption, name the first thing you would check.
  • Say every rule from the week aloud without reading it, and cut any you cannot state in a single sentence, since a rule you have to reconstruct mid-answer will not survive an interruption.

Deliverable: A one-page card holding the recovery script and only the rules you could state from memory.

Practice prompt ↗Practice prompt ↗Worked solution ↗

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

Every story you tell gets read for blast radius and judgement: what could have broken, who else it touched, what you knew at the moment you decided. Nobody can audit your code in an hour, so they audit your reasoning instead. Pick work where the call was genuinely yours and the consequences were real enough to remember.

How do you handle concurrency in your application design?

medium
behavioural and engineering judgement

How do you handle concurrency in your application design?

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

Ship to a fixed date with debt you can name

medium
deadlinestechnical debtrisk

Prepare a five-minute account of shipping to a date that could not move, with shortcuts you took knowingly. Pick work where the load was also spiky — a launch, a seasonal rollover, a migration window — rather than a routine sprint. Constraint: name at least two shortcuts you took deliberately and one you refused, and say which invariant each one put at risk. Deliverable: the decision as it stood at the time, the kill switch or fallback you kept, the debt's paid-or-open status today, and what you would cut first if the date moved closer.

Approach
  1. Anchor on what made the date immovable and what made the load spiky. An event or rollover that multiplies write volume by 20 to 50 times for a few hours is not simply more of the same traffic; it is the concurrency at which lost-update and duplicate-write races stop being theoretical and start firing on every deploy.
  2. Classify each shortcut by reversibility. A skipped cache warm is recoverable in minutes. A skipped unique index on an idempotency key creates value or state you cannot claw back once it has moved between accounts. Strong answers cut only in the recoverable column and say explicitly that the line exists.
  3. Name the refusal and its price in days or scope. Someone who cut nothing was not really under a deadline; someone who cut everything had no line. The refusal is where the judgement is visible.
  4. Describe the fallback you kept live: a flag that disables the path without a deploy, a consumer you could pause, a dual-write with the old path still authoritative. Say who could pull it at three in the morning and whether that person had been told.
  5. Close with the debt's state today and the mechanism that kept it visible — a ticket with an owner and a trigger condition beats a wiki page. 'We never went back' is an acceptable ending only if you can say what made it acceptable.
Follow-up
  • Which of those shortcuts would you refuse at any deadline now, and what changed your mind?
  • How did you communicate the residual risk to whoever owned the date?

Decide a rollback that also reverses legitimate user actions

hard
irreversibilityincident responsestakeholders

Prepare a six-minute account of an incident where the clean fix would also have undone correct work by real users — a replayed batch, a bad backfill, value granted twice and then spent. Constraint: you must give the option you rejected and the number that decided it. Deliverable: how you bounded the affected set, the three options you weighed (full reversal, partial reversal under a rule, absorb the loss and close the hole), who outside engineering had to agree, and how you explained the residual harm to someone who does not read code.

Approach
  1. Start with bounding, because every option depends on it: the predicate that separates affected rows from unaffected ones, the time window you were willing to trust, and your confidence at the edges. Say what you did with rows you could not classify, and that over-including or under-including them was a deliberate choice rather than an accident.
  2. Lay out the three options with their asymmetric costs. Full reversal is the cheapest to implement and the hardest to defend, because it reverses correct actions taken in good faith. Partial reversal needs a rule a support agent can restate in one sentence. Absorbing the loss costs money once and preserves trust, but only if you can show the hole is closed.
  3. Give the number that decided it — affected accounts, value at stake, ratio of collateral to genuine — and name who owned the decision. An incident of this shape is rarely solely an engineering call, and treating it as one is itself the scope error the question is looking for.
  4. Describe how you made the repair idempotent and re-runnable, because a compensation applied twice is a second incident on top of the first. A reversal written as a new row referencing the original can be audited and replayed; an in-place update cannot be either.
  5. Close with the prevention and the proof it holds: the constraint added, the test that fails without it, and the monitor that would catch the same shape arriving from a different source.
Follow-up
  • Support cannot restate your partial-reversal rule in one sentence. What do you change — the rule or the explanation?
  • Some of the value was already spent before you acted. Do you leave a negative balance carrying a debt, or record a shortfall that blocks future spending?
  • How would you make the same call with half the data and half the time?
  • 01

    How do you handle concurrency in your application design?

  • 02

    Prepare a five-minute account of shipping to a date that could not move, with shortcuts you took knowingly. Pick work where the load was also spiky — a launch, a seasonal rollover, a migration window — rather than a routine sprint. Constraint: name at least two shortcuts you took deliberately and one you refused, and say which invariant each one put at risk. Deliverable: the decision as it stood at the time, the kill switch or fallback you kept, the debt's paid-or-open status today, and what you would cut first if the date moved closer.

  • 03

    Prepare a six-minute account of an incident where the clean fix would also have undone correct work by real users — a replayed batch, a bad backfill, value granted twice and then spent. Constraint: you must give the option you rejected and the number that decided it. Deliverable: how you bounded the affected set, the three options you weighed (full reversal, partial reversal under a rule, absorb the loss and close the hole), who outside engineering had to agree, and how you explained the residual harm to someone who does not read code.

PracHub interview preparation framework ↗
Is this an official Liftoff interview guide?

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

PracHub interview research ↗
How long does the interview process take?

The process typically spans 4 to 8 weeks, though it can be expedited for strong candidates. The recruiting team is known for being highly responsive and efficient in scheduling.

PracHub interview research ↗
Is the 4-hour coding project difficult?

It is designed to be a realistic reflection of the work you would do on the job. Focus on creating a working, well-structured solution rather than over-engineering the design.

PracHub interview research ↗
How do I stand out?

Successful candidates demonstrate a strong sense of ownership and an ability to communicate their thought process clearly while coding. Showing that you can iterate on your own work is highly valued.

PracHub interview research ↗
Does Liftoff offer remote work?

Policies can vary by team and location, but Liftoff has successfully conducted many remote interview processes. Clarify specific location requirements with your recruiter early on.

PracHub interview research ↗
Sources & methodology 3 sources ↗

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