debounce vs throttle

Combine Mid-level Swift 5.1+ iOS 13+ Reviewed By Alok Singh

Predict the output

Values arrive at 0 ms, 100 ms, 200 ms and 800 ms. With .debounce(for: .milliseconds(300), ...), what is emitted?

// input:  a@0ms  b@100ms  c@200ms  d@800ms
subject
    .debounce(for: .milliseconds(300), scheduler: RunLoop.main)
    .sink { print($0) }
Options
Hint 1 of 1

Look for gaps longer than 300 ms.

Choose an answer, then open Show answer below to check it.

Show answer

Answer: B c at about 500 ms, then d at about 1100 ms

Correct. Each burst emits its last value 300 ms after the burst ends.

Why not the others?
  • A a, b, c, d. Debounce drops values that are followed quickly by another.
  • C a at 0 ms, then d at 800 ms. That is closer to throttle with latest: false.
  • D Only d. c is followed by 600 ms of quiet, which is longer than 300 ms.

30-second answer

debounce waits until values stop arriving for a set time and then emits the last one, which suits search-as-you-type. throttle emits at most one value per interval while values keep arriving, either the first or the latest, which suits scroll or sensor updates. Debounce can delay forever while input keeps coming; throttle guarantees regular output.

Practise saying it · 30 s. No recording, just a timer

Explain debounce vs throttle.

Say your answer out loud, then check which of these points you covered:

  • Debounce waits for quiet
  • Throttle limits rate
  • Pick by product behaviour

Deep dive

Pair debounce with removeDuplicates for search.

Use a test scheduler or virtual time when testing timing operators.

In async code, .task(id:) plus Task.sleep gives a debounce.

Swift Async Algorithms provides debounce and throttle for AsyncSequence.

Common mistakes

  • Throttling search, which sends half-typed queries.
  • Debouncing a progress stream, which shows nothing until it stops.

Senior take & follow-ups

Seniors choose by the product behaviour they want and can draw the marble diagram.

Follow-up questions

Think of your answer first, then open the hint.

  1. Throttle latest: true or false?

    Show hint

    true emits the newest value in each interval; false emits the first.

  2. How do you debounce without Combine?

    Show hint

    .task(id:) with Task.sleep, or Async Algorithms.

Suggest a fix if something here is wrong or out of date.