<!--
{
  "availability" : [
    "iOS: 8.0.0 -",
    "iPadOS: 8.0.0 -",
    "macCatalyst: 13.1.0 -",
    "macOS: 10.11.0 -",
    "tvOS: -",
    "visionOS: 1.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "Metal",
  "identifier" : "/documentation/Metal/MTLCommandBuffer/addCompletedHandler(_:)",
  "metadataVersion" : "0.1.0",
  "role" : "Instance Method",
  "symbol" : {
    "kind" : "Instance Method",
    "modules" : [
      "Metal"
    ],
    "preciseIdentifier" : "c:objc(pl)MTLCommandBuffer(im)addCompletedHandler:"
  },
  "title" : "addCompletedHandler(_:)"
}
-->

# addCompletedHandler(_:)

Registers a completion handler the GPU device calls immediately after the GPU finishes running the commands in the command buffer.

```
func addCompletedHandler(_ block: @escaping MTLCommandBufferHandler)
```

## Parameters

`block`

A Swift closure or an Objective-C block that Metal calls after the GPU finishes running the commands in the command buffer.

## Discussion

You can register one or more completion handlers for the same command buffer. The GPU device’s driver (on the CPU) calls the completion handlers after the GPU finishes executing the command buffer.

> Important:
> You can only call this method before calling the command buffer’s ``doc://com.apple.metal/documentation/Metal/MTLCommandBuffer/commit()`` method.

For example, you can use the command buffer’s [`gpuEndTime`](/documentation/Metal/MTLCommandBuffer/gpuEndTime)
and [`gpuStartTime`](/documentation/Metal/MTLCommandBuffer/gpuStartTime) properties to calculate how much time the GPU spends running the command buffer.

```swift
commandBuffer.addCompletedHandler { commandBuffer in
    let start = commandBuffer.gpuStartTime
    let end = commandBuffer.gpuEndTime

    let gpuRuntimeDuration = end - start

    /* ... */
}
```

The completion handler is also a good place to check the [`status`](/documentation/Metal/MTLCommandBuffer/status) property to determine whether the GPU successfully completes the buffer’s commands. If the status is equal to [`MTLCommandBufferStatus.error`](/documentation/Metal/MTLCommandBufferStatus/error), you can investigate further by checking the [`error`](/documentation/Metal/MTLCommandBuffer/error) and log properties for more details about the issue. See [Command buffer debugging](/documentation/Metal/command-buffer-debugging) for more methods and properties that can help you isolate the issue.

> Warning:
> Avoid calling the ``doc://com.apple.metal/documentation/Metal/MTLCommandQueue/insertDebugCaptureBoundary()`` method within the completion handler, which can cause a debug-time deadlock if you request GPU frame capture.

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)