
When we first launched Productlane, we built it on Replicache, a client-side sync engine that works with most backend stacks. At first, performance was amazing. New workspaces loaded quickly, the Inbox felt instant, and moving between conversations had the local, responsive feel we were aiming for. For smaller teams, this held up well.
As some of our customers grew, the experience started to change. Larger workspaces accumulated thousands of emails, threads, changelog entries, and requests. Initial load times increased gradually at first, then dramatically. In the worst cases, the first sync took several minutes. On mobile, the app became close to unusable.

Nothing was technically broken. The system was doing exactly what it was supposed to. The problem was the underlying assumption.
Replicache works by pulling essentially all workspace data to the client. That provides a very convenient programming model. Every piece of data was always available on the frontend, which made derived views, counters, and cross-entity logic easy to build. For small datasets, this felt fast. At scale, it became a hard limit.
The core challenge we needed to solve was how to keep the instant UX of sync without downloading everything up front. Syncing years of historical data just to show the Inbox is not practical, especially on mobile. That meant moving to some form of partial sync.
Zero is a new sync engine built by Rocicorp, the team behind Replicache. It was specifically built to solve this partial sync problem.
Instead of syncing an entire dataset, the app subscribes to queries, and Zero synchronizes only the rows required to satisfy those queries. New queries run against the local cache first. If they can be satisfied by local data, the user gets an instant result. Otherwise they fall back to the server automatically.
By thoughtfully preloading queries, an app can tune the tradeoff between instant UX and fast app startup.
For Productlane, this was a much better fit. Loading the Inbox no longer required syncing every email a workspace had ever received. The app could fetch exactly what was needed for the current view, plus data likely to be needed for future views, without having to sync everything.
Over several months, we refactored essentially the entire frontend related to the Inbox and all Admin areas. All actions and data-fetching logic were rewritten to work with the new sync model.
With Replicache, we could assume that all workspace data was available on the client. With Zero, that assumption no longer holds, which forced us to rethink how data is accessed and computed. In practice, almost every part of the app was touched.
One of the biggest changes was the Requests admin page. Scoring had previously been calculated on the frontend by traversing connected entities in memory. That approach does not work with partial sync. We moved this logic into Postgres, introduced counters, and replaced repeated frontend recomputation with a single precomputed field. The result was significantly faster and easier to reason about.
Similar refactors happened across counters, dashboards, and the Inbox. In many cases, the new constraints led to simpler and more robust designs.
From a development perspective, the codebase is now much cleaner. A large number of complex, hard-to-understand files existed purely to support the previous sync model. With Zero, much of that complexity disappeared.
Since this was a big change that touched a lot of the UI, and introduced a new server component, a major question was how to roll it out safely and confidently.
Luckily sync engines have a trick for this. Because both Replicache and Zero are backed by Postgres, and because in both cases Postgres is the source of truth, both can run against the same database concurrently.
We simply put up a staging branch of Productlane with the new Zero-based UI and developed mainly against that while we kept the Replicache branch frozen except for bugfixes. When we were ready to start onboarding, we did it in stages: first a few users, then 10%, then half, then everyone. This gave us a way to gain experience and confidence in the system incrementally.
At the same time, we also adopted Cloud Zero , the new managed Zero service also from Rocicorp. This greatly reduced operational burden and complexity, since Rocicorp completely manages and maintains the server side of the sync engine.
Productlane is now dramatically faster, even for very large workspaces. Initial load times are no longer tied to historical data volume, and the app works reliably on mobile. The product scales in a way that matches how customers actually use it, but we've retained the feel of instant UX that customers loved so much from the beginning.
We did not migrate our Next.js app to Zero … yet. For now, Next.js continues to power our public portal pages and some API functionality. But one of the great things about Zero is that by using queries we can easily build fully public pages with it too. This is something we look forward to trying in the near future.
This was a major change, but a necessary one. Rebuilding the foundation took time, but it allowed us to remove a hard scaling limit and make Productlane feel fast again, even as our customers continue to grow.
Omnichannel support engineered for AI. Built around Linear to turn customer messages into code instantly.
