<!--
{
  "documentType" : "article",
  "framework" : "Metal",
  "identifier" : "/documentation/Metal/synchronizing-events-across-multiple-devices-or-processes",
  "metadataVersion" : "0.1.0",
  "role" : "article",
  "title" : "Synchronizing events across multiple devices or processes"
}
-->

# Synchronizing events across multiple devices or processes

Use shareable events to synchronize your app’s work across multiple devices or processes.

## Discussion

The following figure and code show a shareable event that synchronizes graphics rendering on one device with compute processing on another.

![A timeline diagram that shows a shareable synchronization event encoded into two devices. Device A shows graphics-rendering commands, and device B shows compute-processing commands.](images/com.apple.metal/synchronizing-events-across-multiple-devices-or-processes-1@2x.png)

```swift
func setupMultipleDeviceEvent() {
    // Shareable event
    sharedEvent = deviceA.makeSharedEvent()
    
    // Built-in GPU command queue
    commandQueueA = deviceA.makeCommandQueue()
    
    // External GPU command queue
    commandQueueB = deviceB.makeCommandQueue()
}

func renderFrame() {
    guard
        let sharedEvent = sharedEvent,
        let commandBufferA = commandQueueA?.makeCommandBuffer(),
        let commandBufferB = commandQueueB?.makeCommandBuffer()
        else { return }
    
    // Device A (Graphics Rendering)
    /* Encode first render pass */
    commandBufferA.encodeSignalEvent(sharedEvent, value: 1)
    /* Encode second render pass */
    commandBufferA.encodeWaitForEvent(sharedEvent, value: 2)
    /* Encode third render pass */
    commandBufferA.commit()
    
    // Device B (Compute Processing)
    /* Encode first compute pass */
    commandBufferB.encodeWaitForEvent(sharedEvent, value: 1)
    /* Encode second compute pass  */
    commandBufferB.encodeSignalEvent(sharedEvent, value: 2)
    /* Encode third compute pass */
    commandBufferB.commit()
}
```

During setup, the code creates a shareable event ([`MTLSharedEvent`](/documentation/Metal/MTLSharedEvent)) and command queues on two different devices. Like the example shown in [Synchronizing events within a single device](/documentation/Metal/synchronizing-events-within-a-single-device), it encodes render commands onto the first queue and compute commands on the second queue.

You call the same methods when signaling and waiting on shared events as you do when working with events on a single device. The only difference is that the queues are associated with different devices and the event being used to synchronize access is a shared event.

The code shown above assumes you’ve created each resource on both device objects, and each pair of resources share a single allocation of memory. This strategy means that change made by one device object are visible to the other device object. For an example of how to do this, see [Selecting device objects for compute processing](/documentation/Metal/selecting-device-objects-for-compute-processing).

---

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)