Rebuilding Consumer Social In Rust
The following is my interview with Sylvain Laperche, Backend Engineer at amo, a consumer social startup comprised of veteran engineers from the social industry. I felt it was a real honor to hear about all the experience-informed decisions they're making in building a social service the second time around. Spoiler alert, this time they're doing it in Rust! As always, feel free to check out our extensive rust job board.
Drew: When I was studying up on amo, I learned that the company has a pretty interesting backstory including a lot of you working together previously. Could you explain a bit about how amo got started and how you got involved?
Sylvain: For a bit of history, zenly was acquired by Snap in 2017 and then shut down very abruptly in 2022. amo started with a lot of former zenly employees — it was basically the core team from zenly, getting together again to build something new in the social space. I joined amo almost immediately because I was part of the team at zenly and really enjoyed it. And since we were Rust lovers at zenly, it seemed like the obvious choice at amo. What's funny is that at zenly the decision to use Rust came from the strong conviction of 1 team member, but fast forward to amo and there was pretty much consensus from everyone to use it from the get go.
Drew: I saw that amo raised a bunch of money really early, and I was trying to figure out how that was possible until I discovered the backstory.
Sylvain: Yes, we’ve raised €18 million so far, in large part thanks to our strong track record.
Drew: I think it’s interesting that you decided to do it again with the same group. What is it about this group of people that pulled you back in?
Sylvain: Well, a lot of them are more than coworkers for me. Some of them are really good friends. This group is also very strong technically. I learn so much by working with them. So, I see amo as a good place for me to continue learning and progressing. On top of that, the vision speaks to me. I don’t find a lot of value in the current state of social media, so I’m excited by the chance to build something better.
Drew: Speaking of vision, could you explain a little bit about how amo’s approach to social media makes it different from what currently exists?
Sylvain: So, the current state of social media isn’t actually very social. It’s more like TV than anything. You don’t see a lot of your friends. You just have algorithms picking content for you from strangers. It’s a lot of influencers, and the content about your friends and family is buried under all of that. The friends and family focus of social media was present in the early days, but it doesn’t really exist anymore. We think a lot of this is because of the ad-based revenue model. So, in the long term when we eventually monetize, we’ll probably look to do something like a subscription-based model. That would align our incentives a lot more with the users. There are also things that are part of our culture, some of which comes from our experience at Zenly. For example, every employee is a heavy user of our applications along with their friends and family. So, we get a lot of first hand feedback that way.
Drew: That makes sense. I didn’t know that amo was planning on doing a subscription model. I agree that could help align the incentives better for the users. One of the things that I found very unusual about what you’re doing is the fact that you are using separate apps to deliver separate features instead of having one big app. Can you talk about that choice?
Sylvain: Yeah, this also came out of our experiences at zenly, which was a location sharing app. Maybe this is a bit less true now, but back then sharing your location was very divisive. Some people loved it, and others really hated it. We also had a lot of other features like a chat and a map where you could keep memories of places you’d visited. And, I think we probably lost some users because there were some who really wanted the chat but didn’t want the location aspects. So, with amo existing across several apps, people can very clearly opt in and out of the features they want. It’s also easier to design smaller apps. When apps get big and stuffed full of features, you start to worry a lot more about screen real estate. So, a simple app can have a really great user experience for the one thing it does. I see it as an extension of the K.I.S.S. principle in programming. With that said, the apps do integrate with each other. They share a common feed and friend list. So, you can get more out of each individual app if you use them all together.
Drew: I love it when companies make different choices like that, so I’m excited to see how this strategy will play out. By the way, what are the three apps?
Sylvain: The first app we released is called ID. It's a kind of limitless whiteboard that you and your friends can drop things on. We see it as a place to build your virtual identity and highlight all the different things about who you are and what you like. Some users, especially artists, have done some really crazy things. Some of them you just zoom and zoom and it feels like you’re discovering new worlds each time you zoom. It’s pretty crazy.
Sylvain: The second app, Capture, is for sharing videos of daily moments. The idea is really that you can just snap a quick video of the moment and then get back to living it. This speaks to one of our principles. We really feel like the most important thing is the time you spend with friends in reality. So, we want to avoid having the infinite feed and doom scrolling.
Sylvain: The last application is a location-sharing app called Bump. I think most people expected us to do this first since we were coming from zenly. But, we saved it as a surprise. Anyway, it’s a way to share your real-time location with your friends, explore the map, and meet up.
Drew: On the note of having three apps, I noticed that you launched those three apps all in a year. That seems like a lot! How did you move that fast?
Sylvain: One of the main reasons is that we are all experienced engineers. Many of us came from zenly, so we were even working on something very similar before. With this level of experience, we were able to avoid a lot of the pitfalls that you would run into if you were doing this for the first time. We’re also a small team, and we all work together onsite. That leads to a lot of easy communication across the different disciplines (designers, engineers, marketing, etc.). If we want to work on something quickly, we just sit together and prototype until we find something that sticks.
Sylvain: On the more technical side, we also have a lot of shared code. Usually, when you build a social app, there are some key pieces that you always need. For example, there’s a friend graph, there’s user onboarding, there’s basic interaction, a basic profile page, and so on. So, all of that we only had to build once. That made things very fast.
Drew: I’m not sure if this is correct, but I would guess that most engineers work on business to business applications. Since you’re working on a very consumer-facing product, what are the things that are different about working in that context?
Sylvain: It is very different. I had a business to business background before zenly, so I can speak to both sides. In social, you’re very close to your users. For example, I used to work at a storage company and at a telephone company. I don’t have petabytes of storage in my home, and I don’t personally run a cellular network! So, it’s harder to project yourself into the use cases when you’re building things like that. With amo, I can just imagine myself using the things I’m building. You also get to interact with users a lot more. We frequently invite users into our office to test the app together and share feedback. One of the funnest things is that you’ll just see people using your app when you’re out walking on the street or using public transportation!
Drew: That would be really cool to experience that! Have you had that happen already with amo or was that in the zenly days?
Sylvain: It’s still early days, so I haven’t met amo users in the wild yet. But, it definitely happened a lot with zenly.
Drew: Are you focused on growing in a certain location first? Or, is it just anywhere?
Sylvain: At first the focus is the U.S. market. It’s a very homogeneous market, with most users usings iOS. So, it was faster to launch there. But, a few months ago we released the Android version. That will broaden the market significantly for markets in Europe and Asia.
Drew: I really enjoyed reading your “Tech Stack” page because there were a lot of opinionated stances documented on there. And, I give a lot of weight to those opinions because of the veteran team. Did you write that page as a group, or was it written by the CTO or something?
Sylvain: It was actually a group project.
Drew: Cool! I wanted to ask a few questions about that page. For example, the page talks about using a monorepo.
Sylvain: Yeah, that’s a learning from our previous experience. Toward the end at zenly, we were moving toward a monorepo. So, with amo we did it right from the beginning. The reason we use a monorepo is mainly velocity. There’s just a lot of friction that ends up getting added if you want to make a full stack change when you don’t have a monorepo. We have a unified build system based on Bazel. So, in one command you can build the application and the backend, and if you break something you know it right away instead of discovering it after being several steps into your build process. We also find that the monorepo approach frees us from some of the language boundaries. So, someone that usually writes Rust can jump in and write some Swift to get something done.
Drew: The other question I had from that page is about this quote: “Our experience has taught us that migration will consume most of our time in the future. We’ve embraced that reality and used architectural decisions and practices that make the migration process as painless as possible.” That resonated with me because I’ve felt the pain of migrations (laughing). In fact, as I was preparing for this interview I was working on a big one. So, what are those practices?
Sylvain: It’s still a work in progress, but basically the core idea is to use the CDC or Change Data Capture patterns that a lot of databases like postgresql, ScyllaDB, and redis provide. We stream to a unified queue using Redpanda. From there, there’s a lot of ways we can use the data. For example, we could move data right from postgres to ScyllaDB. Since we have the history, we can do this on the fly while keeping everything up. We also have several teams that use analytics to learn about the user behavior. Usually, the queries they want to run don’t work well with the production pattern. So, we have some dedicated analytics databases that are fed from the data stream. Basically, the core idea is just having this stream of data that we replicate and archive under topics. So, if we need to migrate we can replace historical data by feeding with the live. We did a lot of migrations at zenly, and we really weren’t prepared for it. So, it was really hard to do on the fly.
Drew: Another question from the “Tech Stack” page… It says, “It may be surprising, but we didn't choose Rust primarily for ‘performance’, ‘memory safety’ or ‘fearless concurrency’. Those are huge perks and clearly comfort our choice, but the main reason is the unique combination of being able to iterate AND grow quickly.” That goes against a lot of the things you hear people say about Rust having a steep learning curve and such. So, can you explain that statement a little bit?
Sylvain: One of the things we’ve noticed with some other languages, which may be easier to learn, is that they cause problems in big codebases. For example, it can be very daunting when you change a piece of code. It can be hard to know if you’re going to break something else that you weren’t working on. Rust eliminates a lot of these worries because it focuses on doing a lot of correctness checks at compile time. A good example of this is null pointers. In Rust, you won’t have a null pointer that you forget to check because you have the Option type. Another example is the Result type for error checking. At zenly, we were using Go. If you forget to check an error in Go, you’re going to crash something. So, Rust may be a bit harder to learn depending on your background, but I find it easier to onboard new people into a big codebase when using Rust, because you’re much less likely to have a new employee crashing things with their first pull request or something like that. Previously, I worked in big codebases in C, C++, and even some Fortran (laughing), and I never even really knew where to start. Rust just gives a lot more confidence. Aside from the confidence for newcomers, the daily confidence in refactoring is great too. I’ve done some of the biggest refactors of my life in Rust. Multiple times I’ve been surprised to find that when I was done, it just worked. The compiler can really guide you through a refactoring. For example, when we released our first application, we had a lot of users signing up, and we had some verification issues with SMS not sending and that sort of thing. We rewrote the verification service that same day without issues. I’m not sure that would have been possible in another language.
Drew: I can definitely understand the benefits of having that confidence. I’m very used to working in other languages and feeling very suspicious when something works the first time.
Sylvain: Yeah, it’s a real problem. In our codebase, we exploit the type system to the maximum. We have a lot of custom types. We basically try to encode as much as possible into the types so that the compiler can catch as many errors as possible.
Drew: I’ve had other people say that exact thing in previous interviews! One thing that I noticed about what you’re doing with Rust is that you’re using it very heavily on the backend AND the frontend. That’s kind of unique. What’s the logic behind using Rust in your mobile apps?
Sylvain: Well the reason we don’t do everything either in Swift or Kotlin is that we want to have as much shared behavior as possible. All of the business logic we want to work in the same way in both applications. We don’t want Android to be a second-class citizen compared to iOS or vice-versa. So, having a shared Rust library helps with that. This also frees up the Swift and Kotlin developers to focus on the user experience and do things like create cool animations and such. They don’t have to think a lot about the business logic and how it works with the backend.
Sylvain: People might also wonder why we chose to do this native library in Rust. One of the reasons is that we use Rust on the backend. So, if we build the client side in Rust we can reuse code from the backend like errors types and those kinds of things. It really makes the integration easier. It’s also very important that Rust doesn’t have a garbage collector. If you’re calling another garbage-collected language from something like Kotlin, you have to be very careful. With Rust, you don’t have any surprises with memory. It’s also very cool to be able to use the same developer to drive a new feature from the backend almost all the way to the user experience.
Drew: So when you yourself work on a feature, you work on it from the backend all the way through to the client side?
Sylvain: That’s right.
Drew: That is cool. So, are there any tips or things people should keep in mind if they’re trying to do Rust in mobile apps?
Sylvain: Yeah, they need to be prepared for a lot of work honestly. It’s still not a very mature ecosystem. There are some libraries starting to appear, but we don’t have a clear winner yet in the way we do for some things like asynchronous where everyone just knows to use tokio. We use uniFFI from Mozilla. That does FFI in one direction. For the other direction, we had to build some codegen in-house. So, there are some rough edges. A lot of those rough edges are in the interaction with the native platform. iOS has its own API and quirks as an example. It’s really cool, but you have to be ready to really get under the hood to troubleshoot things. And, you’ll probably have to build libraries that you’ll be missing. The building blocks just aren’t all there yet. As I said, they’re starting to appear, but the ecosystem is still a bit young on that side.
Drew: So, you had to build some tooling in-house to make it work?
Sylvain: Yeah, I think we don’t have as many issues with Android anymore, because it's a bit better with Java. But for Swift at least, UniFFI only helps with one direction. I can’t remember which direction. But, we needed to go Swift to Rust and Rust to Swift. So yeah, we had to build some glue to make it work.
Drew: I think the people who read these interviews might be somewhat curious about what it’s like to work at the companies we talk to. Can you speak a little bit about what it’s like working at amo?
Sylvain: Yeah, I mentioned before that we are fully onsite. So, we see everyone every day. We have a really cool office in the center of Paris. So, it’s a really enjoyable environment to work in. We frequently do things together after work. Sometimes there are parties in the office to celebrate different milestones. And, like I mentioned, a lot of us are friends. So, we just end up doing a lot together. There are a couple of people who ran a marathon together recently. There’s a funny type of bar in France called a PMU where you can get scratch cards. There’s a group that goes to one of those bars every week. I think it started as a joke and now it’s a recurring event. One of the things I most like is the size of the teams. Because we’re still pretty small, there’s really no boundaries between the different functions. You can always just go and sit with a designer to work through a feature for example. Also, no matter where you work in the company, if you have a good idea, it can be included. We’ve had several ideas come from engineers rather than designers.
Drew: I think that was all of my questions. Thanks so much for talking Sylvain!
Sylvain: Thank you!
Know someone we should interview? Let us know: filtra@filtra.io