New to Jamsocket: Y-Sweet, our batteries-included service for realtime apps.Learn More

Why Rayon replaced their database with Jamsocket

2025-01-09

Felicia Chang

Rayon is a next-generation CAD tool for architecture and interior designers. Recently, Rayon launched their V2, which introduced better performance and new features like version control.

I got together with Bastien Dolla co-founder of Rayon to learn more about their launch.

Hi Bastien! Your interview on Browsertech was a great deep dive into how you use Rust, WASM and WebGL. I’m super excited to dive into new topics today. To start, how would you describe Rayon? Rayon is a tool for architectural drawings. In the broad landscape of architecture tools, you have 2D tools like AutoCAD and Building Information Modeling (BIM) tools for drawing with semantic objects like walls, doors. Rayon offers a 2D BIM experience so you can work faster by drawing walls as well as lines like any vector graphics tool or CAD tool.

You recently launched Rayon v2. Can you talk a little bit about the transformation from v1 to v2? Our goal is really to create a new way to design the world. It's a big ambition that requires building a professional grade tool. The V2 launch was about entering the world of professional architecture design and becoming a fully featured alternative to existing CAD tools.

We rebuilt the whole rendering pipeline. So we now have a state of the art, multi threaded, tile based vector graphics renderer. Performance is absolutely key for a CAD tool because users can build very large models with millions of curves, so this was a really important milestone for us.

Wow, can you speak more about this new rendering engine? Drawing high quality 2D shapes with stroking, fills, patterns, is a very different problem than rendering a 3D model. So what we had to build was something less like a 3D pipeline and more like the technology you’d expect in a vector graphic tool. The goal was to produce very high quality anti-aliasing at a high performance all the while building a platform upon which we would be able to add common vector graphics features such as gradients, masking, blurs, box shadows, blending modes, etc. The state of the art technology for vector graphics is a tile-base renderer. In a very simplified manner, we divide the screen into small tiles and compute the coverage for each of these tiles according to what kind of curves are being drawn.

The trick is to parallelize this work and use the GPU as much as possible. The result is pretty great, and I think we now have one of the most advanced and performant vector graphics renderers in production. It's a foundational layer for what's coming.

For how technically dense this product is, how do you manage to have such high engineering velocity? When you build a design tool, there is so much to build. The minimum viable feature set is huge. Having the ability to rely on good tools that you don't need to build, has been really awesome for us. This is true for Jamsocket and also for the maturation of the whole Rust and WASM ecosystem.

Writing our engine in Rust was a key decision we made early on, for performance and reliability reasons. The amazing type system of Rust also allows us to significantly reduce the bug surface of the software. This gives us a very strong foundation to work as a team.

What was the impetus for using Jamsocket? In the very early beginning of Rayon, we actually stored all of the model data in a relational database. Very rapidly, we understood that this was not going to scale.

Using files to store the data of each model and persisting them on a blob storage such as S3 ended up being a much better solution. We now have more than 15 millions files in our storage, and we add a million more every two weeks. This would not be scalable otherwise.

Storing data on S3 is great, but fetching, parsing, and writing the entire model file to and from S3 for every modification isn’t practical, especially when updates occur multiple times per second. So that's where the Jamsocket session backend really comes in handy. We operate on a copy of the data in the session backend's memory so we can make quick updates and sync changes among several clients.

So the value of Jamsocket is having that source of truth in memory. Yeah, exactly. Just fetching the model from S3 and deserializing from the binary data can take a few seconds for very large models. Some of them can more than 100MB in size. So it's not possible to do that on every change. You need to load it once a user opens a model and have it in memory in a session backend like Jamsocket.

In addition to that, there are invariants we need to check to make sure the models never get corrupted when merging edits from multiple clients. For example, we never want an entity to point to a layer that doesn't exist anymore or accidentally create cycles. So we need to check that using some temporary structures we build in the Jamsocket backend.

One of the big features of the V2 launch was version control. What was involved in building it? So actually, version control was something we thought about from the very beginning. We call every modification on Rayon a commit because they're very similar to what you would have in Git. We store the whole history of all the commits in our backend, and we can recreate the whole model from that. It's quite a huge list, but it enables us to rebuild the whole history of the model at any point in time.

The other thing that made version control easier to implement was designing our data model with an ECS Framework or Entity Component System from the very beginning. This made the data very simple. You basically have entities, which are differentiated with an ID, and a bag of small components for each of them. So any modification of the model can be summarized as an insertion, a mutation, or a deletion of a component for a specific entity, which is very easy to expand as we add more features to Rayon.

Collaboration was a core part of your thesis from day one. But as you were building, did you encounter any unforeseen challenges with designing a multiplayer system? The main challenge is not building a multiplayer experience but building it in a robust way. There’s a big difference between prototypes and having something that is actually polished enough to support the tens of thousands of people who use Rayon every month.

There are so many specific edge cases that it requires thinking about the system in an almost theoretical or mathematical way. The goal is to really make the system correct by definition. Otherwise, the surface of what you need to take into account is so vast, and you're going to make mistakes.

It's been super cool to see Rayon grow. Have you encountered any scaling challenges? Every two weeks we add one terabyte of model file data to S3, so scaling is definitely an issue for us. The nice thing about having a data layer using Jamsocket and blob storage is that by definition it's highly scalable because S3 can store a lot of data cheaply. As for the compute the session backends run on, Jamsocket handles scaling that horizontally for us, and it has been working really well.

Do you think the complexity of the files themselves have increased? So we have two big limitations. The biggest one has to do with the browser. We're limited to 4GB of RAM per tab – we never thought we would hit those limits, but some of our users are building crazy models.

When you build an infinite canvas, people will really treat it as infinite. But there is a point at which it breaks. So we've added limits and warnings to explain to our users that when they exceed one million objects, they might experience performance issues.

There are of course still many things we can do to improve performance, and this is always an area of focus for us. But every time we improve performance, people will just create bigger, more complex models. It's a never-ending race.

I know you use Jamsocket in your own AWS cloud. What compelled you to BYOC? The initial reason was very simple – we had AWS credits. That's the basic answer.

But the other one, which is more important, is being able to guarantee to our users that we have full control over the data. The fact that everything happens in our cloud is a very important guarantee.

BYOC also enables us to use our own tools. For example, we use CloudWatch for logs, which has been super useful as well. That helps us debug and access the data easily.

Lastly, what is next at Rayon? We're not completely done on the basics! There are some features that we need to finish, such as dynamic blocks and even better import and export with AutoCAD. I would say we're 80 percent of the way there.

And then the big thing we're working on - which is something we've wanted to do from the get go - is AI. It’s going to be a big change, one that will be a game changer for our users.

And the last thing that we're starting to think about is 3D. And from the beginning, we always thought Rayon would be a 2D tool. But some users have expressed the idea that they want ways to generate 3D models directly from the 2D program. So this is something we're thinking about and will probably implement in the long term.

That's awesome. I'm looking forward to seeing what's next!


To learn more about Jamsocket's session backends, check out our blog post. Or get started building your next collaborative application with Y-Sweet, our open source Yjs server.

Ready to build?

Getting started is simple and quick. Explore documentation, or sign up and start building today.

Jamsocket