# \[Pitch\] \`withTimeout\` method

**URL:** <https://forums.swift.org/t/pitch-withtimeout-method/84447>\
**Category:** Swift Async Algorithms\
**Tags:** asyncawait, async-algorithms\
**Created:** [January 29, 2026, 10:11am UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447 "2026-01-29T10:11:23Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![vanvoorden](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/vanvoorden/32/33619_2.png) [@vanvoorden](https://forums.swift.org/u/vanvoorden)\
**Post date:** [January 29, 2026, 7:43pm UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/21 "2026-01-29T19:43:28Z")

</div>

> [@FranzBusch](#):
>
> ```swift
> nonisolated(nonsending) public func withTimeout<Return, Failure: Error, Clock: _Concurrency.Clock>(
> in timeout: Clock.Instant.Duration,
> tolerance: Clock.Instant.Duration? = nil,
> clock: Clock = .continuous,
> body: nonisolated(nonsending) () async throws(Failure) -> Return
> ) async 
> 
> ```

AFAIK the minimum supported compiler from `swift-async-algorithms` is 5.7:

> <https://github.com/apple/swift-async-algorithms/blob/103f5e5beab0896f7ec5e85d9383ce0f026065f5/Package%40swift-5.7.swift#L1>

But typed throws I believe requires a 6.0 compiler… how would the `withTimeout` function be able to compile from 5.7?

---

<div class="post-metadata">

**Author:** ![Philippe\_Hausler](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/philippe_hausler/32/22569_2.png) [@Philippe\_Hausler](https://forums.swift.org/u/Philippe_Hausler)\
**Post date:** [January 29, 2026, 8:01pm UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/22 "2026-01-29T20:01:20Z")

</div>

I would imagine that this would actually be gated with a newer availability than 5.7; it would likely be available from a given tag of swift-async-algorithms instead

---

<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 29, 2026, 9:31pm UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/23 "2026-01-29T21:31:44Z")

</div>

> [@allevato](#):
>
> this feels like one of those small-but-impactful fundamental building blocks that deserves inclusion in the standard library

+1. Standard library is the most logical place for this fundamental feature.

---

<div class="post-metadata">

**Author:** ![ksluder](https://avatars.discourse-cdn.com/v4/letter/k/eada6e/32.png) [@ksluder](https://forums.swift.org/u/ksluder)\
**Post date:** [January 29, 2026, 10:01pm UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/24 "2026-01-29T22:01:32Z")

</div>

Waiting for the original task to complete seems to considerably limit the usefulness of this function. Since any async work can block on a task that doesn’t pay attention to cancellation, is there actually a practical advantage of `withTimeout` compared to just checking the current time after awaiting the original task?

I think a much more useful version of this would be to cancel and _detach_ the child task when the timeout expires. The child task can then clean itself up without impeding the task that asked for the timeout in the first place. `TimeoutError` could still offer a `Future<UnderlyingError>` in case the caller wants to report any errors that happen post timeout.

---

<div class="post-metadata">

**Author:** ![Philippe\_Hausler](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/philippe_hausler/32/22569_2.png) [@Philippe\_Hausler](https://forums.swift.org/u/Philippe_Hausler)\
**Post date:** [January 29, 2026, 11:21pm UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/25 "2026-01-29T23:21:50Z")

</div>

> [@ksluder](#):
>
> Waiting for the original task to complete seems to considerably limit the usefulness of this function.

Just because it is marked as async does not mean it is concurrent. The other runtime functions are built upon the idea of avoiding fully unstructured tasks - this API should do the same; it is up to the callee to determine if an early return is possible/warrented. It might be worthwhile to instead of throwing have a version that calls a callback; ala `withTaskCancellationHandler` so perhaps it would be `withDeadlineHandler` or something of the sorts.

> [@ksluder](#):
>
> could still offer a `Future<UnderlyingError>`

Future in Swift concurrency is spelled `Task`. In general that concept is not ideal and causes some level of possibility of performance hits. I don't think we should be offering that many APIs that create them unless they are either funneled into a singular task and multiplexed via something like withTaskGroup or they are somehow intended to be a root level, top of the app structure, type thing. I don't see temporal termination as part of that root.

---

<div class="post-metadata">

**Author:** ![ksluder](https://avatars.discourse-cdn.com/v4/letter/k/eada6e/32.png) [@ksluder](https://forums.swift.org/u/ksluder)\
**Post date:** [January 30, 2026, 12:01am UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/26 "2026-01-30T00:01:51Z")

</div>

> [@Philippe\_Hausler](#):
>
> Just because it is marked as async does not mean it is concurrent.

A useful `withTimeout` API requires _some_ form of concurrency so that the timer can fire while the task is being awaited. While devolution into executing the entire original task is a reasonable failure mode in a non-concurrent or otherwise degraded system, I would expect this API to be designed for the case where the timeout can fire concurrently with the original task.

As pitched, the behavior of `withTimeout` is useless if the task might block for long periods of time. The prohibition on blocking only applies to the default cooperative threadpool; a custom executor could be designed specifically for blocking operations, such as an `epoll`-driven server or a façade around a web service. A “timeout” API that doesn’t actually time out when my HTTP request stalls isn’t a very useful timeout API.

Even in the case of pure compute tasks, the pitched API depends on the entire task tree checking for cancellation. Furthermore, the task tree must check frequently enough to respond to the timeout cancellation within a tolerable window, but not so frequently as to wipe out the benefits of parallelism. This is extremely difficult to fine-tune, especially since it will vary based on the hardware.

---

<div class="post-metadata">

**Author:** ![ibex](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ibex/32/30439_2.png) [@ibex](https://forums.swift.org/u/ibex)\
**Post date:** [January 30, 2026, 12:08am UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/27 "2026-01-30T00:08:59Z")

</div>

> [@FranzBusch](#):
>
> If the operation completes before the timeout expires, the function returns the result; if the timeout expires first, the operation is cancelled and a `TimeoutError` is thrown **once the operation completed**.

I have always wanted something like this function, but I second @ksluder. The implication of " **once the operation completed**" would diminish the usefulness of this function in real life scenarios.

---

<div class="post-metadata">

**Author:** ![Honza\_Dvorsky](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/honza_dvorsky/32/29867_2.png) [@Honza\_Dvorsky](https://forums.swift.org/u/Honza_Dvorsky)\
**Post date:** [January 30, 2026, 11:46pm UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/28 "2026-01-30T23:46:19Z")

</div>

> [@ksluder](#):
>
> As pitched, the behavior of `withTimeout` is useless if the task might block for long periods of time.

In my head I actually translate `withTimeout` to "please mark my task as canceled after this amount of time". So not only is it not useless, it's exactly what I'd expect in structured concurrency. The comment sounds to me to be related to the concept of cooperative cancelation rather than to specifically triggering cancelation after a timeout. Wouldn't this argument apply to manual cancelation too?

---

<div class="post-metadata">

**Author:** ![ksluder](https://avatars.discourse-cdn.com/v4/letter/k/eada6e/32.png) [@ksluder](https://forums.swift.org/u/ksluder)\
**Post date:** [January 30, 2026, 11:51pm UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/29 "2026-01-30T23:51:17Z")

</div>

> [@Honza\_Dvorsky](#):
>
> please mark my task as canceled after this amount of time

That interpretation makes much less of an implication that the caller can use this to reliably reassert execution within a short window around the timeout.

Would folks consider a name like `withAutomaticCancellation(after:)` for the pitched semantics?

---

<div class="post-metadata">

**Author:** ![mattie](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mattie/32/13267_2.png) [@mattie](https://forums.swift.org/u/mattie)\
**Post date:** [January 31, 2026, 12:25am UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/30 "2026-01-31T00:25:01Z")

</div>

I’m so happy to see something along these lines proposed! I also kinda agree that the standard library feels like a nicer spot for this to land, even though it has downsides.

> [@ksluder](#):
>
> Would folks consider a name like `withAutomaticCancellation(after:)` for the pitched semantics?

Now this is an interesting idea. Because while I imagine this name will be very unappealing to experts, I think it will save a lot of non-experts confusion and frustration.

---

<div class="post-metadata">

**Author:** ![FranzBusch](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/franzbusch/32/19447_2.png) [@FranzBusch](https://forums.swift.org/u/FranzBusch)\
**Post date:** [January 31, 2026, 3:37pm UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/31 "2026-01-31T15:37:45Z")

</div>

Thanks for all the great feedback so far. I updated the [pitch](https://github.com/apple/swift-async-algorithms/pull/396) with the following changes:

- Moved to a deadline based approach and renamed the method to `withDeadline` and the error to `DeadlineError`
- Enhanced the error to contain the `Clock` and the deadline `Instant`

Curious to hear what everyone thinks about the above changes.

> Waiting for the original task to complete seems to considerably limit the usefulness of this function. Since any async work can block on a task that doesn’t pay attention to cancellation, is there actually a practical advantage of `withTimeout` compared to just checking the current time after awaiting the original task?

I am strongly against detaching the task that runs the operation and returning from the method early. This is going to break all the guarantees of structured concurrency where you can reason about the state of your program by looking at the linear flow of your code. If the task were to be detached, then anything running with a deadline becomes unpredictable. While I understand that in bad scenarios the operation might run significantly longer than the deadline, this is strictly a bug in the code inside the operation. If a developer wants to detach the task, they can do that manually inside their operation closure by setting up a detached task and handling cancellation and awaiting the result manually.

---

<div class="post-metadata">

**Author:** ![ksluder](https://avatars.discourse-cdn.com/v4/letter/k/eada6e/32.png) [@ksluder](https://forums.swift.org/u/ksluder)\
**Post date:** [January 31, 2026, 4:25pm UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/32 "2026-01-31T16:25:40Z")

</div>

> [@FranzBusch](#):
>
> While I understand that in bad scenarios the operation might run significantly longer than the deadline, this is strictly a bug in the code inside the operation.

Not checking for cancellation is not a bug. In fact, checking for cancellation too frequently could be a bug. And there are some operations which are simply not interruptible from the CPU side, such as blocking on GPU work.

---

<div class="post-metadata">

**Author:** ![NotTheNHK](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/notthenhk/32/43199_2.png) [@NotTheNHK](https://forums.swift.org/u/NotTheNHK)\
**Post date:** [January 31, 2026, 5:36pm UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/33 "2026-01-31T17:36:30Z")

</div>

Disagree, while it isn’t a bug in Swift’s concurrency model, it would certainly be an implementation bug. Also, executing long-running synchronous work in Swift’s default execution context is, in most cases, not a good idea.

---

<div class="post-metadata">

**Author:** ![ksluder](https://avatars.discourse-cdn.com/v4/letter/k/eada6e/32.png) [@ksluder](https://forums.swift.org/u/ksluder)\
**Post date:** [January 31, 2026, 5:42pm UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/34 "2026-01-31T17:42:16Z")

</div>

> [@NotTheNHK](#):
>
> Disagree, while it isn’t a bug in Swift’s concurrency model, it would certainly be an implementation bug.

I categorically disagree with this, and I would actually implore the designers of Swift Concurrency to back me up on this: proper adoption of Swift Concurrency _never requires_ the client to check for cancellation. In other words, omission of a cancellation check may be a missed opportunity for a performance gain, but it is _not a bug._

> [@NotTheNHK](#):
>
> Also, executing long-running synchronous work in Swift’s default execution context is, in most cases, not a good idea.

Swift concurrency is not limited to the default cooperative thread pool. There is nothing wrong with blocking for long periods on an executor that is specifically designed for such. I would expect an operation called `withTimeout` to preemptively return execution to my awaiting caller while disposing of the blocked task. This is how all existing timeout APIs have worked for blocking I/O and GPU operations since preemptive multitasking became widespread on consumer machines in the mid-1990s.

---

<div class="post-metadata">

**Author:** ![NotTheNHK](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/notthenhk/32/43199_2.png) [@NotTheNHK](https://forums.swift.org/u/NotTheNHK)\
**Post date:** [January 31, 2026, 5:49pm UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/35 "2026-01-31T17:49:06Z")

</div>

> Swift concurrency is not limited to the default cooperative thread pool.

I never said otherwise, but that’s exactly what I was talking about with “Swift’s default execution context” (default actors, GCE).

> I would expect an operation called `withTimeout` to preemptively return execution to my awaiting caller while disposing of the blocked task.

Swift concurrency is not preemptive but cooperative, and I strongly believe we should stay true to this.

---

<div class="post-metadata">

**Author:** ![ksluder](https://avatars.discourse-cdn.com/v4/letter/k/eada6e/32.png) [@ksluder](https://forums.swift.org/u/ksluder)\
**Post date:** [January 31, 2026, 5:52pm UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/36 "2026-01-31T17:52:08Z")

</div>

> [@FranzBusch](#):
>
> This is going to break all the guarantees of structured concurrency where you can reason about the state of your program by looking at the linear flow of your code. If the task were to be detached, then anything running with a deadline becomes unpredictable.

For the record, I would like to specifically acknowledge this. It’s a significant but extremely useful tradeoff. Timeouts are very often used as a safety mechanism to catch accidentally deadlocked or stalled operations. If `withTimeout` results in a new concurrent task that’s stuck waiting for the first one to complete, then it’s actually counterproductive, and an attractive nuisance that will be deployed in the exact scenario it will make worse.

The name `withAutomaticCancellation` eschews the implied utility that comes with the word “timeout.”

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [January 31, 2026, 8:12pm UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/37 "2026-01-31T20:12:31Z")

</div>

Happy to discuss and push this topic forward a bit, but sadly I’ve gotten super sick in the middle of travel so will need a few days to get better and formulate thoughts more clearly here.

Short version though for now: We could experiment with something in that package. Whatever we come up there does not dictate how such API will look like inside the Concurrency library. The concurrency library must be the one offering this – this is a fundamental piece – and if we’re introducing a temporary thing somewhere, I want everyone to understand that this is very likely to be very quickly deprecated and replaced by a Concurrency library impl.

Specific implementation requirements I had from last time I was investigating this:

- This must be expressed as deadlines, as timeouts don’t compose very well, while deadlines do naturally (you can only add deadlines “before” an existing deadlines, adding one after an existing one is a noop – I’ll speak to that more later, when I’m not sneezing every other sentence 🤧 ). I see Franz already took this feedback, there’s some nuances to check here still though.
- We need to be able to read a task deadline, in order for propagation across process boundaries. This includes IPC/XPC use-cases but also network.

I need a few days to get better and will give this proposal a proper review then. Other than the “this might just get deprecated immediately” I don’t mind experimenting in packages for impls, even if the Swift runtime can do these things better. We may gain some experience prototyping before we commit the API to the stdlib this way.

---

<div class="post-metadata">

**Author:** ![NotTheNHK](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/notthenhk/32/43199_2.png) [@NotTheNHK](https://forums.swift.org/u/NotTheNHK)\
**Post date:** [January 31, 2026, 8:31pm UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/38 "2026-01-31T20:31:16Z")

</div>

This has always been my interpretation of the swift-async-algorithms package: a place that serves as an extension of Swift’s concurrency implementation, where we might move some APIs to the concurrency library in the future.

P.S. Wishing you a speedy recovery.

---

<div class="post-metadata">

**Author:** ![artemredkin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/artemredkin/32/7066_2.png) [@artemredkin](https://forums.swift.org/u/artemredkin)\
**Post date:** [February 2, 2026, 11:05am UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/39 "2026-02-02T11:05:07Z")

</div>

Super happy with this proposal, huge +1 from me, but I wish macOS target was not as high, are typed throws the main reason for macOS 15.0+?

---

<div class="post-metadata">

**Author:** ![Philippe\_Hausler](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/philippe_hausler/32/22569_2.png) [@Philippe\_Hausler](https://forums.swift.org/u/Philippe_Hausler)\
**Post date:** [February 2, 2026, 4:40pm UTC](https://forums.swift.org/t/pitch-withtimeout-method/84447/40 "2026-02-02T16:40:44Z")

</div>

They are the primary reason; yes.

[Previous page](https://forums.swift.org/t/pitch-withtimeout-method/84447.md?page=1)

[Next page](https://forums.swift.org/t/pitch-withtimeout-method/84447.md?page=3)
