← Snowflake Interview Insights

Snowflake·Software Engineer·Onsite - System Design / Architecture·Senior

SeniorPrefer not to say
Apr 2026Remote

Summary

Snowflake system design round for a software engineer role. The whole session was basically one big distributed systems question with a bunch of follow-ups that kept drilling deeper. Not a comfortable interview if you haven't thought carefully about scheduler correctness before.

Questions Asked (10)

Q1

Design a distributed cron job scheduler that triggers user-defined jobs on recurring schedules. Worker capacity is unlimited, so the focus should be on correct scheduling, state management, and reliable triggering rather than scaling the compute side.

System DesignTechnical Trade-offsData Modeling
Author's notes

This is the kind of question where the unlimited workers constraint is a trap if you don't internalize it fast.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements and constraints, then propose a high-level architecture with a central scheduler and distributed workers. Focus on correctness, state management, and reliable triggering, using a database or coordination service for persistence and leader election.

Pro tip: Emphasize idempotency and exactly-once semantics for job triggers, and discuss how to handle missed schedules and failures gracefully.

1. Clarify Requirements

Ask about job types, scheduling granularity, scale, and reliability guarantees. Confirm that worker capacity is unlimited and focus is on scheduling correctness.

2. High-Level Architecture

Propose a central scheduler service that manages job definitions and schedules, and a pool of workers that execute jobs. Use a persistent store for job state and a coordination service for leader election.

3. Scheduling and Triggering

Design how the scheduler computes next run times, handles time zones, and triggers jobs. Use a queue or direct RPC to dispatch jobs to workers, ensuring at-least-once delivery with idempotent execution.

4. State Management and Fault Tolerance

Store job definitions, schedules, and execution history in a durable database. Implement leader election to avoid duplicate scheduling, and handle failures with retries and dead-letter queues.

5. Trade-offs and Extensions

Discuss trade-offs between centralized vs. decentralized scheduling, push vs. pull models, and how to handle missed schedules. Mention monitoring, alerting, and potential for scaling.

Key Points to Mention

  • Use of a distributed coordination service (e.g., ZooKeeper, etcd) for leader election and configuration.
  • Idempotent job execution and exactly-once triggering semantics.
  • Persistent storage for job definitions, schedules, and execution logs.
  • Handling of missed schedules and catch-up policies.
  • Time zone and daylight saving time considerations.
  • Monitoring, alerting, and observability for job failures.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

What clarifying questions would you ask before starting the design? Things like schedule granularity, timezone support, backfill behavior on resume, at-least-once vs at-most-once delivery, and what the job hand-off target looks like.

System DesignAdaptability & Ambiguity
Author's notes

I got most of these but fumbled the backfill question.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Demonstrate a structured approach to requirements gathering by categorizing questions into functional, non-functional, and operational aspects. Show that you prioritize questions that most impact the design, and explain how the answers would shape your architecture. Emphasize collaboration with stakeholders to uncover hidden assumptions.

Pro tip: Ask about the cost of failure and the expected scale early on—these often drive the most critical design decisions. Also, frame questions as options (e.g., 'Should we support at-least-once or at-most-once delivery?') to show you understand trade-offs.

1. Clarify Functional Requirements

Ask about core features: What exactly is being scheduled? What actions are triggered? What are the inputs and outputs? This defines the system's scope.

2. Define Non-Functional Requirements

Inquire about scale, latency, throughput, and availability. For example: How many jobs per second? What's the acceptable delay? This shapes technology choices.

3. Explore Operational Semantics

Dig into delivery guarantees, retry policies, backfill behavior, and timezone handling. These details affect correctness and complexity.

4. Understand Integration and Hand-off

Ask about downstream systems, job hand-off targets, and monitoring. This ensures the design fits into the broader ecosystem.

5. Prioritize and Confirm

Summarize key questions and confirm priorities with the interviewer. This shows you can drive clarity and focus on what matters most.

Key Points to Mention

  • Schedule granularity: How precise must scheduling be (e.g., minute-level, second-level)?
  • Timezone support: Do we need to handle multiple timezones and daylight saving?
  • Backfill behavior: How should missed jobs be handled upon resume?
  • Delivery semantics: At-least-once vs at-most-once—what are the implications for idempotency?
  • Job hand-off target: What system executes the job (e.g., Kubernetes, Lambda)?
  • Scale and performance: Expected job volume, concurrency, and latency requirements.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

Walk through the data model that drives scheduling correctness. What fields does a job record need, and why?

Data ModelingSystem Design
Author's notes

I knew next_run_at and status were important but initially forgot to include a concurrency token (version or lease field).

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by framing scheduling correctness as a state machine problem, then walk through the job record fields that capture state, timing, and dependencies. Emphasize how each field prevents specific failure modes like duplicate execution, missed runs, or race conditions.

Pro tip: Mention that Snowflake's multi-tenant, distributed environment requires idempotent job execution and exactly-once semantics, so fields like execution_id and lease_expiry are critical to prevent duplicate work across nodes.

1. Define the job lifecycle and states

Describe the states a job transitions through (e.g., PENDING, RUNNING, SUCCEEDED, FAILED, RETRYING) and why explicit state tracking is necessary for correctness.

2. Identify core identity and ownership fields

List fields like job_id, tenant_id, and owner that uniquely identify the job and enforce multi-tenant isolation and access control.

3. Add timing and scheduling fields

Include fields such as scheduled_time, cron_expression, next_run_time, and timeout to ensure jobs run at the right time and don't hang indefinitely.

4. Incorporate concurrency and coordination fields

Explain fields like execution_id, lease_expiry, and retry_count that prevent duplicate execution and manage distributed coordination.

5. Include dependency and result fields

Cover fields like depends_on, status, and result_payload to handle job dependencies and store outcomes for downstream consumers.

Key Points to Mention

  • State machine with explicit states (PENDING, RUNNING, SUCCEEDED, FAILED) to track progress and enable recovery.
  • Idempotency and exactly-once semantics via execution_id and lease_expiry to avoid duplicate execution in distributed systems.
  • Multi-tenant isolation with tenant_id and job_id to ensure security and correct resource attribution.
  • Timing fields like scheduled_time, next_run_time, and timeout to handle scheduling and prevent stuck jobs.
  • Retry and backoff fields (retry_count, max_retries, backoff_interval) to handle transient failures gracefully.
  • Dependency tracking (depends_on) to enforce ordering and data freshness constraints.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q4

Describe the core scheduler loop: how does it find due jobs efficiently at a scale of a million job definitions, claim them safely, emit a run record, and advance the schedule?

System DesignAlgorithms & Data Structures
Author's notes

The indexing angle is what I almost missed.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Structure your answer around the four sub-problems: efficient due-job discovery, safe claiming, run record emission, and schedule advancement. Emphasize how data structures and concurrency primitives scale to a million job definitions, and discuss trade-offs between precision and throughput.

Pro tip: Mention that you'd use a time-bucketed priority queue or timing wheel to avoid scanning all million jobs, and that claiming should be done with a conditional update (e.g., compare-and-swap) to prevent double execution. This shows you think about both performance and correctness at scale.

1. Clarify requirements and scale

Restate the problem: a million job definitions, each with a schedule (e.g., cron, interval). The scheduler must find due jobs with low latency, claim them atomically, emit a run record, and compute the next run time.

2. Efficient due-job discovery

Propose a time-ordered data structure like a min-heap keyed by next_run_time, or a hierarchical timing wheel for O(1) insertion and O(1) expiration. For a million jobs, a heap gives O(log n) per operation, which is acceptable; a timing wheel can be more efficient for high-throughput.

3. Safe claiming and concurrency

Use a conditional update (e.g., UPDATE ... WHERE next_run_time = old_value AND status = 'pending') or a distributed lock (e.g., via ZooKeeper/etcd) to ensure only one scheduler instance claims a job. Alternatively, partition jobs across scheduler instances to avoid contention.

4. Run record emission and schedule advancement

After claiming, emit a run record (e.g., to Kafka or a database) with job ID, scheduled time, and status. Then compute the next run time based on the job's schedule and update the job definition atomically, reinserting it into the timing structure.

5. Handle failures and scale-out

Discuss failure recovery: if a scheduler crashes, jobs must be re-claimed after a timeout. For scale, shard jobs by job ID or time bucket across multiple schedulers, and use a distributed queue for run records.

Key Points to Mention

  • Time-bucketed priority queue or timing wheel for O(1)/O(log n) due-job discovery
  • Atomic claiming via conditional updates or distributed locks to prevent double execution
  • Run record emission to a durable log (e.g., Kafka) for auditing and downstream processing
  • Next run time computation using cron parsing or interval arithmetic
  • Partitioning/sharding jobs across scheduler instances for horizontal scalability
  • Failure handling: timeouts, retries, and idempotent claiming

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q5

With multiple scheduler replicas all seeing the same due jobs simultaneously, how do you prevent the same job from firing more than once per tick?

System DesignTechnical Trade-offs
Author's notes

Optimistic locking with a version field was my answer.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by acknowledging the distributed coordination challenge, then present a layered solution: use a distributed lock or leader election to serialize scheduling decisions, and add idempotency at the job execution level as a safety net. Discuss trade-offs between consistency, availability, and complexity, and mention how you would handle failures and clock skew.

Pro tip: Emphasize that even with perfect coordination, network partitions and retries can cause duplicate executions, so idempotent job handlers are non-negotiable. Also, mention that you would measure and monitor duplicate rates to validate your approach.

1. Clarify requirements and constraints

Ask about the consistency requirements (e.g., exactly-once vs at-least-once), acceptable latency, and scale (number of jobs, replicas). This shows you tailor solutions to business needs.

2. Choose a coordination mechanism

Propose using a distributed lock service (e.g., ZooKeeper, etcd, or a database with SELECT FOR UPDATE) or leader election so only one replica schedules jobs per tick. Discuss trade-offs like added latency and single point of failure.

3. Implement idempotent job execution

Design job handlers to be idempotent using unique job IDs and deduplication stores (e.g., Redis or database unique constraints). This ensures that even if duplicates occur, side effects happen only once.

4. Handle failures and edge cases

Address what happens if the lock holder crashes (e.g., lease timeouts, fencing tokens) and how to handle clock skew across replicas. Mention retry logic and dead-letter queues.

5. Validate and monitor

Describe how you would test the solution (e.g., chaos engineering) and monitor for duplicate executions. Suggest metrics like duplicate rate and lock contention.

Key Points to Mention

  • Distributed locking with lease-based expiration and fencing tokens to prevent stale lock holders.
  • Leader election using consensus protocols (Raft, Paxos) or external services (ZooKeeper, etcd).
  • Idempotency keys and deduplication stores to ensure at-most-once side effects.
  • Trade-offs between strong consistency (e.g., serializable transactions) and availability (e.g., eventual consistency).
  • Handling clock skew and time synchronization (e.g., NTP, logical clocks).
  • Monitoring and alerting for duplicate job executions and lock contention.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q6

What are the exact semantics of pause and resume, and how do you handle the race where a scheduler has already picked up a job for the current tick at the exact moment pause commits?

System DesignTechnical Trade-offsAPI & Integrations
Author's notes

This one got me.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clearly defining the semantics of pause and resume in terms of state transitions and guarantees, then walk through the race condition step-by-step, explaining how to detect and resolve it using mechanisms like fencing tokens or two-phase commit. Emphasize the trade-offs between consistency and availability, and how your solution ensures exactly-once or at-least-once execution semantics.

Pro tip: Demonstrate awareness that pause is not instantaneous and that the system must handle in-flight jobs gracefully; mention that you would use a generation number or epoch to invalidate stale scheduler decisions, which shows deep understanding of distributed systems.

1. Define pause and resume semantics

Specify what pause means: does it stop new job scheduling, allow in-flight jobs to complete, or abort them? Define resume as the point from which new jobs can be scheduled again, and clarify the expected state of the system during pause.

2. Identify the race condition

Describe the exact scenario: a scheduler reads the pause flag as false, picks a job, and then pause commits before the job starts. Explain why this leads to an inconsistency if not handled.

3. Choose a resolution strategy

Propose a mechanism such as a two-phase commit, a fencing token (epoch), or a distributed lock to ensure that once pause commits, no new jobs are started. Discuss how the scheduler can check the pause state atomically with job pickup.

4. Handle in-flight jobs

Decide whether to let the already-picked job run to completion, abort it, or requeue it. Explain how this decision affects system guarantees and user expectations.

5. Discuss trade-offs and edge cases

Compare consistency vs. availability, latency implications, and failure scenarios (e.g., scheduler crash). Mention how to ensure idempotency and exactly-once semantics if required.

Key Points to Mention

  • Atomicity of pause commit and scheduler's job pickup
  • Use of fencing tokens or epoch numbers to invalidate stale scheduler decisions
  • Two-phase commit or distributed consensus for coordinating pause across nodes
  • Idempotency and exactly-once vs. at-least-once execution semantics
  • Handling of in-flight jobs: complete, abort, or requeue
  • Trade-offs between consistency, availability, and latency (CAP theorem)

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q7

If a scheduler instance crashes after writing the run record to the database but before the run reaches the queue, how does your design ensure the trigger is neither lost nor delivered twice?

System DesignTechnical Trade-offs
Author's notes

Transactional outbox pattern basically.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by acknowledging the classic dual-write problem and the need for atomicity between state persistence and queue delivery. Then describe a design that uses transactional outbox or two-phase commit with idempotent consumers to guarantee exactly-once semantics. Finally, discuss trade-offs and failure recovery mechanisms.

Pro tip: Emphasize that exactly-once delivery is impossible without idempotency; focus on at-least-once delivery with deduplication. Mention that Snowflake's scale demands partitioning and distributed tracing for debugging.

1. Identify the failure scenario

Clearly state the problem: a crash between DB write and queue enqueue creates a window where the trigger could be lost or duplicated. This is the dual-write problem.

2. Propose atomic commit solutions

Describe using a transactional outbox pattern: write the run record and an outbox entry in the same DB transaction. A separate relay process reads the outbox and publishes to the queue, ensuring at-least-once delivery.

3. Ensure idempotent processing

Explain that consumers must be idempotent, using a unique trigger ID to deduplicate. This handles duplicate deliveries from the relay retrying after a crash.

4. Discuss recovery and monitoring

Outline how the relay recovers from crashes: it polls the outbox, marks entries as sent, and retries on failure. Monitoring ensures no stuck entries.

5. Evaluate trade-offs

Compare with alternatives like two-phase commit (complex, blocking) or direct queue write with retries (risk of loss). Highlight that outbox + idempotency is robust and scalable.

Key Points to Mention

  • Transactional outbox pattern
  • Idempotent consumer with deduplication key
  • At-least-once delivery + idempotency = effectively-once
  • Relay process with retry and dead-letter queue
  • Monitoring and alerting for outbox backlog
  • Trade-offs: latency vs. consistency, complexity vs. reliability

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q8

A job is configured to run every minute but each execution takes about five minutes. How do you handle the overlap: skip the new run, queue it, or allow concurrent runs? How does the data model express that policy?

System DesignData Modeling
Author's notes

Short answer: it depends on a per-job concurrency policy field.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the job's semantics: is it idempotent, does it have side effects, and what are the SLAs? Then evaluate each policy (skip, queue, concurrent) against those requirements, and finally explain how to encode the chosen policy in the data model using status flags, timestamps, and constraints.

Pro tip: Mention that the best policy often depends on whether the job is idempotent and whether missing a run is acceptable; for Snowflake, leverage its unique features like streams and tasks for efficient scheduling and state management.

1. Clarify job characteristics and requirements

Ask about idempotency, side effects, data dependencies, and SLAs to determine what matters most (e.g., no data loss vs. no overlap).

2. Evaluate each policy against requirements

Compare skip, queue, and concurrent runs: skipping may lose runs, queuing may cause backlog, concurrency may cause race conditions or resource contention.

3. Choose a policy and justify it

Select the most appropriate policy based on the analysis, and explain trade-offs and potential mitigations (e.g., idempotency keys, backpressure).

4. Design the data model to enforce the policy

Describe tables/columns (e.g., job_runs with status, start_time, end_time) and constraints (unique index on job_id where status='RUNNING') to prevent overlaps or manage queues.

5. Discuss implementation details and edge cases

Explain how to handle failures, retries, and monitoring; mention Snowflake-specific features like tasks, streams, and transactions.

Key Points to Mention

  • Idempotency of the job and whether missing a run is acceptable
  • Trade-offs of skip vs. queue vs. concurrent policies (data loss, backlog, resource contention)
  • Data model: job_runs table with status (RUNNING, SUCCESS, FAILED), timestamps, and unique constraints to enforce policy
  • Use of transactions and locking (e.g., SELECT FOR UPDATE) to atomically check and update job state
  • Snowflake-specific features: tasks for scheduling, streams for change data capture, and ACID transactions
  • Monitoring and alerting for long-running jobs and queue depth

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q9

The metadata store becomes a throughput bottleneck with a million jobs all being scanned and updated. How do you partition or shard the scheduling work across replicas without losing the no-double-fire guarantee?

System DesignTechnical Trade-offs
Author's notes

I went with consistent hashing on job_id to assign ownership of job ranges to specific scheduler replicas.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the scale and requirements, then propose a sharding strategy that partitions jobs by a key like job ID or time window, using a consistent hashing ring or a coordination service to assign shards to replicas. Ensure no-double-fire by combining lease-based ownership with idempotent operations and a distributed lock or consensus protocol for critical sections.

Pro tip: Emphasize that the no-double-fire guarantee is ultimately about exactly-once semantics, which requires idempotency and transactional boundaries—not just partitioning. Mention that you'd monitor shard load and support dynamic rebalancing to handle hotspots.

1. Clarify requirements and constraints

Ask about the expected job rate, latency requirements, and whether the system can tolerate brief unavailability during rebalancing. Confirm that the no-double-fire guarantee is absolute or can be relaxed with idempotent side effects.

2. Choose a sharding key and partitioning scheme

Select a key like job ID, tenant ID, or time bucket to distribute jobs evenly. Use consistent hashing or a range-based partition to map shards to replicas, allowing scalable and balanced assignment.

3. Implement ownership and lease management

Assign each shard to a replica via a lease with a TTL, renewed periodically. Use a coordination service like ZooKeeper or etcd to store shard ownership and detect failures, ensuring only one replica processes a shard at a time.

4. Guarantee no-double-fire with idempotency and transactions

Make job execution idempotent by using unique job IDs and deduplication logic. For critical updates, use a distributed transaction or a consensus protocol to atomically update job state and mark it as fired.

5. Handle rebalancing and failure recovery

When a replica fails or a shard moves, ensure the new owner waits for the lease to expire before processing. Use a handoff protocol that includes a grace period and checks for in-flight jobs to avoid duplicate fires.

Key Points to Mention

  • Consistent hashing for even distribution and minimal reshuffling during scaling
  • Lease-based ownership with TTL and heartbeat to detect failures
  • Idempotent job execution using unique IDs and deduplication
  • Distributed coordination service (e.g., ZooKeeper, etcd) for shard assignment
  • Transactional boundaries or consensus protocols for atomic state updates
  • Monitoring and dynamic rebalancing to handle hotspots and load skew

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q10

How would you handle per-job timezones and make sure a daylight saving transition doesn't cause a job scheduled for 2 a.m. to either fire twice or get skipped entirely?

System DesignTechnical Trade-offs
Author's notes

Honestly this was the follow-up I felt least prepared for.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the requirements: jobs are scheduled in a per-job timezone, and the system must handle DST transitions without duplicate or missed executions. Then propose a design that stores schedules in UTC with timezone metadata, uses a robust scheduler with idempotency and catch-up logic, and explicitly handles ambiguous and skipped local times.

Pro tip: Mention that you would store the next run time in UTC and recompute it after each run using the job's timezone, and that you would use a database transaction with a unique constraint on (job_id, scheduled_utc_time) to guarantee exactly-once execution even if multiple scheduler instances race.

1. Clarify requirements and edge cases

Confirm that jobs are scheduled in a specific timezone and that the system must handle DST transitions correctly. Identify the two problematic cases: spring forward (2 a.m. may not exist) and fall back (2 a.m. occurs twice).

2. Store schedules in UTC with timezone context

Persist each job's schedule as a local time plus timezone identifier, but compute and store the next run time in UTC. This avoids ambiguity and makes comparisons straightforward.

3. Define DST transition policies

For spring forward, decide whether to run at the next valid time (e.g., 3 a.m.) or skip; for fall back, decide whether to run once (at the first occurrence) or twice. Document and enforce these policies consistently.

4. Implement idempotent execution and catch-up

Use a unique constraint on (job_id, scheduled_utc_time) to prevent duplicate runs. If a run is missed due to downtime, have a catch-up mechanism that runs the job once and then reschedules based on the next valid time.

5. Test with DST scenarios and monitor

Write unit and integration tests that simulate DST transitions in different timezones. Add monitoring and alerts for missed or duplicate runs to catch issues in production.

Key Points to Mention

  • Store next run time in UTC and recompute after each execution using the job's timezone.
  • Use a database unique constraint on (job_id, scheduled_utc_time) to ensure exactly-once execution.
  • Handle ambiguous times (fall back) by choosing the first occurrence and skipping the second.
  • Handle non-existent times (spring forward) by running at the next valid time or skipping, based on policy.
  • Implement catch-up logic for missed runs due to scheduler downtime, ensuring the job runs only once.
  • Test with timezone libraries (e.g., IANA tz database) and simulate DST transitions.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.