
Michael is the founder of smry, an all-in-one clean reader, read-it-later and archiving tool with >300k MAUs. Michael was inspired by Linear’s UX, and built smry with instant reactivity at the core of the app. To achieve this, he cobbled together his own sync engine using IndexedDB, R2 and Redis. He ran into a bunch of issues with this architecture. In this post, we’ll be describing why and how he switched to PowerSync, and what the outcome was.
How smry began
Michael had one primary requirement for smry’s web UI from day one: everything the user did needed to be instant. Opening of history? Clicking on an article? Navigation? All instant. Additionally, he had a long term vision of a mobile app for smry, which would need to support offline reading mode. It was also important to him that users of smry felt like they owned the content, and the best way to achieve that was to store the data in the browser using IndexedDB, as well as his backend DB (Neon).
His initial architecture was quite simple:

One issue with this architecture was that it wasn’t feasible to sync attachments into Postgres, so R2 was used for attachments on the backend, and localStorage on the client:

This architecture still didn’t deliver on the instant UI promise though, so Redis was added to speed up DB queries:

At this point, everything was miraculously working. There was one snag, however. The system was incredibly complex and hard to reason about, and coding agents would constantly be breaking stuff.
In Michael’s own words:
Honestly, Redis was the thing that made this work, because basically Redis was caching everything, and even if something broke, Redis would just cache it and the user would get something in a reasonable amount of time. Much faster than a database call. But it's still not fast enough. Redis isn't literally instant. There's still latency, especially depending on where the user is in the world. A lot of users are not in the US, so they don't have good internet connections.
The biggest problem for me was development velocity, to be honest. And whenever I'd deploy, I'd be like, "Where are my agents breaking something?” Honestly, the code got really, really messy.
Also, whenever I would change my database schema, IndexedDB would also be very, very annoying and break, right? Because I was doing database migrations, but IndexedDB doesn't care about your database. So, that was a massive problem. So I knew I needed some sync layer created with a little bit more foresight.
Michael sends out an SOS

After a casual chat between Michael and Kobie on X, Michael was intrigued:
My goals for a migration to PowerSync was, hey, massively simpler code, right?
The PowerSync FDE team jumped in to show Michael what smry could look like with PowerSync, and the app was migrated to a PowerSync architecture:

We’ll let Michael describe the benefits of this architecture in his own words:
With PowerSync at the core of smry, it made me much more excited about expanding the product. Now efforts are going into a mobile app because, hey, this is now much easier to think about with a mobile app, right? Now that we have PowerSync, it allows for a lot more developer velocity. Now I don't check my sync layer every time I want to push a fix.
And yes, the biggest thing for me was agents. So smry, a one-person project, I don't have time to learn new PowerSync skills. Agents seem to grok PowerSync. And at this point I can make changes without worrying that an agent's going to f*** up my DB or f*** up my sync or f*** up something else, which is quite nice. And so overall, the biggest unlock with PowerSync was development velocity. Because now I could, like, change things on my app.
Actually, there was a massive set of migrations that I needed to do, and I was delaying them because of the sync layer problem, because these migrations would make the sync layer just, like, much more complex. And now, with PowerSync, I could actually, like, redesign the app, make migrations, make massive changes. People who aren't me can push code without me worrying that something massive just broke that I have to spend, you know, hours or days fixing. So right now, like, the app went through some major app redesigns, and this was actually, like, pretty much enabled by PowerSync, if I'm being perfectly honest.
If you’re considering adding sync to the core of your product, or if you rolled your own sync and any of this resonates - we’d love to hear from you.
App Details
| App Name | smry | |
|---|---|---|
| Platforms | Web, iOS Extension | |
| Source Database | Neon | |
| Backend API Stack | Next.js | |
| AI Services via Vercel AI SDK | OpenRouter | Main model gateway: Remy chat, summaries, explanations, and text-to-speech |
| Groq | Fast inference for article cleanup, translation, quizzes, mind maps, and briefings | |
| External AI Services | Context.dev | Article extraction, file parsing, web search, page reads, and research |
| Classifier.dev | Article completeness checks, automatic tags, and feed relevance classification | |
| Configure.dev | Remy’s personalization, user memory/profile context, and connected tools | |
| Cloudflare Workers AI | File/image conversion and audio transcription using Whisper | |
| Pulpie | ML-based extraction of an article’s main content from HTML | |
| Pangram | AI authorship detection | |
| Client-side Frameworks | React PowerSync React hooks ( @powersync/react) | |
| ORMs | Drizzle PowerSync Drizzle Driver ( @powersync/drizzle-driver) | |
| Auth Provider | Clerk | |
| PowerSync Deployment | PowerSync Cloud | |
