# Timers vs actors

**URL:** <https://forums.swift.org/t/timers-vs-actors/83944>\
**Category:** Using Swift\
**Tags:** concurrency, actors, timer\
**Created:** [January 4, 2026, 10:57pm UTC](https://forums.swift.org/t/timers-vs-actors/83944 "2026-01-04T22:57:23Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [January 4, 2026, 10:57pm UTC](https://forums.swift.org/t/timers-vs-actors/83944/1 "2026-01-04T22:57:23Z")

</div>

Is there something like Timer (as per API) that's compatible with actors?

I cooked this one myself:

```swift
final class AsyncTimer: @unchecked Sendable {
    var task: Task<Void, Never>!

    func invalidate() {
        task.cancel()
    }

    @discardableResult static func scheduledTimer(withTimeInterval interval: TimeInterval, repeats: Bool, block: @Sendable @isolated(any) @escaping (AsyncTimer) async -> Void) -> AsyncTimer {
        let timer = AsyncTimer()

        timer.task = Task {
            if repeats {
                while !Task.isCancelled {
                    try? await Task.sleep(for: .seconds(interval))
                    await block(timer)
                }
            } else {
                try? await Task.sleep(for: .seconds(interval))
                if !Task.isCancelled {
                    await block(timer)
                }
            }
        }
        return timer
    }
}

```

which seems to be working alright (as in a "drop-in" replacement for the Timer API compatible with actors) however if there's something like this already in the standard library I would prefer using that instead.

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [January 5, 2026, 12:04am UTC](https://forums.swift.org/t/timers-vs-actors/83944/2 "2026-01-05T00:04:25Z")

</div>

I believe `Task.sleep` is the concurrency-friendly alternative, as long as you're okay with the lower precision. I also suggest you use something like [`swift-clocks`](https://github.com/pointfreeco/swift-clocks) to give yourself more control while testing.

---

<div class="post-metadata">

**Author:** ![KeithBauerANZ](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/keithbaueranz/32/27897_2.png) [@KeithBauerANZ](https://forums.swift.org/u/KeithBauerANZ)\
**Post date:** [January 5, 2026, 2:20am UTC](https://forums.swift.org/t/timers-vs-actors/83944/3 "2026-01-05T02:20:48Z")

</div>

There's also [AsyncTimerSequence in swift-async-algorithms](https://github.com/apple/swift-async-algorithms/blob/main/Sources/AsyncAlgorithms/AsyncTimerSequence.swift)

---

<div class="post-metadata">

**Author:** ![pyrtsa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/pyrtsa/32/740_2.png) [@pyrtsa](https://forums.swift.org/u/pyrtsa)\
**Post date:** [January 5, 2026, 5:45am UTC](https://forums.swift.org/t/timers-vs-actors/83944/4 "2026-01-05T05:45:43Z")

</div>

Also if you implement a timer by using `sleep(for:)`, you’ll end up getting events at a slightly longer interval than expected due to the extra execution time spent between the sleeps.

If keeping up with the frequency matters to you, better remember the original start instant and call `Task.sleep(until: start + n * interval)` for `n` = 1, 2, …, like `AsyncTimerSequence` does.
