Use when profiling async/await performance, diagnosing actor contention, or investigating thread pool exhaustion. Covers Swift Concurrency Instruments template, task visualization, actor contention analysis, thread pool debugging.
/plugin marketplace add CharlesWiltgen/Axiom/plugin install axiom@axiom-marketplaceThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Profile and optimize Swift async/await code using Instruments.
✅ Use when:
❌ Don't use when:
| Track | Information |
|---|---|
| Swift Tasks | Task lifetimes, parent-child relationships |
| Swift Actors | Actor access, contention visualization |
| Thread States | Blocked vs running vs suspended |
Symptom: UI freezes, main thread timeline full
Solution patterns:
// ❌ Heavy work on MainActor
@MainActor
class ViewModel: ObservableObject {
func process() {
let result = heavyComputation() // Blocks UI
self.data = result
}
}
// ✅ Offload heavy work
@MainActor
class ViewModel: ObservableObject {
func process() async {
let result = await Task.detached {
heavyComputation()
}.value
self.data = result
}
}
Symptom: Tasks serializing unexpectedly, parallel work running sequentially
Solution patterns:
// ❌ All work serialized through actor
actor DataProcessor {
func process(_ data: Data) -> Result {
heavyProcessing(data) // All callers wait
}
}
// ✅ Mark heavy work as nonisolated
actor DataProcessor {
nonisolated func process(_ data: Data) -> Result {
heavyProcessing(data) // Runs in parallel
}
func storeResult(_ result: Result) {
// Only actor state access serialized
}
}
More fixes:
Symptom: Tasks queued but not executing, gaps in task execution
Cause: Blocking calls exhaust cooperative pool
Common culprits:
// ❌ Blocks cooperative thread
Task {
semaphore.wait() // NEVER do this
// ...
semaphore.signal()
}
// ❌ Synchronous file I/O in async context
Task {
let data = Data(contentsOf: fileURL) // Blocks
}
// ✅ Use async APIs
Task {
let (data, _) = try await URLSession.shared.data(from: fileURL)
}
Debug flag:
SWIFT_CONCURRENCY_COOPERATIVE_THREAD_BOUNDS=1
Detects unsafe blocking in async context.
Symptom: High-priority task waits for low-priority
// ✅ Explicit priority for critical work
Task(priority: .userInitiated) {
await criticalUIUpdate()
}
Swift uses a cooperative thread pool matching CPU core count:
| Aspect | GCD | Swift Concurrency |
|---|---|---|
| Threads | Grows unbounded | Fixed to core count |
| Blocking | Creates new threads | Suspends, frees thread |
| Dependencies | Hidden | Runtime-tracked |
| Context switch | Full kernel switch | Lightweight continuation |
Why blocking is catastrophic:
Run these checks first:
Is work actually async?
await)Holding locks across await?
// ❌ Deadlock risk
mutex.withLock {
await something() // Never!
}
Tasks in tight loops?
// ❌ Overhead may exceed benefit
for item in items {
Task { process(item) }
}
// ✅ Structured concurrency
await withTaskGroup(of: Void.self) { group in
for item in items {
group.addTask { process(item) }
}
}
DispatchSemaphore in async context?
withCheckedContinuation instead| Issue | Symptom in Instruments | Fix |
|---|---|---|
| MainActor overload | Long blue bars on main | Task.detached, nonisolated |
| Actor contention | High red:blue ratio | Split actors, use nonisolated |
| Thread exhaustion | Gaps in all threads | Remove blocking calls |
| Priority inversion | High-pri waits for low-pri | Check task priorities |
| Too many tasks | Task creation overhead | Use task groups |
Safe with cooperative pool:
await, actors, task groupsos_unfair_lock, NSLock (short critical sections)Mutex (iOS 18+)Unsafe (violate forward progress):
DispatchSemaphore.wait()pthread_cond_waitThread.sleep() in TaskWWDC: 2022-110350, 2021-10254
Docs: /xcode/improving-app-responsiveness
Skills: axiom-swift-concurrency, axiom-performance-profiling, axiom-synchronization
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.