Behind the scenes: How we added real-time collaboration to a native Mac app
Find out about the challenges and tech behind this year’s biggest new feature in Sketch
Earlier this year we launched real-time collaboration in Sketch, available for anyone at no additional cost to your existing Sketch subscription. When we were developing the feature, we knew that there had to be a single source of truth for people to collaborate effectively. And that’s why it works as part of your Workspace, which is included with a subscription.
If you’ve already taken it for a spin, you may be curious about how the tech behind the feature works — and just how we integrated real-time collaboration into a native Mac app.
The challenges of ‘real-time’
We’ve all used products like Google Docs, with multiple cursors and avatars whizzing around the screen. That was, ultimately, our goal. But the biggest challenge in getting there was definitely technical. As a native Mac app, Sketch was originally built to handle documents on your local storage and therefore assumed that only you, the user, would open and edit the document.
Because of this, we had to revisit a lot of our code. But we were also adamant that we didn’t want to lose the things that make a native Mac app unique — such as the ability to work offline. And at the same time, in order for multiple people to work effectively together, updates had to appear near-instantly, for everyone.
Making real-time a reality
To overcome these challenges, we now stream patches to your Workspace as soon as you make a change — whether that’s moving an object, changing its fill, or something else entirely.
Sketch’s internal model has always been represented as a tree of objects. There’s a document at the root, then pages, groups, layers, styles, and so on. So when you make a change, an object in this tree changes a property. To generate a patch, we compare the document’s old state to the new, and the patch describes the route to take on the tree to reach the object and its updated properties.
Because these patches are incredibly small and targeted, conflicts are very rare. Two people can be working on the same shape, and one person can change its stroke while the other changes its fill, and it won’t cause any conflicts. And if changes do conflict? The latest patch to arrive at the server will win.
Because these patches are incredibly small and targeted, conflicts are very rare. Two people can be working on the same shape, and one person can change its stroke while the other changes its fill, and it won’t cause any conflicts.
The devil’s in the details
While sending patches back and forth sounds fairly straightforward, it’s the details that make the feature feel right. We can’t dig into them all in this post, but here are just a few that we wanted to highlight.
Undo or not to undo?
What makes Undo in this new world a tricky problem? Well, you only want to be undoing your own changes — even if someone else is working on the same thing. For example, let’s say you move a square in your document, and someone else then makes it blue. If you hit Undo, we want to end up with a blue square at the original location.
That means Undo isn’t just ‘rewind one step’ — it’s now ‘rewind, then replay the edits from other users, and send a patch of what I just undid’. We actually shipped this small update to the Undo system months before launching real-time collaboration. Hopefully, you didn’t even notice!
What makes a native Mac app
So far we’ve talked about ideal scenarios — where everyone is online and connections are stable. But some of our unique strengths as a Mac app mean extra complications for real-time collaboration.
Some of our unique strengths as a Mac app mean extra complications for real-time collaboration.
For example, if you work offline for a while — such as on a long flight — you need to be able to share your work again when you reconnect. So we made our patch system flexible enough to handle this. And, of course, you have a full version history for your document, so you can revisit an older version if your edits overwrote something another team member did.
Putting you in control
Similarly, we give people the freedom to update their Sketch version whenever they want. Whatever your reasons for staying on an older release are, it‘s your Mac, and you should be in control of what software you run on it. For us, this was an extra complication — we can’t assume that everyone is running the same version, and some versions may be incompatible with each other.
Whatever your reasons for staying on an older version of Sketch are, it‘s your Mac, and you should be in control of what software you run on it.
To solve this, we now allow people to collaborate across different releases as long as there are no fundamental changes in how we represent a document. That might happen if a release contains a big change, such as new OpenType features — because if we have two versions that build text layers in different ways, that could lead to issues.
Thankfully, these changes are rare enough that we can support collaboration sessions going back a long way. So you’ll still be able to collaborate in future, even if your team sticks with an older version.
The magic of Presence
So far we’ve talked about keeping documents in sync with patches. But we also wanted to include presence in real-time collaboration — so you could see other people’s cursors and their selections, and follow along with your collaborators.
In our first internal builds, there was no UI for collaboration. Changes from your collaborators just appeared, as if by magic. After all, we knew that keeping the document state consistent for everyone was the biggest technical challenge — if we couldn’t pull that off, the rest wouldn’t matter.
Honestly? It felt really weird. From the start of this process we knew we needed presence information, but seeing the feature work without it made that case even stronger. We set to work — and it soon gave us a surprise in a place we didn’t expect.
Scaling the server (and DDOSing ourselves)
We knew that, as more people started using real-time collaboration, we’d have a lot presence data and patches flying back and forth through our servers. And while not everyone would collaborate on day one, we had to have a system that scaled.
So we started testing the system with extensive metrics, to understand at a granular level how our servers were performing. And after our first beta, these metrics showed that our presence system simply wouldn’t scale. As it turns out, people move their cursors a lot — who knew?
So for the second beta, we rewrote presence to adapt to the network’s load. We sent fewer presence updates when the server load was high and smoothed the movements between the updates to avoid distracting jitters on the Canvas.
It worked really well, and the adaptive presence system has inspired us to apply lessons to other areas where we communicate with the server a lot. Our work here isn’t done, and you can expect more collaboration improvements in the future.
Real-time collaboration was probably the largest and most challenging feature we’ve ever built. But we’re incredibly proud that it’s now in your hands — we really think it feels amazing to collaborate together in Sketch in real-time. We hope you love it as much as we do.