cswork / libraryOpen practice workspace

Interview guides · Vanna Health

Vanna Health Software Engineer Interview Guide

Vanna Health Software Engineer interview guide: reported rounds, questions and how candidates describe the process.

The 60-second brief

At Vanna Health, a Software Engineer plays a pivotal role in building and scaling the digital infrastructure that supports community-based care for individuals with serious mental illness. Unlike traditional tech companies where software is purely digital, your work here directly impacts real-world clinical operations, care coordination, and patient outcomes. You will be responsible for developing tools that empower care teams, streamline patient outreach, and ensure secure, seamless data integration across complex health systems. The engineering team at Vanna Health operates with a high degree of autonomy and ownership. Because the engineering organization is lean, every engineer contributes across the entire product lifecycle—from initial scoping with product managers to architecting backend services and refining frontend user interfaces.

This guide is scoped to a Software Engineer candidate at Vanna Health.

Focus areas

  • Take-home assessment
  • Code challenges
  • Back-end engineering

The Vanna Health interview process

Vanna Health candidates report 5 rounds over 4-6 weeks. The stages below are what candidates describe, not a published process.

Recruiter Conversation

Initial conversation with a recruiter to discuss the role and candidate's background.

What to demonstrate

  • Initial conversation with a recruiter to discuss the role and candidate's background
  • Depth in Take-home assessment

How to prepare

  • Be able to walk your CV end to end in two minutes, and say why this company specifically.
  • Have your salary expectations, notice period and location constraints ready, and ask for the rest of the loop in writing.

Technical Screen

A technical screening session to evaluate the candidate's technical skills.

What to demonstrate

  • A technical screening session to evaluate the candidate's technical skills
  • Depth in Take-home assessment

How to prepare

  • Answer aloud and timed: How do you approach error handling and validation when processing large batches of patient demographic data?
  • Answer aloud and timed: Explain how you would optimize a slow-performing database query that retrieves active patient lists for a clinician dashboard.

Take-Home Assessment

A practical take-home assessment designed to reflect real-world engineering tasks.

What to demonstrate

  • A practical take-home assessment designed to reflect real-world engineering tasks
  • Depth in Take-home assessment

How to prepare

  • Answer aloud and timed: How do you manage complex, multi-step form states in a React application without sacrificing rendering performance?
  • Answer aloud and timed: Describe your approach to building reusable, accessible UI components that need to be shared across multiple internal dashboards.

Review Session

Discussion of the candidate's architectural choices from the take-home assessment.

What to demonstrate

  • Discussion of the candidate's architectural choices from the take-home assessment
  • Depth in Take-home assessment

How to prepare

  • Answer aloud and timed: How would you handle real-time updates on a patient queue dashboard to ensure care coordinators always see the most current status?
  • Answer aloud and timed: What strategies do you use to ensure frontend applications remain responsive when rendering large datasets or complex interactive tables?

Deep-Dive Sessions

Final loop of sessions focusing on frontend, backend, systems architecture, and collaboration.

What to demonstrate

  • Final loop of sessions focusing on frontend, backend, systems architecture, and collaboration
  • Depth in Take-home assessment

How to prepare

  • Answer aloud and timed: How would you architect a secure file ingestion pipeline that processes sensitive patient documents and stores them in compliance with HIPAA guidelines?
  • Answer aloud and timed: Describe how you would decouple a monolithic care-coordination tool into microservices as the engineering team and user base scale.

Where candidates lose points

Communicate your trade-offs explicitly

During both the coding and system design sessions, there is rarely a single "correct" answer. Explain why you are choosing a specific approach and what the trade-offs are regarding time, complexity, and scalability.

Showcase your testing mindset

When working on the take-home assessment or participating in live coding, explain how you would test your code. Writing or describing unit and integration tests shows that you value code quality and reliability.

Express genuine interest in the mission

Vanna Health is deeply committed to improving mental health care. Candidates who can articulate why they want to work in this specific domain and how they maintain empathy for patients and clinicians stand out.

Questions & practice

How do you approach error handling and validation when processing large batches of patient demographic data?

Medium · Real-World Backend & System Integration

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. Choose the data structure from the access pattern, not from familiarity.
  4. State the target complexity and say which constraint rules the naive version out.

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?

Archive a resource graph without breaking live references or recursing

Medium · graph traversal · topological order · tenant isolation

Resources reference other resources within a tenant; for the largest tenant the reference table holds up to 2,000,000 nodes and 8,000,000 edges. Archiving a resource must archive everything reachable from it that nothing outside the set still references, refuse when a live external referrer exists, and terminate when references form cycles, which they legitimately do. Produce the archive order and the refusal list, targeting O(V+E). Say what stops the traversal crossing a tenant boundary, and why recursion is the wrong control structure at this size.

Approach

  1. Load the subgraph with the tenant predicate on both endpoints of the edge, not only on the side you started from. Scoping the left table alone is the classic cross-tenant leak: one mis-entered edge then pulls another tenant's resources into the traversal and, worse, into the archive.
  2. Traverse iteratively with an explicit stack. A 2,000,000-node graph can hold a chain deep enough to exhaust a native stack in the low tens of thousands of frames, and that failure is a process crash rather than an error you can return.
  3. Treat cycles as data rather than corruption: compute strongly connected components with Tarjan in O(V+E) using its own explicit stack, then condense. The condensation is a DAG, so a topological order over it gives the archive order, and every member of a component archives in one transaction because no order within a cycle is valid.
  4. Decide refusals with reverse edges. A candidate is archivable only if every in-edge originates inside the candidate set, so build the transpose or count in-degrees restricted to the visited set, and emit each blocked resource with the id of the external referrer, which is the only part of the answer an operator can act on.

Follow-up

  • The graph is read in one query and the archive writes a minute later. What can change in between, and how do you make the write safe?
  • The candidate set is 400,000 resources. Is that one transaction, and if not, what does a half-finished archive look like to a reader?

Identify the heaviest tenants in a five-minute window under memory pressure

Medium · top-k · heavy hitters · streaming

The edge service handles about 3,000 requests per second across roughly 50,000 tenants, peaking near 9,000. Expose the 50 heaviest tenants by request count over the trailing five minutes so limits can be tightened before one tenant's backfill starves the fleet. You may not retain five minutes of raw records. Give the exact solution and its memory, then the bounded-memory approximation with its error stated as a formula, and say which you would ship and at what tenant cardinality that choice changes.

Approach

  1. Do the exact version first, because it is affordable at this cardinality: a ring of 300 one-second counters per tenant, advanced lazily, is 1,200 bytes of counters per tenant and roughly 60 to 90 MB for 50,000 tenants with overhead. Carry a running total and subtract the bucket you overwrite so a window read is O(1) rather than 300 adds.
  2. Extract the top 50 with a size-k min-heap over the tenant sums: O(d log k) for d tenants, against O(d log d) to sort them all. Maintaining the heap continuously instead of on query requires a tenant-to-heap-index map, because incrementing a count already inside the heap means sifting from a known position, and without that map you rebuild the heap on every request.
  3. State the approximation precisely rather than gesturing at sketches. Misra-Gries with m counters retains every item whose true count exceeds N/(m+1), and each retained count underestimates the truth by at most N/(m+1). With m = 1,000 and N = 900,000 requests in the window the error is roughly 900 requests, which is fine for spotting a tenant sending 50,000 and useless for ranking two tenants 200 apart.
  4. Say what breaks when the window slides: Misra-Gries and Space-Saving are insert-only and cannot be decremented as records age out. The workable construction is one summary per sub-window, say ten seconds, with 30 summaries merged at query time, and the merged error is the sum of the per-summary errors, so the bound degrades linearly in the number of sub-windows.

Follow-up

  • The heaviest tenant is heavy because of one export job rather than user traffic. Should the limiter treat those as the same tenant?
  • Two tenants sit tied at the boundary of the top 50. Does your answer flap, and does the flapping matter?

Explain how you would optimize a slow-performing database query that retrieves active patient lists for a clin

Medium · Real-World Backend & System Integration

Explain how you would optimize a slow-performing database query that retrieves active patient lists for a clinician dashboard.

Approach

  1. Name the grain you start from and join outward from it.
  2. Check whether any join is one-to-many before aggregating, or the sums inflate.
  3. Say which index the query would use, and what makes it unusable.
  4. Handle the rows that do not match: that is usually the actual question.

Follow-up

  • How does the query change if that join becomes one-to-many?
  • What happens to this when the table is ten times larger?

Walk me through your choice of database (SQL vs. NoSQL) for storing unstructured notes from clinical visits al

Medium · System Design & Architecture

Walk me through your choice of database (SQL vs. NoSQL) for storing unstructured notes from clinical visits alongside structured medical codes.

Approach

  1. Name the grain you start from and join outward from it.
  2. Check whether any join is one-to-many before aggregating, or the sums inflate.
  3. Say which index the query would use, and what makes it unusable.
  4. Handle the rows that do not match: that is usually the actual question.

Follow-up

  • How does the query change if that join becomes one-to-many?
  • What happens to this when the table is ten times larger?

How would you design a relational database schema to track patient care plans, historical touchpoints, and ass

Medium · Real-World Backend & System Integration

How would you design a relational database schema to track patient care plans, historical touchpoints, and assigned care coordinators over time?

Approach

  1. Fix the scope first: who calls this, how often, and what they do when it fails.
  2. Name the read and write paths separately; they rarely have the same bottleneck.
  3. Choose a partition key and say what query it makes expensive.
  4. State the consistency you need, and where you are willing to be stale.

Follow-up

  • What breaks first when traffic grows ten times?
  • How does this behave when that dependency is down for an hour?

Walk me through how you would structure an API endpoint to ingest data from an external electronic health reco

Medium · Real-World Backend & System Integration

Walk me through how you would structure an API endpoint to ingest data from an external electronic health record (EHR) system while ensuring transactional safety.

Approach

  1. Say who the caller is and what they do when the call fails halfway.
  2. Define the identity of a request so a retry cannot double-apply it.
  3. Separate accepted, pending, failed and confirmed; they are different facts.
  4. Design the error taxonomy before the success shape; callers branch on it.

Follow-up

  • What happens if the caller retries after a timeout?
  • How does a client discover it is on an old version of this contract?

How do you manage complex, multi-step form states in a React application without sacrificing rendering perform

Medium · Frontend & Collaborative UI Development

How do you manage complex, multi-step form states in a React application without sacrificing rendering performance?

Approach

  1. Clarify what is being asked and what a complete answer contains.
  2. State your assumptions explicitly before working the problem.
  3. Say what you would check first and why it is the highest-information step.
  4. Work from the requirement backwards to the design.

Follow-up

  • What assumption would you test first?
  • How would you know your answer was wrong?

Describe your approach to building reusable, accessible UI components that need to be shared across multiple i

Medium · Frontend & Collaborative UI Development

Describe your approach to building reusable, accessible UI components that need to be shared across multiple internal dashboards.

Approach

  1. Clarify what is being asked and what a complete answer contains.
  2. State your assumptions explicitly before working the problem.
  3. Say what you would check first and why it is the highest-information step.
  4. Work from the requirement backwards to the design.

Follow-up

  • What assumption would you test first?
  • How would you know your answer was wrong?

How would you handle real-time updates on a patient queue dashboard to ensure care coordinators always see the

Medium · Frontend & Collaborative UI Development

How would you handle real-time updates on a patient queue dashboard to ensure care coordinators always see the most current status?

Approach

  1. Clarify what is being asked and what a complete answer contains.
  2. State your assumptions explicitly before working the problem.
  3. Say what you would check first and why it is the highest-information step.
  4. Work from the requirement backwards to the design.

Follow-up

  • What assumption would you test first?
  • How would you know your answer was wrong?

What strategies do you use to ensure frontend applications remain responsive when rendering large datasets or

Medium · Frontend & Collaborative UI Development

What strategies do you use to ensure frontend applications remain responsive when rendering large datasets or complex interactive tables?

Approach

  1. Clarify what is being asked and what a complete answer contains.
  2. State your assumptions explicitly before working the problem.
  3. Say what you would check first and why it is the highest-information step.
  4. Work from the requirement backwards to the design.

Follow-up

  • What assumption would you test first?
  • How would you know your answer was wrong?

How would you architect a secure file ingestion pipeline that processes sensitive patient documents and stores

Medium · System Design & Architecture

How would you architect a secure file ingestion pipeline that processes sensitive patient documents and stores them in compliance with HIPAA guidelines?

Approach

  1. Fix the scope first: who calls this, how often, and what they do when it fails.
  2. Name the read and write paths separately; they rarely have the same bottleneck.
  3. Choose a partition key and say what query it makes expensive.
  4. State the consistency you need, and where you are willing to be stale.

Follow-up

  • What breaks first when traffic grows ten times?
  • How does this behave when that dependency is down for an hour?

Describe how you would decouple a monolithic care-coordination tool into microservices as the engineering team

Medium · System Design & Architecture

Describe how you would decouple a monolithic care-coordination tool into microservices as the engineering team and user base scale.

Approach

  1. Fix the scope first: who calls this, how often, and what they do when it fails.
  2. Name the read and write paths separately; they rarely have the same bottleneck.
  3. Choose a partition key and say what query it makes expensive.
  4. State the consistency you need, and where you are willing to be stale.

Follow-up

  • What breaks first when traffic grows ten times?
  • How does this behave when that dependency is down for an hour?

How do you design systems for high availability and disaster recovery when dealing with critical care-coordina

Medium · System Design & Architecture

How do you design systems for high availability and disaster recovery when dealing with critical care-coordination software?

Approach

  1. Fix the scope first: who calls this, how often, and what they do when it fails.
  2. Name the read and write paths separately; they rarely have the same bottleneck.
  3. Choose a partition key and say what query it makes expensive.
  4. State the consistency you need, and where you are willing to be stale.

Follow-up

  • What breaks first when traffic grows ten times?
  • How does this behave when that dependency is down for an hour?

One customer endpoint stalls deliveries to every other destination

Medium · bulkhead · timeouts · saturation

The egress service delivers about 1.5k webhooks/second across 40,000 destinations, with a per-destination concurrency cap of 4 and a 10-second connect-plus-read timeout. Throughput falls to 300/second, queue depth climbs, and p99 delivery latency for unaffected destinations goes from 200 ms to minutes, while the error rate barely moves. One tenant holds 900 destination rows whose URLs share a hostname that now answers in 9.5 seconds. Explain the mechanism with the arithmetic, then give the containment in the order you would apply it.

Approach

  1. Look at saturation before errors. A flat error rate with collapsing throughput says nothing is failing, things are waiting, so the first signal to pull is in-flight request count or pool wait time rather than the error counter. This is the distinction that decides the whole investigation.
  2. Group in-flight work by resolved host, not by destination id. The cap is keyed per destination row, so 900 rows sharing one hostname buy 3,600 concurrent slots against a single host, each held for 9.5 seconds. The bulkhead was never a bulkhead for that host, and grouping by the wrong dimension is why the dashboard looked healthy.
  3. Do the arithmetic in both directions. Required concurrency is arrival rate times latency, so 1.5k/second at 200 ms needs about 300 in flight, which is entirely consumed by 3,600 slow slots; conversely whatever concurrency is left sustains rate equals concurrency divided by 9.5 seconds, which is the 300/second you are seeing. Matching both numbers is what promotes this from a plausible story to the mechanism.
  4. Explain why the circuit breaker never helped. It opens on consecutive failures, and a 9.5-second response inside a 10-second timeout is a success. Slow is not failing, so an error-rate breaker cannot see this; you need a slow-call ratio, a deadline propagated from the caller's remaining budget, or a concurrency limiter.

Follow-up

  • The host recovers to 80 ms. How long does the queue take to drain, and what does the drain do to the recovered host?
  • Where should the 10-second timeout number actually come from?

Suggested practice checklist

Built from the rounds and topics Vanna Health candidates report.

Day 1 — Map the Vanna Health loop

  • Write out the reported sequence: Recruiter Conversation, Technical Screen, Take-Home Assessment, Review Session, Deep-Dive Sessions.
  • For each round, write one sentence on what it is judging, from the description above, and mark the one you are least ready for.

Deliverable: A one-page map of the 5 reported rounds, with the weakest marked.

Day 2 — Work Take-home assessment

  • Spend the session on Take-home assessment, which Vanna Health candidates report being tested on.
  • Write one worked example in Take-home assessment and time yourself on it.

Deliverable: One timed worked example in Take-home assessment.

Day 3 — Work Code challenges

  • Spend the session on Code challenges, which Vanna Health candidates report being tested on.
  • Write one worked example in Code challenges and time yourself on it.

Deliverable: One timed worked example in Code challenges.

Day 4 — Work Back-end engineering

  • Spend the session on Back-end engineering, which Vanna Health candidates report being tested on.
  • Write one worked example in Back-end engineering and time yourself on it.

Deliverable: One timed worked example in Back-end engineering.

Day 5 — Answer out loud: Real-World Backend & System Integration

  • Answer aloud, timed: How would you design a relational database schema to track patient care plans, historical touchpoints, and assigned care coordinators over time?
  • Answer aloud, timed: Walk me through how you would structure an API endpoint to ingest data from an external electronic health record (EHR) system while ensuring transactional safety.

Deliverable: Spoken answers to 2 reported Real-World Backend & System Integration question(s), under time.

Day 6 — Answer out loud: Frontend & Collaborative UI Development

  • Answer aloud, timed: How do you manage complex, multi-step form states in a React application without sacrificing rendering performance?
  • Answer aloud, timed: Describe your approach to building reusable, accessible UI components that need to be shared across multiple internal dashboards.

Deliverable: Spoken answers to 2 reported Frontend & Collaborative UI Development question(s), under time.

Day 7 — Answer out loud: System Design & Architecture

  • Answer aloud, timed: How would you architect a secure file ingestion pipeline that processes sensitive patient documents and stores them in compliance with HIPAA guidelines?
  • Answer aloud, timed: Describe how you would decouple a monolithic care-coordination tool into microservices as the engineering team and user base scale.

Deliverable: Spoken answers to 2 reported System Design & Architecture question(s), under time.

Behavioural preparation

Behavioural rounds judge the decision you made and what it cost.

Tell me about a time you had to make a technical trade-off to meet a tight product deadline. What was the impa

Medium · Behavioral & Cross-Functional Collaborat

Tell me about a time you had to make a technical trade-off to meet a tight product deadline. What was the impact, and how did you communicate it to stakeholders?

Approach

  1. Pick a story where you made the decision, not one where you watched it.
  2. State the situation in two sentences and spend the rest on the reasoning.
  3. Give the blast radius: what could have broken, and what you measured.
  4. 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?

How do you handle a situation where a product manager proposes a feature that is technically unfeasible or hig

Medium · Behavioral & Cross-Functional Collaborat

How do you handle a situation where a product manager proposes a feature that is technically unfeasible or highly complex to implement?

Approach

  1. Pick a story where you made the decision, not one where you watched it.
  2. State the situation in two sentences and spend the rest on the reasoning.
  3. Give the blast radius: what could have broken, and what you measured.
  4. 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?

Describe a time when you received constructive feedback on your code or system design. How did you incorporate

Medium · Behavioral & Cross-Functional Collaborat

Describe a time when you received constructive feedback on your code or system design. How did you incorporate that feedback?

Approach

  1. Pick a story where you made the decision, not one where you watched it.
  2. State the situation in two sentences and spend the rest on the reasoning.
  3. Give the blast radius: what could have broken, and what you measured.
  4. 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?

Why do you want to work in the healthcare technology space, and how do you maintain user empathy when writing

Medium · Behavioral & Cross-Functional Collaborat

Why do you want to work in the healthcare technology space, and how do you maintain user empathy when writing code?

Approach

  1. Pick a story where you made the decision, not one where you watched it.
  2. State the situation in two sentences and spend the rest on the reasoning.
  3. Give the blast radius: what could have broken, and what you measured.
  4. 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?