<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <generator>Persumi - Level up your writing and blogging with AI</generator>
  <category label="persumi" term="persumi"/>
  <category label="Persumi" scheme="http://persumi.com/c/persumi" term="persumi"/>
  <link href="http://persumi.com/c/persumi/t/persumi"/>
  <link href="http://persumi.com/c/persumi/t/persumi/feed/rss"/>
  <link rel="self" href="http://persumi.com/c/persumi/t/persumi/feed/atom"/>
  <subtitle>The official community of Persumi. Bug reports and feature requests are welcomed!</subtitle>
  <id>http://persumi.com/c/persumi/t/persumi</id>
  <title>Persumi - Communities</title>
  <updated>2026-04-14T20:50:09.295542Z</updated>
  <entry>
    <content type="html">&lt;![CDATA[&lt;p&gt;
Like many software engineers and indie hackers, I dream of and experiment with different product ideas every now and then.&lt;/p&gt;
&lt;p&gt;
Five years ago, in 2018, I toyed with an idea where &lt;strong&gt;personas&lt;/strong&gt; and &lt;strong&gt;expressions&lt;/strong&gt; are the enablers for showcasing people’s talents and interests.&lt;/p&gt;
&lt;p&gt;
I called it, &lt;strong&gt;Persumi&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
The Origin&lt;/h2&gt;
&lt;p&gt;
The original idea was to break the pattern of modern day social media platforms like Facebook, Instagram and Twitter, where every person is hidden behind a two-dimensional facade. Words and photos are often used to skew the way people see who we are.&lt;/p&gt;
&lt;p&gt;
After a while, everything becomes bland as information is being overloaded and people’s attention span starts to decrease drastically. The signal to noise ratio is so low that more and more algorithms and tracking are invented to help curate content so advertisers would keep spending their dime on those social media platforms.&lt;/p&gt;
&lt;p&gt;
It’s a vicious cycle. There is now even a term for it: &lt;a href=&quot;https://knowyourmeme.com/memes/enshittification&quot;&gt;&lt;strong&gt;enshittification&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;
Enshittification is when an online platform becomes more monetized and less user-oriented the longer it lasts.  &lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
The Goals&lt;/h2&gt;
&lt;p&gt;
With Persumi, personas and expressions are the key concepts to modernise content creation, curation and consumption in a simple yet meaningful way.&lt;/p&gt;
&lt;p&gt;
I set out a few goals for Persumi, in the hope to change the social media landscape for the better:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
Find ways to encourage the creation and consumption of long form content  &lt;/li&gt;
  &lt;li&gt;
Make it easy for people to create vastly different topics without confusing their audiences  &lt;/li&gt;
  &lt;li&gt;
Make it easy for people to follow different topics, rather than relying on following users  &lt;/li&gt;
  &lt;li&gt;
Allow people to decorate their pages with their own personality and style via HTML + CSS, &lt;em&gt;bring back &lt;a href=&quot;https://en.wikipedia.org/wiki/Myspace&quot;&gt;MySpace&lt;/a&gt;!&lt;/em&gt;  &lt;/li&gt;
  &lt;li&gt;
An API-driven, open marketplace that allows developers to build and extend advanced functionalities  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Some example use cases outlined in my original “pitch deck”:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
&lt;strong&gt;social personas&lt;/strong&gt; for friends, family, work…  &lt;/li&gt;
  &lt;li&gt;
&lt;strong&gt;interest personas&lt;/strong&gt; as a gamer, traveller, photographer…  &lt;/li&gt;
  &lt;li&gt;
&lt;strong&gt;functional personas&lt;/strong&gt; for travel plan, marketing campaign…  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
It kind of makes sense, but there is one problem.&lt;/p&gt;
&lt;h2&gt;
The Problem&lt;/h2&gt;
&lt;p&gt;
The age-old “chicken-and-egg” problem of starting a platform that thrives on user-generated content - how do I get early-adopter users without a decent amount of users and content already?&lt;/p&gt;
&lt;p&gt;
These goals might be nice, but they probably aren’t enough to convince users to drop what they are used to for something experimental and without users or traction.&lt;/p&gt;
&lt;p&gt;
So I parked this idea…&lt;/p&gt;
&lt;h2&gt;
Revisit the Problem&lt;/h2&gt;
&lt;p&gt;
A few years have gone by, and with a whole pandemic thrown into the mix, this Persumi idea has all of a sudden awakened me yet again.&lt;/p&gt;
&lt;p&gt;
In early 2023, after wrapping up my last freelancing project I decided to tackle Persumi’s chicken-and-egg problem once more.&lt;/p&gt;
&lt;p&gt;
I reflected on how my own content consumption behaviour has changed over the past few years. Instead of reading physical books, e-books or blogs, I consume more and more podcasts and audio-books. Instead of consuming content fully concentrated, I often consume them while on the go or during my workouts.&lt;/p&gt;
&lt;p&gt;
Then a light bulb moment occurred - I don’t &lt;em&gt;need&lt;/em&gt; to build a massive social network platform to compete with the likes of Twitter. I just need to build a “simple” blogging platform for my own use and my own content. If I find it useful, other people will find it useful too. It doesn’t need to go viral, it just needs to be steadly discovered by like-minded people who share my frustration and vision in content creation and consumption.&lt;/p&gt;
&lt;h2&gt;
Iterate the Idea&lt;/h2&gt;
&lt;p&gt;
With a few more years of experience of leading teams and building products under my belt, I thought about how to iterate on the original idea, and came up with three main “twists” if you will:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;
Long form text content needs to be consumable in audio form, to suit the modern lifestyle  &lt;/li&gt;
  &lt;li&gt;
An API-driven open marketplace is way too ambitious for a new platform, build the core concept first, then iterate  &lt;/li&gt;
  &lt;li&gt;
An aura system that helps in both curating content as well as driving away bad actors  &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
The rest of the original goals are still as relevant as before. In hindsight, these are pretty obvious product direction pivots, the result is an MVP that builds on a simple core concept - &lt;strong&gt;to turn long form text content into audio&lt;/strong&gt;. And to make it easy to organically grow the platform and audience.&lt;/p&gt;
&lt;h2&gt;
Build a Sustainable Business&lt;/h2&gt;
&lt;p&gt;
With the chicken-and-egg problem behind me, it’s time for me to think about how to build a sustainable business to support my product ambition.&lt;/p&gt;
&lt;p&gt;
Interestingly, in Feb/March 2023, I was thinking about what the VC funding model did to the social media platforms we all love and hate, and why it’s a bad idea. The fact that then &lt;em&gt;during&lt;/em&gt; the short few months of developing Persumi, both Twitter and Reddit seemed to be actively imploding themselves just proved my initial hypothesis:&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;To build a truly user-oriented platform, it needs to be built for users and content creators, rather than investors and advertisers&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;
That means, no obnoxious ads, no annoying pop ups, every visitor can view content without being forced to sign in, etc, etc… We do what VC-backed companies don’t.&lt;/p&gt;
&lt;p&gt;
If you’ve seen the &lt;a href=&quot;/&quot;&gt;landing page&lt;/a&gt; then you probably would have noticed a few things either available now or later to help create more value for users, such as:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
The hero feature - AI audio, will be a paid feature, however, every user will be able to listen to audio posts, as well as to preview their own content with audio  &lt;/li&gt;
  &lt;li&gt;
Advanced expressions such as HTML and CSS for those who want to customise their pages to their own style  &lt;/li&gt;
  &lt;li&gt;
Ad-revenue share and paid subscribers - coming later, to make Persumi a platform that shares its success with content creators  &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Keep on Building&lt;/h2&gt;
&lt;p&gt;
The MVP was essentially built in three months in my spare time. It wasn’t easy juggling between having a day job as a CTO, and moonlighting on my side hustle every evening and weekend.&lt;/p&gt;
&lt;p&gt;
This is just the beginning. I have many things planned for Persumi, some of which are already mentioned on the landing page, but there are much more to come. Early alpha and beta users are also able to help shape what this platform can become.&lt;/p&gt;
&lt;p&gt;
In the next week or two I will write about &lt;em&gt;how&lt;/em&gt; I managed to build Persumi in three months - the tech choices, architecture and feature prioritisation I went through to make this product a reality.&lt;/p&gt;
&lt;p&gt;
Like what you’ve read or listened to? Why not &lt;a href=&quot;/auth/register&quot;&gt;sign up&lt;/a&gt; and try the platform yourself, the Pro plan is free during the alpha and beta testing stages. Also check out Persumi’s founder &lt;a href=&quot;/u/fredwu&quot;&gt;@fredwu’s profile here&lt;/a&gt; to see what personas and expressions look like and can achieve.&lt;/p&gt;
&lt;p&gt;
Update: Read about &lt;a href=&quot;how-i-built-a-mostly-feature-complete-mvp-in-3-months-whilst-working-full-time&quot;&gt;How I Built a Mostly Feature-Complete MVP in 3 Months Whilst Working Full-Time&lt;/a&gt;, it covers the features, the tech stack, the global infrastructure and the machine learning…&lt;/p&gt;
]]&gt;</content>
    <published>2023-07-17T04:18:07.386547Z</published>
    <category label="persumi" term="persumi"/>
    <category label="Persumi" scheme="http://persumi.com/c/persumi" term="persumi"/>
    <link href="http://persumi.com/c/persumi/u/fredwu/p/welcome-to-persumi-a-modern-platform-for-content-creation"/>
    <author>
      <name>Fred Wu</name>
      <email>ifredwu@gmail.com</email>
      <uri>http://persumi.com/u/fredwu</uri>
    </author>
    <id>http://persumi.com/c/persumi/u/fredwu/p/welcome-to-persumi-a-modern-platform-for-content-creation</id>
    <title>Welcome to Persumi - A Modern Platform for Content Creation</title>
    <updated>2023-07-17T04:18:07.386547Z</updated>
  </entry>
  <entry>
    <content type="html">&lt;![CDATA[&lt;p&gt;
A few weeks ago I &lt;a href=&quot;welcome-to-persumi-a-modern-platform-for-content-creation&quot;&gt;soft launched&lt;/a&gt; an MVP - you are looking at it right now.&lt;/p&gt;
&lt;p&gt;
In this post I’ll talk about the features, the tech stack and the globally distributed infrastructure behind building this MVP, and of course, with a sprinkle of learnings too.&lt;/p&gt;
&lt;h2&gt;
The “MVP”&lt;/h2&gt;
&lt;p&gt;
Deciding what makes up an “MVP” is always interesting - I’ve heard some saying if the product &lt;em&gt;isn’t&lt;/em&gt; embarrassing you’re releasing it too late, and also if the product &lt;em&gt;is&lt;/em&gt; embarrassing, you’re not gonna make it.&lt;/p&gt;
&lt;p&gt;
For me, I’ve always had the idea of building all the essential features as part of the MVP, with one or two “hero” features that would differentiate the product from the competitions, and then build out more premium features over time.&lt;/p&gt;
&lt;p&gt;
If you can’t already tell, Persumi is a content creation platform with some social networking features. It may sound bland, but what I believe makes it stand out, is the desire of putting the focus back onto the content, rather than the VC-fuelled, ever increasing appetite for more ads and user hostile features.&lt;/p&gt;
&lt;h2&gt;
The Long Nights and Weekends&lt;/h2&gt;
&lt;p&gt;
There is no magic beans for productivity - especially when I have a full time job. Working on a side hustle means giving up on almost all social and entertainment activities. It’s not for everyone, but I didn’t mind it too much. Being an introvert definitely helped - I was happy to see night by night the MVP gradually taking shape to become more and more real.&lt;/p&gt;
&lt;p&gt;
Looking back, I spent about three months to build out most of the MVP, then another week or two on infrastructure, and another week or two for polishing, all whilst having a full time job.&lt;/p&gt;
&lt;p&gt;
It’s been a journey, I’m glad that it “only” took me 3-4 months to get to this stage, as initially I estimated for a 6+ months MVP build.&lt;/p&gt;
&lt;h2&gt;
The Features&lt;/h2&gt;
&lt;p&gt;
With all that in mind, I’ve set out to build the essential features that make a blogging and social networking platform:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
Short form content like a tweet  &lt;/li&gt;
  &lt;li&gt;
Long form content like a blog post or a book chapter  &lt;/li&gt;
  &lt;li&gt;
RSS feeds  &lt;/li&gt;
  &lt;li&gt;
Communities similar to forums and sub-reddits  &lt;/li&gt;
  &lt;li&gt;
Direct messaging between users  &lt;/li&gt;
  &lt;li&gt;
A voting (like/dislike) system  &lt;/li&gt;
  &lt;li&gt;
A bunch of CRUD glue pieces to make all these things work  &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
The “Hero” Features&lt;/h3&gt;
&lt;p&gt;
Beyond these seemly unremarkable features, I’ve also had in mind two key features that would differentiate the platform from the rest:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
The “persona” concept, whereby each user is allowed to have multiple personas to hold different content or topics of interest, e.g. a persona for professional stuff, a persona for gaming stuff and a persona for travel stuff, etc  &lt;/li&gt;
  &lt;li&gt;
AI generated audio content for text (also known as Text-to-Speech)  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
These two “hero” features are what drove me to build Persumi in the first place. Together, they solve some very real pain points for me, namely:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
Following specific topics of interest from people is difficult, with the algorithms taking over people’s home feeds, there are simply way too much noise, thanks to VC-fuelled “user engagement” metrics  &lt;/li&gt;
  &lt;li&gt;
Content consumption on the go (e.g. during commute or during workouts, etc) is becoming more and more prevalent, but the traditional platforms haven’t adopted to this new lifestyle other than shoving short form content down our throats  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
There’s also a third “hero” feature: the Aura system. Unlike the upvote/downvote or like/dislike buttons in many social platforms that only serve the algorithm to push more content to you, Persumi’s Aura system keeps track of user’s content quality over time, and would punish the low quality content and promote high quality content using visual cues - lower quality content has a much lower contrast making them easy to ignore. In the age of social media, self-curating content becomes essential to keep a platform healthy, engaging and usable.&lt;/p&gt;
&lt;h3&gt;
The Non-MVP Features, a.k.a. The Future&lt;/h3&gt;
&lt;p&gt;
There are many features that didn’t make the MVP cut, most of these are value-added features that will eventually make their way into paid subscriptions - if Persumi gains enough traction to attract users who don’t mind paying for premium features.&lt;/p&gt;
&lt;p&gt;
A prime example of such paid features is ones that help users monetise their content, e.g. ad revenue sharing and paid subscribers (like Patreon).&lt;/p&gt;
&lt;p&gt;
I also have the ambition of building out Persumi’s features so it can eventually compete against the likes of LinkedIn and Tinder.&lt;/p&gt;
&lt;p&gt;
Wouldn’t it be better for the world to have a platform like Persumi that doesn’t focus on dark patterns and exploiting users? 😉&lt;/p&gt;
&lt;h2&gt;
The Tech Stack&lt;/h2&gt;
&lt;p&gt;
Over the past decade or so I’ve mainly worked with two tech stacks: Ruby and Elixir. So naturally, Persumi was going to be built using one of them.&lt;/p&gt;
&lt;p&gt;
After some consideration, I’ve decided to go ahead with Elixir, the main reasons were:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
Elixir and Erlang/OTP support distributed systems out of box  &lt;/li&gt;
  &lt;li&gt;
I’ve been writing more Elixir than Ruby lately, so I’m more productive in Elixir  &lt;/li&gt;
  &lt;li&gt;
I really wanted to try and use &lt;a href=&quot;https://github.com/phoenixframework/phoenix_live_view&quot;&gt;LiveView&lt;/a&gt; in production  &lt;/li&gt;
  &lt;li&gt;
I prefer Phoenix’s application architecture more than Rails’  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
On top of Elixir, I’ve decided early on a few other things to go with it:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
Tailwind for CSS  &lt;/li&gt;
  &lt;li&gt;
Postgres for database, preferably a serverless option  &lt;/li&gt;
  &lt;li&gt;
A search engine  &lt;/li&gt;
  &lt;li&gt;
An easy to maintain infrastructure that doesn’t cost an arm and a leg  &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
Elixir&lt;/h3&gt;
&lt;p&gt;
I first discovered Elixir in 2014 while I was still actively involved in the Ruby and Rails communities, but it was two years later that I had the opportunity to really dive into it. I built a few open source libraries to help me learn Elixir and OTP:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
&lt;a href=&quot;https://github.com/fredwu/crawler&quot;&gt;Crawler&lt;/a&gt; - a high performance web scraper.  &lt;/li&gt;
  &lt;li&gt;
&lt;a href=&quot;https://github.com/fredwu/opq&quot;&gt;OPQ: One Pooled Queue&lt;/a&gt; - a simple, in-memory FIFO queue with back-pressure support, built for Crawler.  &lt;/li&gt;
  &lt;li&gt;
&lt;a href=&quot;https://github.com/fredwu/simple_bayes&quot;&gt;Simple Bayes&lt;/a&gt; - a Naive Bayes machine learning implementation. Hey, I was doing machine learning before it was mainstream! 😆  &lt;/li&gt;
  &lt;li&gt;
&lt;a href=&quot;https://github.com/fredwu/stemmer&quot;&gt;Stemmer&lt;/a&gt; - an English (Porter2) stemming implementation, built for Simple Bayes.  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
With a decent amount of experience building Phoenix web apps over the years, I unfortunately never had the opportunity to use LiveView…&lt;/p&gt;
&lt;p&gt;
I guess that’s finally changed now.&lt;/p&gt;
&lt;p&gt;
LiveView has been amazing, not only does it drastically reduce the amount of front-end code you have to write, make the entire web app feel super snappy, but it also virtually eliminates any front-end and back-end code/logic duplications. It is such an awesome piece of technology that improves both the user experience and the developer experience.&lt;/p&gt;
&lt;h4&gt;
Petal Pro&lt;/h4&gt;
&lt;p&gt;
During my initial tech research, I came across &lt;a href=&quot;https://petal.build/&quot;&gt;Petal Pro&lt;/a&gt; which is a boilerplate starter template built on top of Phoenix. It handles things like user authentication which almost every web app needs, but is somewhat tedious to build.&lt;/p&gt;
&lt;p&gt;
Petal Pro isn’t free but it ended up saving me so much time. I also started contributing small bug fixes and features to it too. If you are about to build something in Phoenix, check it out!&lt;/p&gt;
&lt;h3&gt;
Tailwind CSS&lt;/h3&gt;
&lt;p&gt;
As I kept progressing my career, there have been fewer and fewer opportunities for me to write front-end and CSS code. Last time I rebuilt my blog, I used &lt;a href=&quot;https://bulma.io/&quot;&gt;Bulma&lt;/a&gt; - that was 2019. Since then Tailwind has gained a lot more traction, so I wanted an excuse to try finally give it a shot.&lt;/p&gt;
&lt;p&gt;
There is a debate on how many new things you should try for building your MVP - the more you have to learn, the slower your MVP progresses. That said, given CSS is reasonably straightforward, I figured it wouldn’t slow me down too much, if anything, Tailwind’s flexibility might just eventually make up any time lost in learning.&lt;/p&gt;
&lt;p&gt;
I’m happy to report that it is indeed true - by using Tailwind, it became significantly easier for me to customise my components and elements. I can see why it became so popular. It’s not for everyone, but I like it.&lt;/p&gt;
&lt;h3&gt;
Postgres&lt;/h3&gt;
&lt;p&gt;
Choosing Postgres as a database was a no brainer, given how popular and versatile it is. I did briefly consider NoSQL options like DynamoDB but quickly wrote them off as I needed an RDBMS to get things off the ground quickly, and the DB is unlikely to be the bottleneck for a long time anyway.&lt;/p&gt;
&lt;p&gt;
In Elixir, the &lt;a href=&quot;https://hexdocs.pm/ecto/Ecto.html&quot;&gt;Ecto library&lt;/a&gt; works wonders for Postgres.&lt;/p&gt;
&lt;p&gt;
Later in the post I’ll touch on how I deploy and run Postgres in production.&lt;/p&gt;
&lt;h3&gt;
Search Engine&lt;/h3&gt;
&lt;p&gt;
For a search engine, my requirements were:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
The ability to search across multiple fields of a schema  &lt;/li&gt;
  &lt;li&gt;
The ability to rank them  &lt;/li&gt;
  &lt;li&gt;
The ability to have typo tolerance, word stemming and other similar language features to make search more intuitive  &lt;/li&gt;
  &lt;li&gt;
The ability to search multiple languages, including CJK (Chinese/Japanese/Korean) characters  &lt;/li&gt;
  &lt;li&gt;
Simple to run  &lt;/li&gt;
  &lt;li&gt;
Cheap to run  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Using Postgres’ full text search was probably going to be the simplest but it doesn’t offer all the functionalities I need without a bunch of set up and manual SQL queries so I didn’t pursue it.&lt;/p&gt;
&lt;p&gt;
Elasticsearch on the other hand, offers good search functionalities but takes a bit of effort to set up and maintain, and can be costly to run.&lt;/p&gt;
&lt;p&gt;
After doing some more research, I found the following three options that would fit my needs:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
&lt;a href=&quot;https://www.algolia.com/&quot;&gt;Algolia&lt;/a&gt;  &lt;/li&gt;
  &lt;li&gt;
&lt;a href=&quot;https://www.meilisearch.com/&quot;&gt;Meilisearch&lt;/a&gt;  &lt;/li&gt;
  &lt;li&gt;
&lt;a href=&quot;https://typesense.org/&quot;&gt;Typesense&lt;/a&gt;  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Both Meilisearch and Typesense are open source, with commercial SaaS offerings, whilst Algolia is SaaS-only.&lt;/p&gt;
&lt;p&gt;
It’s been an interesting journey. I started with Typesense as I liked what I read, but I quickly discovered that it doesn’t search Chinese characters properly.&lt;/p&gt;
&lt;p&gt;
I then turned to Meilisearch. I especially liked the fact that they offered a generous free tier SaaS to get you off the ground running. Spoiler: during my implementation they did a bait and switch and removed the free tier.&lt;/p&gt;
&lt;p&gt;
At the time the Elixir support for Meilisearch wasn’t up to date, so I ended up &lt;a href=&quot;https://github.com/nutshell-lab/meilisearch-ex/pull/5&quot;&gt;contributing to a community library&lt;/a&gt; to add the features I needed.&lt;/p&gt;
&lt;p&gt;
Curious timing, after Meilisearch removed their free tier, I discovered that even though they officially support searching for Chinese characters, the implementation wasn’t perfect. I found some edge cases where characters weren’t detected properly, making the search results unreliable.&lt;/p&gt;
&lt;p&gt;
So, my last hope was Algolia. Despite them being the more expensive option out of the three, it does offer a free tier. It turns out, their search results for Chinese characters were much better than Meilisearch’s. Luckily, re-implementing the search from Meilisearch to Algolia didn’t take too much effort, it was pretty much done in one night.&lt;/p&gt;
&lt;h3&gt;
Infrastructure&lt;/h3&gt;
&lt;p&gt;
Early on during the development I’d already determined I wanted to try &lt;a href=&quot;https://fly.io/&quot;&gt;Fly&lt;/a&gt; and &lt;a href=&quot;https://neon.tech/&quot;&gt;Neon&lt;/a&gt;, for web and DB, respectively.&lt;/p&gt;
&lt;p&gt;
I am in no way associated with either company, I was curious about Fly due to its tie-in with the Elixir community (Phoenix Framework’s author Chris McCord works there), and Neon due to its serverless nature.&lt;/p&gt;
&lt;h4&gt;
Globally Distributed Infra&lt;/h4&gt;
&lt;p&gt;
With Fly, the infrastructure automatically becomes globally distributed as soon as I started provisioning servers in more than one region. As of the time of writing, Persumi is deployed to US West, Australia and EU.&lt;/p&gt;
&lt;p&gt;
Despite being simple to use, making Fly work initially actually took quite a bit of finessing due to its incomplete official documentation and flakiness. Some of the services were having issues during the course of my MVP development. Worse, they don’t report (or sometimes even acknowledge) the issues unless they are region-wide outages. To this date, I believe their blue/green deployment strategy which was recently introduced, is still buggy, I often have to use their rolling deployment strategy instead. Deployment logs were provided to Fly but I think they’re too busy with other things…&lt;/p&gt;
&lt;p&gt;
Still, I’m sticking with them for now due to the ease of use after the initial hurdle, and their globally distributed infrastructure without asking for my kidney.&lt;/p&gt;
&lt;p&gt;
To augment Fly’s web servers, I also use Cloudflare’s &lt;a href=&quot;https://www.cloudflare.com/application-services/products/cdn/&quot;&gt;CDN&lt;/a&gt; as well as &lt;a href=&quot;https://www.cloudflare.com/developer-platform/r2/&quot;&gt;R2&lt;/a&gt; to serve asset files and audio files.&lt;/p&gt;
&lt;p&gt;
Funny tangent, initially I used &lt;a href=&quot;https://bunny.net/&quot;&gt;Bunny&lt;/a&gt; for asset files and CDN, as I misread Cloudflare’s terms and thought I couldn’t serve audio files from Cloudflare. Bunny worked okay but their dashboard for some reason was painfully slow - not a good look for a CDN company. Like the search engine switch, it didn’t take me too long to switch over to Cloudflare.&lt;/p&gt;
&lt;h4&gt;
Serverless Postgres&lt;/h4&gt;
&lt;p&gt;
There are a few options to run Postgres:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;
Run on a standard server for maximum portability, but it requires more server maintenance overhead  &lt;/li&gt;
  &lt;li&gt;
Run on AWS RDS/Aurora or a similar managed service, easy but can be costly  &lt;/li&gt;
  &lt;li&gt;
Run on a serverless option such as Aurora Serverless or Neon  &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
For my use case, I think option 2 or 3 are better fitting. As I mentioned earlier, I started the experiment with &lt;a href=&quot;https://neon.tech/&quot;&gt;Neon&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
Neon worked well initially, until I started deploying Fly instances in multiple regions. Due to Neon being only available in one region (I chose US West), and I live in Australia, the round trips between Fly’s Australian instance and Neon’s US instance were a show stopper - especially when complex DB transactions were involved. Actions sometimes took &lt;em&gt;seconds&lt;/em&gt; to complete, yikes.&lt;/p&gt;
&lt;p&gt;
Despite Fly not offering a managed Postgres service, I ended up trying it anyway due to its &lt;a href=&quot;https://fly.io/docs/postgres/advanced-guides/high-availability-and-global-replication/&quot;&gt;distributed nature&lt;/a&gt;. After incorporating &lt;a href=&quot;https://github.com/superfly/fly_postgres_elixir&quot;&gt;Fly Postgres&lt;/a&gt; in the app, all DB operations immediately became more responsive. Paired with LiveView, it feels like running the application locally.&lt;/p&gt;
&lt;p&gt;
The current Persumi infra looks like:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
1 x Fly instance in US West, always on  &lt;/li&gt;
  &lt;li&gt;
1 x Fly instance in Australia, auto-shutdown when there’s no traffic  &lt;/li&gt;
  &lt;li&gt;
1 x Fly instance in Netherlands, auto-shutdown when there’s no traffic  &lt;/li&gt;
  &lt;li&gt;
1 x Fly Postgres writer instance in US West, always on  &lt;/li&gt;
  &lt;li&gt;
1 x Fly Postgres read replica instance in Australia, always on  &lt;/li&gt;
  &lt;li&gt;
1 x Fly Postgres read replica instance in Netherlands, always on  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
With this setup, I think I’m quite happy with the cost and scalability balance - it costs ~$20/m to run, with the potential of both vertical and horizontal scaling with ease.&lt;/p&gt;
&lt;h2&gt;
The Missteps&lt;/h2&gt;
&lt;p&gt;
The search engine and CDN swaps mentioned earlier certainly took away some of my time, but they were nothing compared to a major misstep I encountered.&lt;/p&gt;
&lt;p&gt;
And that was:  the choice of how machine learning is done.&lt;/p&gt;
&lt;p&gt;
Let me explain.&lt;/p&gt;
&lt;h3&gt;
Machine Learning, and Inference&lt;/h3&gt;
&lt;p&gt;
Even before I started the first line of code, I already painted a picture in my head on the machine learning needed: a TTS (text-to-speech) model that I could run inference locally on the instance.&lt;/p&gt;
&lt;p&gt;
The reason being I believed it was the more flexible approach to gradually improve the inference  and therefore the end result by training my own AI models over time.&lt;/p&gt;
&lt;p&gt;
Given I didn’t want to rent expensive GPU instances, I opted for fast TTS models that could do near real-time inference on CPUs. I used &lt;a href=&quot;https://github.com/coqui-ai/TTS&quot;&gt;Coqui TTS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
The resulting out-of-box audio wasn’t great, but I kept pressing on.&lt;/p&gt;
&lt;p&gt;
The show stopper came when it was time to deploy everything onto Fly. Due to Fly’s architecture (they deploy small-ish Docker images, &lt; 2GB each, onto their global network), I struggled to keep the Docker image file small enough to be able to deploy. With Coqui TTS, I would need Python and all the dependencies that resulted in a Docker image around 4-5GB in size.&lt;/p&gt;
&lt;p&gt;
With my tunnel vision, I then chose to offload the entire Python and Coqui TTS dependency tree onto Fly’s &lt;a href=&quot;https://fly.io/docs/reference/volumes/&quot;&gt;persistent volumes&lt;/a&gt;. I knew it wasn’t a great option, as that meant my infrastructure (other than the database) was no longer immutable.&lt;/p&gt;
&lt;p&gt;
Sometimes it’s necessary to take a step back, re-evaluate, and then press on in a different direction. Which thankfully I did.&lt;/p&gt;
&lt;p&gt;
The new direction is quite simple really: instead of performing inference locally, use an external service instead.&lt;/p&gt;
&lt;p&gt;
After doing a quick comparison between the offerings from AWS, Azure and GCP, I ended up using &lt;a href=&quot;https://cloud.google.com/text-to-speech&quot;&gt;Google’s TTS&lt;/a&gt;. Honestly I think I would’ve been happy with any of the options, they all seem to have decent neural based TTS.&lt;/p&gt;
&lt;p&gt;
In hindsight, these giant corporations have much more resources and expertise to train better models than I ever could on my own.&lt;/p&gt;
&lt;p&gt;
The end result:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
The TTS sounds significantly better than before  &lt;/li&gt;
  &lt;li&gt;
It’s just as cheap to run (Google offers a certain amount of free TTS API calls per month)  &lt;/li&gt;
  &lt;li&gt;
It no longer needs complex Python calls and FFmpeg calls to make local TTS work  &lt;/li&gt;
  &lt;li&gt;
The Fly infrastructure is simple and immutable again  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
In hindsight, I never should’ve even entertained the idea of running ML locally on CPUs, no matter how simple and efficient a model might be.&lt;/p&gt;
&lt;p&gt;
That said, with TTS, it wasn’t as simple as just calling the APIs and getting the perfect resulting audio back. Some pre and post processing were needed, but that’s a topic for another time.&lt;/p&gt;
&lt;h3&gt;
More Machine Learning&lt;/h3&gt;
&lt;p&gt;
The cherry on top - now that Google’s APIs were integrated into the app, I ended up also using Google’s &lt;a href=&quot;https://ai.google/discover/palm2/&quot;&gt;PaLM 2&lt;/a&gt; to do text summarisation (it was initially done locally too) as well as for a ChatGPT-like AI prompt service, to power Persumi’s AI writing assistance feature.&lt;/p&gt;
&lt;h2&gt;
The Closing&lt;/h2&gt;
&lt;p&gt;
If you read this far, thank you! I hope you enjoyed reading (or listening) to this post. Please look around and kick tyres, I would love your feedback on how to improve Persumi.&lt;/p&gt;
&lt;p&gt;
Sign up for an account if you haven’t already, and leave a comment if you have any questions. Until next time!&lt;/p&gt;
]]&gt;</content>
    <published>2023-08-09T09:28:12.135201Z</published>
    <category label="persumi" term="persumi"/>
    <category label="Persumi" scheme="http://persumi.com/c/persumi" term="persumi"/>
    <link href="http://persumi.com/c/persumi/u/fredwu/p/how-i-built-a-mostly-feature-complete-mvp-in-3-months-whilst-working-full-time"/>
    <author>
      <name>Fred Wu</name>
      <email>ifredwu@gmail.com</email>
      <uri>http://persumi.com/u/fredwu</uri>
    </author>
    <id>http://persumi.com/c/persumi/u/fredwu/p/how-i-built-a-mostly-feature-complete-mvp-in-3-months-whilst-working-full-time</id>
    <title>How I Built a Mostly Feature-Complete MVP in 3 Months Whilst Working Full-Time</title>
    <updated>2023-08-09T09:28:12.135201Z</updated>
  </entry>
</feed>