swift-concurrency-performance
Use this skill when reviewing Swift Concurrency performance and responsiveness, including task explosions, actor hopping, MainActor bottlenecks, cancellation, AsyncSequence cleanup, continuations, reentrancy, executor behavior, blocking async work, or async work that affects UI latency. Do not use it for general async/await syntax questions unless performance, responsiveness, cancellation, or lifetime is part of the task.
How do I install this agent skill?
npx skills add https://github.com/livsy90/ios-performance-agent-skills --skill swift-concurrency-performanceIs this agent skill safe to install?
- Gen Agent Trust Hubpass
This skill serves as a technical reference and diagnostic workflow for evaluating Swift Concurrency performance. It consists entirely of Markdown and YAML files, with no executable code, network activity, or security vulnerabilities detected.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
What does this agent skill do?
Swift Concurrency Performance
Purpose
Use this skill to review, diagnose, and improve Swift Concurrency code when async work affects UI responsiveness, throughput, memory, cancellation, task lifetime, actor contention, or correctness under load.
This skill is not a general Swift Concurrency tutorial. It is a performance and responsiveness review workflow.
When to use this skill
Use this skill when the task involves:
- UI stalls, slow interactions, hangs, or frame drops related to async work;
- excessive
Taskcreation, task groups, detached tasks, or unstructured concurrency; MainActorbottlenecks, actor hopping, actor queue buildup, or actor contention;- cancellation that does not stop work, navigation leaks, or tasks outliving their owner;
AsyncSequence,AsyncStream, long-running streams, buffering, or producer cleanup;- continuation bridges, delegate/callback wrappers, or async wrappers around legacy APIs;
- blocking calls inside async contexts, semaphores, synchronous I/O, locks, or cooperative pool starvation;
- actor reentrancy, duplicate in-flight work, cache stampedes, or inconsistent actor state after
await; - Swift 6 isolation behavior, explicit isolation,
@concurrent,nonisolated, or Sendable boundaries; - Instruments traces, logs, or production signals that point to concurrency-related latency, memory growth, or throughput loss.
When not to use this skill
Do not use this skill for:
- basic
async/awaitsyntax questions with no performance, lifetime, or responsiveness concern; - general architecture discussions where concurrency is not part of the critical path;
- purely SwiftUI rendering issues unless async lifecycle work contributes to the symptom;
- launch performance unless async startup work, task lifetime, or actor isolation is part of the launch path;
- runtime-level allocation, ARC, generics, or existential costs unless they interact with concurrency behavior;
- server-side concurrency questions unless the task is specifically about Swift Concurrency performance patterns.
Prefer another skill when a more specific domain dominates the task:
- use
ios-launch-performancefor app startup, first frame, first interaction, pre-main, dyld, or SDK launch work; - use
swiftui-performancefor SwiftUI invalidation, identity, layout, scrolling, or body cost; - use
ios-performance-profilingwhen the main task is choosing or interpreting profiling tools; - use
swift-runtime-performancefor allocations, ARC traffic, dispatch, existentials, generics, or copy-on-write costs.
Core workflow
- Identify the user-visible symptom: UI stall, slow interaction, low throughput, memory growth, duplicate work, leaked task, missed cancellation, actor contention, or blocked cooperative threads.
- Locate the async boundary:
Task, task group, actor method,MainActor, continuation, stream, lifecycle callback, delegate bridge, or legacy blocking API. - Determine the lifetime owner: view, view model, service, actor, request, app session, stream consumer, or detached background process.
- Separate required work from optional or deferrable work.
- Check whether concurrency is being used to express structure, isolation, and cancellation rather than as a vague performance fix.
- Look for blocking work inside async contexts.
- Check whether work that affects UI state is isolated narrowly and whether CPU-heavy work is kept off the main actor.
- Check cancellation propagation, especially across task groups, streams, continuations, loops, and navigation lifetimes.
- Check for actor reentrancy after every
awaitinside actor-isolated methods. - Propose the smallest safe change that improves lifetime, cancellation, isolation, or throughput.
- Include a validation path before calling the change a performance improvement.
Decision rules
- Treat
asyncas suspension, not as automatic background execution. - Do not assume concurrency improves performance. More tasks can increase scheduling overhead, memory pressure, actor contention, and cancellation complexity.
- Prefer structured concurrency when the parent owns the lifetime of the work.
- Use unstructured tasks only when the lifetime is deliberately independent and cancellation ownership is explicit.
- Use
Task.detachedonly as an explicit escape hatch from inherited context, priority, task-local values, and actor isolation. - Bound parallel work when the input size can grow.
- Keep
MainActorwork short and focused on UI state, presentation coordination, and main-thread-only APIs. - Move CPU-heavy work outside main-actor isolation, but do not cross isolation boundaries casually.
- Batch actor calls on hot paths when repeated hops dominate latency.
- After an
awaitinside an actor, assume actor state may have changed. - Use checked continuations by default and verify every path resumes exactly once.
- Treat stream termination and producer cleanup as part of the API contract.
- Prefer cancellation-aware loops and pipelines for long-running or high-volume work.
- Connect every performance claim to evidence or a validation plan.
Gotchas
- Do not recommend adding
asyncorTasksimply because code is slow. - Do not move work off the
MainActorif the API or UI state must remain main-actor isolated. - Do not leave CPU-heavy computation in a
@MainActortype just because the type also owns UI state. - Do not use
Task.detachedto silence isolation errors without explaining the lifetime, cancellation, priority, and data-safety consequences. - Do not create one child task per item for large or unbounded collections without limiting concurrency.
- Do not swallow cancellation with broad
catchblocks. - Do not assume cancelling a parent automatically stops legacy callbacks, streams, delegates, or manually retained producers.
- Do not wrap a blocking API in
asyncif the underlying work still blocks a cooperative executor thread. - Do not treat actor isolation as a duplicate-work prevention mechanism when the actor method suspends during a cache miss.
- Do not use unsafe continuations unless profiling shows checked continuation overhead matters and the resume contract is proven.
- Do not call an optimization successful without before/after validation.
Reference routing
Read these only when relevant:
references/concurrency-runtime.md— read when the task needs the mental model for tasks, suspension, cooperative executors, actor executors, priorities, structured concurrency, or why blocking async code is harmful.references/mainactor-responsiveness.md— read when the task involvesMainActor,@MainActortypes, UI state, view models, main-thread stalls,@concurrent, or moving CPU-heavy work away from UI isolation.references/task-lifetime-and-structure.md— read when the task involves structured concurrency, unstructured tasks, task ownership,Task {},Task.detached, view/view-model lifetimes, or tasks that outlive their owner.references/cancellation-and-task-lifetime.md— read when the task involves navigation cancellation, long-running work, cancellation propagation, cancellation swallowed bycatch, task groups, streams, or cancellation tests.references/bounded-task-groups.md— read when the task involveswithTaskGroup,withThrowingTaskGroup, parallel mapping, fan-out work, memory spikes, or limiting concurrency.references/actor-reentrancy.md— read when the task involves actor-isolated state, duplicate network requests, cache stampedes, state checks before and afterawait, or actor queue buildup.references/swift-6-isolation.md— read when the task involves Swift 6 isolation behavior, default actor isolation,@concurrent,nonisolated, Sendable boundaries, or migration-related performance regressions.references/blocking-legacy-apis.md— read when the task involves semaphores, synchronous file I/O, blocking networking, locks, callback APIs, old SDKs, or async wrappers around blocking work.references/continuation-safety.md— read when the task involveswithCheckedContinuation,withCheckedThrowingContinuation, delegate bridges, callback wrappers, timeout paths, cancellation paths, or exactly-once resume guarantees.references/asyncsequence-and-stream-cleanup.md— read when the task involvesAsyncSequence,AsyncStream,AsyncThrowingStream, long-running streams, buffering, producer lifetime,onTermination, orfor awaitloops.references/diagnostics-and-instruments.md— read when the user provides traces, logs, measurements, production signals, or asks how to validate concurrency-related performance changes.
Validation expectations
Recommend validation that matches the suspected issue:
- use Instruments when the symptom involves UI stalls, actor contention, task lifetime, blocked threads, or high task counts;
- use signposts when comparing before/after latency across async boundaries;
- use cancellation tests when work should stop after navigation, deallocation, timeout, or parent cancellation;
- use memory graphs or allocation instruments when streams, task groups, or long-lived tasks may retain producers or large values;
- use logs with task identifiers or request identifiers when checking duplicate in-flight work;
- use XCTest performance tests only when the workload is repeatable enough to produce meaningful comparisons;
- use production metrics when local traces cannot reproduce tail latency or rare stuck tasks.
Do not present a concurrency refactor as a performance win unless there is a clear validation path.
Output expectations
When reviewing code, respond with:
- Finding — the likely concurrency performance, lifetime, isolation, or responsiveness issue.
- Why it matters — the impact on UI latency, throughput, memory, cancellation, actor contention, or correctness.
- Evidence — the code pattern, trace symptom, lifecycle mismatch, missing cancellation path, blocking call, actor hop pattern, or continuation/stream contract issue.
- Recommended change — the smallest safe change first; avoid broad rewrites unless the design itself causes the issue.
- Trade-offs — what the change improves and what it may complicate.
- Validation — how to verify the result with Instruments, signposts, cancellation tests, logs, memory tools, UI behavior, or production metrics.
When the task asks for an investigation plan, respond with:
- the symptom to reproduce;
- the suspected async boundary;
- the likely lifetime or isolation owner;
- the first trace or log to collect;
- the signal that would confirm or reject the hypothesis;
- the smallest next code area to inspect.
When the task asks for an explanation, keep it practical:
- explain the model briefly;
- show one concrete iOS or Swift example only if needed;
- name the common misconception;
- include a validation or debugging technique. :::
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/livsy90/ios-performance-agent-skills/swift-concurrency-performance">View swift-concurrency-performance on skillZs</a>