The source notes describe the Suno Software Engineer role as building the features and infrastructure behind the product, from the frontend interface to the backend API services. Named areas include the Pro-Create experience, Trust & Safety systems and core Platform teams, plus Growth. Reliability and performance work is reported to focus on billing, user credits and audio delivery. The listed responsibilities also include code review and troubleshooting production issues.
For interview purposes, that points to two areas of question. One is general engineering: data structures, clean code under time pressure, database performance and data modeling. The other is specific to this product: streaming audio to many listeners, charging for generation through credits and subscriptions, and moderating user-uploaded audio. The reported topic list (credits and entitlements, billing infrastructure, subscription lifecycle, dunning flows, revenue recovery) suggests the billing side deserves more of your preparation than it usually gets in a generic system design review.
The listed must-have skills are a modern language such as Python, TypeScript or Go, cloud infrastructure experience on AWS or GCP, and a solid grasp of system design. Generative AI experience, familiarity with audio processing frameworks and payment integrations such as Stripe or RevenueCat are listed as nice-to-haves. If you have none of the nice-to-haves, prepare by reasoning through the problems they solve: idempotent charges, subscription state transitions and failed-payment recovery. You can discuss those confidently without having used either vendor.
Recruiter Screen
reportedCandidates describe this as a first conversation with a recruiter about your background and role fit. Use it to learn what the next stage will be. Ask whether the technical assessment is a live screen or a take-home (some candidates report large take-home assignments), what scope and time investment is expected, and which team the opening sits on, since the role description spans Pro-Create, Trust & Safety, Platform and Growth. State any hard constraints now, such as start date, location, work authorisation and compensation expectations, rather than at offer stage. Candidates also note that scheduling can be fluid, so agree on how and when you will hear back.
What to demonstrate
- Whether your background maps to the work described for the role: product features end to end, backend APIs, and reliability work on billing, credits or audio delivery
- Whether you can say specifically why this product interests you, since a question about the intersection of AI and music is reported for the role
- Whether your constraints and expectations fit the role before a full loop is scheduled
How to prepare
- Use the Suno product before the call and write down one concrete observation about the experience that you could connect to engineering work
- Prepare a short background summary built around one shipped production feature, naming your part in it and what changed for users
- Ask directly about the technical assessment format, whether a take-home is involved, and its expected scope, so you do not over-invest in it
Technical Assessment
reportedCandidates describe this stage as a technical screen that includes standardized coding challenges. The reported coding questions for the role are not attributed to a particular round, but they are the best available sample of the category: a circular buffer for audio data streams, a retention rate calculated from session events over a time window, and anomalous pattern detection in request logs. The source's notes on coding also mention hash maps, trees and queues, concurrency when handling multiple generation requests, and error handling that fails gracefully. They also cite example prompts such as an API rate limiter and the top K most active users in a stream. Prepare for correctness on boundaries as much as for speed.
What to demonstrate
- Correct handling of edge cases: an empty or full buffer, wraparound, inclusive window boundaries, users counted once rather than once per event
- Whether you state time and space complexity and explain why the chosen structure fits
- Readable code with explicit handling of invalid input, rather than code that only works on the example
How to prepare
- Implement a fixed-capacity circular buffer that overwrites the oldest samples and returns reads in order, then test capacity one, exact fill and one write past capacity
- Write the retention calculation with a set per cohort and a clearly stated inclusive window, and test an empty cohort
- Drill sliding-window counting per user and endpoint (anomaly detection, rate limiting) and a heap-based top K, saying the complexity of each out loud
- Work the Order a job dependency graph worked exercise in this guide to practise stating complexity for each part of a multi-step problem
Final Round
reportedCandidates describe the final round as a panel-based onsite focused on design discussions and engineering maturity. The source's process notes say to expect a range of team members, including engineering managers and senior individual contributors, in a conversational format. The reported design questions are not tied to a specific round. They are: an audio player and playlist system with low-latency streaming for millions of users, a credit-based subscription system with usage-based billing, a service for real-time content moderation of uploaded audio, and high availability with data consistency in a distributed system. The source's design notes add database schema design for accounts, subscription states and credit systems, versioned API design, and caching, load balancing and asynchronous processing, plus scenarios such as a sudden tenfold traffic spike on an audio generation endpoint.
What to demonstrate
- Whether you clarify scale, constraints and user requirements before drawing components
- Whether your schema and API hold up for accounts, subscription states and credit balances under concurrent use
- Whether you name failure modes and bottlenecks, and how the system degrades under a traffic spike
- Whether you can explain a technical trade-off to a non-technical partner and respond to pushback without defending by authority
How to prepare
- Take each reported design prompt end to end once: requirements, API, data model, the read and write paths, then the failure you are designing for
- For the credit system, write the ledger schema, an idempotent debit per generation request, the refund path when generation fails, and the subscription states including a failed renewal
- Prepare how you would absorb a tenfold spike on a generation endpoint: queueing, admission control, and what the user sees while waiting
- Have stories ready on team conflict, a change in requirements and feedback from non-technical stakeholders in case the panel turns to them
PracHub editorial advice for the preparation topics above.
Leaving full and empty indistinguishable in the reported circular buffer question
If head equals tail means both 'empty' and 'full', the buffer silently drops a whole capacity's worth of audio or returns stale samples. Track a separate count, or reserve one slot, and say which you chose. State the overwrite policy before coding: when the buffer is full, a write advances the read position and discards the oldest sample. Then test capacity one, an exact fill, one write past capacity, and a read after wraparound to confirm samples come back oldest first.
Counting session events instead of distinct users in the retention-rate question
Retention is a ratio of users, so a user with ten sessions inside the window must count once. Define the cohort first (who was active at the start), put each window's user ids in a set, and divide the size of the intersection by the cohort size. Say whether the window boundaries are inclusive, and say what you return for an empty cohort instead of dividing by zero. Then state the complexity: one pass over the events plus set operations.
Designing the credit system as one mutable balance that is read, checked and then written
Two generation requests arriving together both read enough credits and both spend, so the balance goes negative. Model credits as an append-only ledger of grants, debits and refunds. Make the debit a single conditional write (decrement only where the balance covers the cost) with an idempotency key per generation request, so a client retry does not charge twice. Add a refund entry when generation fails. Then cover the subscription side the reported topics point to: renewal, a failed payment, the dunning retries, and what the user can still generate while the account is past due.
Treating real-time moderation of uploaded audio as one synchronous check on upload
Split the design into what must block publication and what can run asynchronously, and say what the uploader sees while a file is pending. Name the cost of each error: a false negative publishes harmful audio, and a false positive blocks a legitimate creator, so include a review or appeal path. Explain how the queue absorbs an upload spike without delaying every file, and how already-published audio gets re-checked when a detection model changes.
Answering the reported 'why AI and music' question with general enthusiasm and no specifics
The source notes advise using the product before interviewing and having an informed view of what AI can and cannot do. Bring one concrete observation from your own use of Suno, one capability and one limitation you have thought about, and connect them to engineering work you would want to do, such as generation latency, credit fairness or moderation. Keep it professional if the conversation turns to your views on AI in your own craft, which the source also mentions as a possible turn.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
Implement a function to manage a circular buffer for audio data stream…
Implement a function to manage a circular buffer for audio data streams.
Approach
- State the target complexity and say which constraint rules the naive version out.
- Name the brute-force solution and its complexity before improving on it.
- 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?
- What is the worst case, and how likely is it on real data?
Order a job dependency graph and find its critical path
A workspace defines up to 50,000 jobs with up to 200,000 dependency edges and an estimated duration_seconds per job. Given the edge list, reject the graph if it contains a cycle and name one cycle's nodes; otherwise return a valid execution order, the earliest possible completion time with unlimited workers, and the set of jobs whose slack is zero. Then say which single job to shorten in order to cut the completion time, and by exactly how much. State the complexity of each part.
Approach
- Kahn's algorithm for the order: compute indegrees, seed a queue with zero-indegree nodes, emit and decrement. O(V + E), which at 50,000 and 200,000 is milliseconds. If fewer than V nodes are emitted, the graph contains a cycle.
- Kahn detects a cycle but cannot name one. The nodes left with indegree above zero contain every cycle, so run one DFS restricted to that residual subgraph with three-colour marking and report the stack slice from the grey node the back edge points at. That is the difference between a usable error message and 'dependency cycle detected'.
- Earliest completion with unlimited workers is the longest path, which is NP-hard on a general graph and linear on a DAG. State the precondition, then relax in topological order:
earliest_finish[v] = duration[v] + max(earliest_finish[u] for u in preds(v)), taking the max over an empty predecessor set as zero. The makespan T is the maximum over all nodes. O(V + E). - Second pass in reverse topological order for
latest_finish, thenslack[v] = latest_finish[v] - earliest_finish[v]. Zero-slack nodes form the critical path, and there can be several disjoint critical paths, so return the set rather than one chain.slack[v] = 0is exactly the statement that some longest path runs through v; equivalently, the longest path through v has lengthT - slack[v]. - The speed-up bound is the point of the question, and the obvious form of it is wrong. Shortening a zero-slack job v by d, with 0 <= d <= duration[v], cuts the makespan by
min(d, T - L_avoid(v)), whereL_avoid(v)is the longest path in the graph with v deleted: the longest path that avoids v, not the second-longest path overall. The two coincide only when the runner-up path misses v. Counterexample: A of 10 s feeds both B of 5 s and C of 4 s, so T = 15 s and the second-longest path is 14 s, yet shortening A by 10 s leaves a makespan of 5 s. The realised gain is the full 10 s, because both paths ran through A and shrank together, whilemin(10, 15 - 14)predicts 1 s. The reason is structural: shortening v reduces every path through v by d and leaves every other path alone, so the new makespan ismax(T - d, L_avoid(v)). - Compute
L_avoid(v)the direct way: delete v and re-run the same forward relaxation, O(V + E) per candidate. The cheaper equivalent skips the deletion, sinceL_avoid(v)only ever matters through that max: setduration[v] := 0, recompute the makespan asT0(v) = max(T - duration[v], L_avoid(v)), and the gain ismin(d, T - T0(v)), which is identical for every d <= duration[v]. Only zero-slack jobs are candidates, because shortening a job with positive slack changes the completion time not at all. One relaxation is milliseconds at this size, so ranking a critical set in the hundreds costs O(k(V + E)) and is worth doing exactly; a critical set in the tens of thousands is not, and there you evaluate a shortlist, longest jobs first, and say that the answer is the best of that shortlist rather than the optimum.
Worked solution 30 min
- Build four fixtures. A: 12 jobs, two branches of 100 s and 95 s that share no job. B: fixture A plus one back edge. C: two disjoint paths tied at 100 s. D: the shared-prefix case, one job of 10 s feeding a 5 s job and a 4 s job, so the longest path is 15 s and the runner-up is 14 s.
- Run Kahn; on fixture B confirm it emits fewer than V nodes, then run the residual-subgraph DFS and print the actual cycle.
- Compute
earliest_finishforward andlatest_finishbackward, and list the zero-slack set for each fixture. - For each zero-slack job v, recompute the makespan with
duration[v] := 0to getT0(v), and record both the correct boundT - T0(v)and the wrong one,T - second_longest_path, side by side. - Apply the shortening for real (20 s off the critical branch of A, 10 s off the shared prefix of D) and diff the recomputed makespan against each prediction.
Follow-up
- Only m workers are available. What happens to your answer, and what can you still promise about the schedule you produce?
- Edges arrive incrementally as the customer edits the pipeline. How do you detect a cycle at insert time without re-running Kahn over 250,000 elements?
- Durations are estimates. How would you express completion time as a distribution, and what breaks about the critical path once you do?
Seal an hour under late data with bounded memory
Metering ingest reads 256 partitions at 10,000 to 40,000 events/second. Events carry occurred_at and ingested_at, and during a producer replay the gap between them is hours. Seal each UTC hour once no more than 50 parts per million of that hour's eventual quantity can still arrive, using memory that does not grow with the size of the replay. Define the watermark, the lateness parameter and how you measure it, the structure holding open hours, and the write that performs the seal. State what an idle partition does to your watermark.
Approach
- Two clocks, two jobs. Bucket by
occurred_at, because that is the hour the customer is billed for, and advance the watermark oningested_at, because that is what the fold has consumed and whatsource_max_ingested_atrecords. Conflating them is what makes late data invisible. - The global watermark is the min over partitions of each partition's committed
ingested_at, not the max: the fold is trustworthy only as far as the slowest partition. The consequence is that one idle partition pins the watermark forever and nothing seals, so an idle partition must promote its watermark to wall clock after a stated idle timeout, and that timeout becomes a correctness parameter, because a partition that is slow rather than idle gets sealed past. - Choose the lateness L from the measured distribution of
ingested_at - occurred_at, weighted by quantity rather than by event count. The target is 50 ppm of the hour's quantity, and a replay is rare in events while carrying disproportionate mass, so an event-weighted quantile picks an L that is comfortably wrong at exactly the moment it matters. - Measure that quantile in bounded memory. A Greenwald-Khanna summary gives epsilon-approximate quantiles in O((1/epsilon) log(epsilon n)) space; a t-digest costs more per merge but has relative error that tightens at the tails, which is the half of the distribution you are reading at p99.99. Keep a separate summary per tenant class, because one tenant's batch importer is not the population.
- Hold open hours in a min-heap keyed by
hour_start. When the watermark advances, pop every hour withhour_end + L < Wand seal it: O(log H_open) per advance and O(1) amortised per event to touch its bucket. Memory is open hours multiplied by distinct(tenant, workspace, sku)keys, so cap the number of simultaneously open hours and spill the oldest intousage_rollup_hourlyasstatus='open'with arevisionbump. While an hour is open the row is upsertable, so the store is your overflow. - The seal itself is a conditional write:
update ... set status='sealed', sealed_at=now() where status='open' returning .... Two sealers race on every restart, and the loser must see zero rows and stop rather than write a second value. After the seal, an event for that hour is not an upsert but an adjustment, andsource_max_ingested_atis what proves it arrived afterwards.
Follow-up
- A replay starts during the sealing window for a period you are about to close. What do you do, and what is the customer-visible consequence of each option?
- Your measured quantity-weighted p99.99 lateness is six hours and the invoice must be issued at 02:00 UTC on the first. How do you reconcile those two numbers?
- How would you detect that L has drifted before it costs you an hour's quantity?
Decide which facts an invoice line copies instead of joining
invoice_line_item already denormalises tenant_id, which is reachable through invoice_id, and stores amount_minor even though quantity times unit_price_micros would recompute it. A reviewer asks you to normalise both away, and separately asks whether the tenant's legal name and billing address should be copied onto the invoice header. Decide each case. For every field you keep denormalised, name the read pattern or the invariant that justifies it, the anomaly the copy can develop, and the mechanism that prevents that anomaly here.
Approach
- Split the question into two kinds of copy, because they fail differently. A copy of a currently mutable fact is a cache: it drifts and needs invalidation. A copy of a fact frozen at write time is not a cache at all, it is the record of what happened, and normalising it away destroys information the source no longer holds.
- Keep tenant_id on the line. It costs 8 bytes, it leads every index on the table so no read is ever accidentally cross-tenant, and it turns a wrong join into an empty result rather than another tenant's money. Prevent the drift structurally: a unique constraint on invoice (invoice_id, tenant_id) plus a composite foreign key from the line on (invoice_id, tenant_id) makes a mismatched pair impossible, so the database enforces agreement instead of a code review.
- Keep amount_minor. Rounding must happen exactly once, at a named site, with a stated mode (half-even here). If readers recompute from quantity and unit_price_micros, every reader owns a rounding decision, and half-up and half-even diverge systematically across thousands of lines rather than cancelling out. A check constraint can bound the stored value but deliberately cannot re-derive it.
- Copy the legal name and billing address onto the invoice header, written once and never updated. The statement must show what was true when it was sealed, and the tenant record will change afterwards. This is a snapshot for the same reason
source_rollup_watermarkis stored per line: without it, nobody can reconstruct what the customer was told. - Name the read pattern that pays for all of it. Rendering, dispute response and export are per-tenant, per-period reads over thousands of lines that would otherwise join back to slowly changing dimensions that no longer hold the historical value. The write side is a once-per-period batch, so the extra columns cost nothing that matters.
- Concede the case where the reviewer is right: a mutable operational attribute such as the tenant's current plan name has no business on a line. If a report wants it, join. If a statement needs the plan as of the period, that is another snapshot and it belongs on the header with the rest.
Worked solution 25 min
- Write the DDL: unique (invoice_id, tenant_id) on invoice, the composite FK from the line, and a comment on each denormalised column saying whether it is a snapshot or a cache.
- Attempt to insert a line whose tenant_id differs from its invoice's and confirm the foreign key rejects it.
- Rename a tenant, re-render a sealed invoice, and confirm the rendered name is the one stored on the header.
- Recompute amount_minor from quantity times unit_price_micros for a thousand synthetic lines rounding half-up, sum both ways, and record the divergence from the stored half-even values.
Follow-up
- Write the composite foreign key and the unique constraint it requires on the parent. What does it cost on every line insert, and what does it do to a bulk load?
- A tenant is renamed after being invoiced. Which rows change, and what does the customer see on last quarter's PDF?
- Where does currency live, and what breaks if a tenant's billing currency changes between two periods?
Find the join that inflates every invoice total
invoice_line_item holds line_id, invoice_id, tenant_id, sku, rate_tier, quantity, unit_price_micros, amount_minor (bigint), currency, kind, voided_at. invoice_payment_attempt holds attempt_id, invoice_id, tenant_id, amount_minor, status (succeeded, failed, pending), created_at, and an invoice has many attempts. A finance report runs select i.invoice_id, sum(l.amount_minor), count(p.attempt_id) from invoice i join invoice_line_item l using (invoice_id) join invoice_payment_attempt p using (invoice_id) group by 1 and the totals are wrong. Say precisely what the sum now equals, and write a version that is also correct for invoices with zero attempts.
Approach
- Compute what the query actually returns before fixing it. The two joins form a Cartesian product per invoice, so each line row repeats once per attempt row:
sum(l.amount_minor)is the true total multiplied by the attempt count, andcount(p.attempt_id)is attempts times lines. Three lines and two attempts report double the money and six attempts. - Reject the reflex repair.
count(distinct p.attempt_id)does fix the count, because attempt_id is unique.sum(distinct l.amount_minor)does not fix the sum, because two legitimate lines with equal amounts collapse into one. DISTINCT inside an aggregate deduplicates values, not rows, and the difference stays invisible until two lines happen to match. - Aggregate each branch to invoice grain before joining: one CTE summing lines by invoice_id, one counting attempts by invoice_id, then join the two results. A LATERAL subquery per invoice is equivalent and sometimes plans better when the outer set is small. Either way every aggregate stays at the grain it was defined at.
- Keep invoices with no attempts by making the attempt branch a LEFT JOIN with
coalesce(attempt_count, 0). An inner join here silently drops every unpaid invoice, which is usually the exact population finance is asking about. - Push each filter to its own grain:
where l.voided_at is nullbelongs inside the line CTE, not the outer query, or it would also filter the attempt branch through the join. Put the tenant predicate on both branches, since the denormalised tenant_id is what stops a wrong join crossing tenants. - Leave yourself a standing check: an invoice total is a function of its non-voided lines and of nothing about payments, so if changing the payment filter moves the money figure, the fan-out is back.
Follow-up
- Add a third branch for credit notes applied to the invoice. Does the CTE shape still hold, and when would a single pass with
filter (where ...)be better? - Over 500k invoices this report takes minutes. Which grain would you materialise, and how do you keep it correct when a line is voided?
- The same report is needed per tenant per month. What index makes the line CTE cheap?
Design an audio player and playlist system that supports low-latency s…
Design an audio player and playlist system that supports low-latency streaming for millions of users.
Approach
- Choose a partition key and say what query it makes expensive.
- Name the failure you are designing for, then the recovery path.
- Fix the scope first: who calls this, how often, and what they do when it fails.
Follow-up
- How does this behave when that dependency is down for an hour?
- What breaks first when traffic grows ten times?
How would you architect a credit-based subscription system that handle…
How would you architect a credit-based subscription system that handles usage-based billing?
Approach
- Fix the scope first: who calls this, how often, and what they do when it fails.
- Name the failure you are designing for, then the recovery path.
- State the consistency you need, and where you are willing to be stale.
Follow-up
- What would you drop to keep the system up under load?
- What breaks first when traffic grows ten times?
Explain how you would design a service to handle real-time content mod…
Explain how you would design a service to handle real-time content moderation for uploaded audio files.
Approach
- Name the failure you are designing for, then the recovery path.
- Name the read and write paths separately; they rarely have the same bottleneck.
- Fix the scope first: who calls this, how often, and what they do when it fails.
Follow-up
- What would you drop to keep the system up under load?
- How does this behave when that dependency is down for an hour?
Specify webhook signature verification a customer can implement
The webhook-delivery service signs each payload before POSTing it to a customer endpoint. Write the signature specification a customer implements in their own language: the header format, exactly which bytes are signed, the algorithm, how replay is bounded, and how a signing secret rotates without a delivery gap. Then write the verification steps the customer performs, in order, including what they compare and what they return on failure. Constraint: most customers reach for their web framework's parsed JSON body by default. Deliverable: the spec section plus reference pseudocode.
Approach
- Sign the concatenation of the timestamp and the raw body,
t + "." + body, and emit a header of the formt=<unix seconds>,v1=<hex>. The timestamp has to be inside the MAC, or an attacker re-stamps a captured body and the tolerance window buys nothing. - Require the raw request bytes. A framework that parses JSON and re-serialises it changes key order, whitespace and number formatting, so the spec must tell the customer to capture the body before the parser runs and give the middleware note for each common framework.
- Use HMAC-SHA256, not sha256(secret || body): SHA-256 is a Merkle-Damgard construction, so the naive form admits length extension. Require a constant-time comparison as well, since a short-circuiting byte compare leaks the expected prefix under repeated probing.
- Bound replay in two layers: reject when |now - t| exceeds a stated tolerance such as 300 seconds, then deduplicate on the event identifier header. The tolerance is what makes the customer's dedup store finite rather than unbounded.
- Rotate by allowing two live secrets and emitting both signatures in one header (
v1=<old>,v1=<new>); the customer accepts if any candidate matches, so neither side needs an instantaneous cutover. A failed verification returns 400 and the body is not processed.
Worked solution 15 min
- Write the header grammar and one real example line with a plausible timestamp and hex digest.
- Write the signed string construction explicitly as a byte concatenation, and add the sentence telling the customer where in their framework to obtain the raw body.
- Write the five verification steps in order: extract t and candidates, check the tolerance, recompute the HMAC over t + '.' + raw body, compare in constant time against each candidate, then deduplicate on the event identifier.
- Add the rotation paragraph: two active secrets, both signatures sent, overlap window stated in the dashboard.
- State the failure response and the fact that the payload is not processed, plus what the sender does with that 400.
Follow-up
- A customer's verification passes locally and fails in production behind a proxy that re-encodes the response body. Where do you look first?
- Why sign with a per-endpoint secret rather than the tenant's API key?
Gateway p99 spikes on a five-minute cadence
edge-gateway caches each credential-to-authorisation-context decision for five minutes. p99 sits at 6 ms except for a spike to 900 ms roughly every five minutes, worst in the region with the most pods, and control-plane CPU and read latency rise in step with it. The error rate stays near zero. Customers are told a revoked credential stops authorising within 60 seconds. Give the ordered checklist that identifies the mechanism, and a fix that removes the spike without weakening the 60-second bound.
Approach
- Test periodicity before anything else: take the spike timestamps modulo the TTL in seconds. A tight cluster at a fixed offset means expiry phase, while traffic-driven spikes scatter.
- Overlay pod start times. Entries filled at first request inherit the phase of the pod that filled them, so a cohort of pods deployed together expires together and the amplitude should track cohort size rather than tenant count.
- Separate a herd from a capacity shortfall by measuring control-plane requests per second during a spike against baseline. A stampede shows a step of roughly (pods x hot keys) for one interval with hit rate collapsing to near zero, not a gradual climb that would indicate the dependency is simply undersized.
- Apply three independent controls: randomise each key's TTL by a factor drawn uniformly from something like 0.8 to 1.0 so cohorts de-phase; coalesce concurrent misses per key per pod so exactly one refresh is in flight; and serve the stale value while that refresh runs so a miss costs the stale read rather than the dependency's queue.
- Bound staleness against the published contract rather than against comfort: serve-stale is admissible only up to the 60-second revocation bound, so the TTL floor and the stale window together must stay inside it, and the published invalidation must delete the entry rather than schedule a refresh.
- Decide in advance what a miss does when the control plane is unreachable, because that is now the only uncached path: failing closed converts a dependency outage into a total outage, while extending stale service past the bound breaks the revocation promise. Pick one and configure it explicitly.
Follow-up
- Publish-subscribe invalidation is lossy under a partition. Given that, what actually enforces the 60-second bound, and what number would you put in the contract if asked to defend it?
- One tenant's key is hot enough that a single pod's coalesced refresh still matters. What changes?
- Would a shared cache tier in front of the control plane help or shift the problem, and what new failure does it add?
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.
Prepare, practise & reflect
One practical outcome each day. Spend longer where you need it.
0 / 7 done01Reported coding: buffers and retention
- Implement a fixed-capacity circular buffer for audio samples that overwrites the oldest sample when full and returns reads in order; handle full and empty explicitly
- Test the buffer with capacity one, an exact fill, one write past capacity, and a read after wraparound
- Write the retention-rate calculation over session events: define the cohort, dedupe users with sets, state whether the window is inclusive, and handle an empty cohort
- State the time and space complexity of both solutions out loud as if to an interviewer
Deliverable: Two working solutions with the edge-case tests written out and the complexity stated for each.
Practice prompt ↗Practice prompt ↗Worked solution ↗02Sliding windows, rate limits and top K
- Solve the reported anomalous request pattern detection with per-user, per-endpoint sliding windows against a frequency threshold
- Implement an API rate limiter and compare a fixed window with a sliding window, noting the burst each one allows at a boundary
- Find the top K most active users in a stream with a heap and state the complexity
- Work the Order a job dependency graph worked exercise in this guide and check your complexity statements against it
Deliverable: Three solutions with complexity notes and one written comparison of rate-limiting windows.
Practice prompt ↗Practice prompt ↗03Data: slow queries and store choice
- Take a query that is slow at peak usage and write the diagnosis order: the query plan, missing or unused indexes, row estimates against actual rows, lock waits, then caching or read replicas
- Write the trade-offs between a relational database and a NoSQL store for user-generated content such as songs and playlists, naming the access pattern that decides it
- Work the invoice-line worked exercise in this guide (Decide which facts an invoice line copies instead of joining), then try the join fan-out drill on invoice totals
Deliverable: A one-page query-latency checklist and a written relational-versus-NoSQL decision for a named access pattern.
Practice prompt ↗Practice prompt ↗04Design: credits and usage-based billing
- Design the reported credit-based subscription system: ledger schema, an idempotent debit per generation request, refunds when generation fails, and balance reads
- Map the subscription lifecycle states, including a failed renewal, dunning retries and recovery, and decide what a past-due user can still do
- Work the webhook signature worked exercise in this guide, since payment providers deliver billing events the same way
- Write the versioned API for credits and subscriptions that the client would call
Deliverable: A credit and subscription design with a schema, state diagram, API list and the concurrency failure it prevents.
Practice prompt ↗Practice prompt ↗Worked solution ↗05Design: audio streaming and traffic spikes
- Design the reported audio player and playlist system with low-latency streaming: storage, CDN delivery, playlist data model and the read path
- Plan how a generation endpoint absorbs a sudden tenfold traffic spike: queueing, admission control, autoscaling limits, and what the user sees
- Write where you need strong consistency (credits, playlist edits) and where stale reads are acceptable (play counts, recommendations), which covers the reported high-availability question
Deliverable: A streaming design with its hot path, its spike plan and a written consistency map.
Practice prompt ↗Practice prompt ↗06Design: moderation and operating under failure
- Design the reported real-time moderation service for uploaded audio: what blocks publication, what runs asynchronously, the review and appeal path, and re-checking when models change
- Estimate the backlog under an upload spike and say which uploads you would prioritise
- Work the gateway cache-stampede debugging drill in this guide and write the ordered checklist before reading the approach
Deliverable: A moderation design with its error costs named, plus a debugging checklist for a periodic latency spike.
Practice prompt ↗Practice prompt ↗07Product, behavioral stories and a mock panel
- Use the Suno product and write one observation you could connect to the credit, streaming or moderation designs
- Prepare stories for the reported prompts: a team conflict, a change of approach after requirements shifted, feedback from non-technical stakeholders, a challenging situation, and why AI and music interest you
- Run one mock design discussion where a partner changes a requirement partway through, then explain your key trade-off to someone non-technical
Deliverable: Five behavioral stories in outline form, one product observation, and notes from a mock design discussion.
Practice prompt ↗Worked solution ↗Expand any day for tasks and deliverables. Your progress is saved on this device.
The behavioral questions reported for this role focus on conflict, changing requirements, working with non-technical partners and your interest in AI and music. For each story, give a short situation, spend most of the answer on your reasoning and actions, and close with a measurable result or what you would change. For the AI and music question, draw on your own use of the product rather than general enthusiasm.
How do you handle feedback from non-technical stakeholders?
How do you handle feedback from non-technical stakeholders?
Approach
- State the situation in two sentences and spend the rest on the reasoning.
- Close with what you would do differently, concretely.
- Name the disagreement and how you resolved it with evidence.
Follow-up
- How did you know your change caused the improvement?
- What did you decide not to do, and why?
Describe a challenging work situation and how you navigated it to reac…
Describe a challenging work situation and how you navigated it to reach a resolution.
Approach
- Name the disagreement and how you resolved it with evidence.
- Give the blast radius: what could have broken, and what you measured.
- Close with what you would do differently, concretely.
Follow-up
- What would you do differently if you ran that again?
- How did you know your change caused the improvement?
Ship metered billing with a named deduplication horizon
Metered billing must be on in three weeks. usage_event is partitioned daily, so its unique index must include the partition key and deduplicates only within a day: a producer retry that crosses midnight, or a replay run a week later, gets through. A cross-partition dedup store is two weeks you do not have. Describe shipping with debt you named in advance: what you shipped, what you wrote down, the detector you added, the trigger and date for paying it off, and what you would have refused to ship under the same pressure.
Approach
- Show you can separate the two kinds of debt, because that distinction is what the question actually probes. Debt that costs engineering time later is shippable on a deadline. Debt that silently corrupts a number a customer gets charged for is not shippable unless the corruption is detectable, and detectability is the whole negotiation.
- Make the exposure narrow and measured rather than gestural. The hole is duplicates whose occurrences straddle a UTC day boundary, plus any replay older than partition retention. Measure it before arguing about it: how often an idempotency_key recurs at all, and the distribution of the gap between first and last occurrence. If the ninety-ninth percentile of that gap is four minutes, the residual risk is a small band around midnight and you can say so numerically.
- Add the detector before the feature, not after. A nightly job counting keys that appear in more than one partition is one grouped scan over recent partitions, and it converts a silent overcount into a page. State what it costs to run and what it fires on.
- Buy the cheap half of the real fix immediately: extend partition retention so the dedup horizon exceeds the producer's maximum retry window plus the longest replay you intend to support. That reframes retention as a correctness parameter rather than a storage cost, which is the sentence you need on record before someone optimises the bill.
- Make repayment mechanical instead of aspirational: a dated entry with a named owner, plus a threshold that pulls the date forward — first detector hit above N events, or first customer dispute. Debt with a trigger gets paid; debt with only a date does not.
- Answer the second half honestly by naming what you would refuse under identical pressure: the sealing path, because a sealed row is frozen and a wrong number there stops being a bug and becomes an adjustment line, a dispute and an audit question.
Follow-up
- The detector fires on forty duplicate events for one tenant, and two of their invoices have already sealed. What happens next?
- Whom did you tell that the billing numbers had a known hole, and in what words?
- Finance asks you to cut storage by shortening partition retention. What do you say, and to whom?
- 01
Describe a time you had to resolve a conflict within your engineering team.
- 02
Why are you interested in the intersection of AI and music?
- 03
Tell me about a project where you had to pivot your approach due to shifting business requirements.
- 04
How do you handle feedback from non-technical stakeholders?
- 05
Describe a challenging work situation and how you navigated it to reach a resolution.
- 06
Describe how you use the product, what feedback you would give on it, and your own experience with music.
Is this an official Suno interview guide?
No. This is PracHub's own research and practice material for the Software Engineer role at Suno. The rounds and questions reflect what candidates have reported, not a process Suno has published, and both change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗What stages does the Suno Software Engineer interview have?
Candidates report three stages: a recruiter screen about background and role fit, a technical assessment that includes standardized coding challenges, and a panel-based final round focused on design discussions and engineering maturity. Reports mention meeting engineering managers and senior individual contributors. Treat this as a reported outline and confirm it with your recruiter.
PracHub Software Engineer practice ↗How difficult is the interview process at Suno?
Candidate reports describe the difficulty as average, with a process that can feel less structured than at larger companies. Prepare for both formats that come up: standardized coding problems where edge cases matter, and open-ended design and behavioral conversations where you need to drive the structure yourself.
PracHub interview research ↗Should I expect a take-home project?
Some candidates report receiving large take-home assignments. If you get one, ask your recruiter about the expected time investment and scope before you start, agree on what a complete submission includes, and write down the trade-offs you made so you can discuss them later.
PracHub interview research ↗Which design topics should I prepare?
The reported design questions cover an audio player and playlist system with low-latency streaming, a credit-based subscription system with usage-based billing, real-time content moderation for uploaded audio, and high availability with data consistency in a distributed system. The reported topic list also includes credits and entitlements, billing infrastructure, subscription lifecycle management, dunning flows and revenue recovery, so practise the billing designs as seriously as the streaming one.
PracHub Software Engineer practice ↗Which languages and tools should I be comfortable with?
The role description lists a modern language such as Python, TypeScript or Go, cloud infrastructure on AWS or GCP, and system design fundamentals as must-haves. Generative AI experience, audio processing frameworks and payment integrations such as Stripe or RevenueCat are listed as nice-to-haves. Interview in the language you are fastest and most accurate in.
PracHub Software Engineer practice ↗How can I stand out during the interview?
Connect your technical answers to the product. Use Suno before interviewing, and when you design or code, relate your choices to the problems the reported questions point at: audio delivery, generation load, credits and billing, and moderation. When you mention a trade-off, say which choice you would make and what would make you change it.
PracHub interview research ↗What is the typical timeline for the hiring process?
Candidate reports put the process at roughly three to five weeks from recruiter screen to decision, and scheduling can shift. Ask your recruiter when to expect updates, and if you have a competing deadline, raise it early.
PracHub interview research ↗Sources & methodology 3 sources ↗
Official role evidence, timestamped platform data and clearly labeled preparation advice.
- 01PracHub interview research ↗
PracHub editorial research into this company and role, maintained with this guide. Candidate-reported, not an employer publication.
platform · Accessed 2026-09-24 - 02PracHub Software Engineer practice ↗
Cross-company practice questions for this role.
platform · Accessed 2026-09-24 - 03PracHub interview preparation framework ↗
The framework the preparation plan follows.
platform · Accessed 2026-09-24