Audioscrape: Building in Rust When Everyone Said I Shouldn't
Why Rust for a Bootstrapped MVP?
Cost-Efficiency: Minimal resource usage translates to lower hosting costs, crucial for bootstrapping.
Performance: Efficient handling of audio processing and web serving, allowing for growth without immediate infrastructure scaling.
Learning Investment: Deepening expertise in a language with growing demand, potentially opening future opportunities.
Proving a Point: Demonstrating Rust's viability for rapid development in web applications.
Project Overview:
Audioscrape aggregates podcast RSS feeds, transcribes episodes, and provides an interactive interface for exploring and discussing podcast content. It's a full-stack Rust application, leveraging various crates from the ecosystem.
Technical Stack:
Backend: Axum (async web framework)
Database: SQLite with SQLx for type-safe queries
Authentication: OAuth2
Image Processing: For social media previews
HTML Templating: Askama
Async Runtime: Tokio
Development Approach:
4k LoC in a single main.rs file (plus HTML templates)
Rapid iteration using Neovim for navigation
Lean development: No external services beyond the VM
Key Features:
Transcription Browsing: Read along with your favorite podcasts or quickly scan for topics of interest.
Segment Highlighting: Share and discuss specific moments from episodes.
Community Interaction: Upvote, comment on, and bookmark your favorite segments.
Advanced Search: Find relevant content across multiple podcasts and episodes.
Person Profiles: Explore appearances of specific guests or hosts across different shows.
Challenges and Learnings:
Overcoming the learning curve of Rust's ownership model
Efficient transcriptions and speaker detection
Managing all aspects solo: Development, design, and operations
Future Plans:
API for third-party integrations
WebAssembly for client-side processing
Scaling strategies for larger datasets (search)
Personalized content delivery
Metrics and Goals:
Current Users: 500 (last 7 days)
MRR: $0
Cost per User: Less than $0.01 (thanks to efficient resource use)
Next Milestone: Add paid features to pay the bills + reduce cost per episode page creation
Questions for the HN Community:
Has anyone else bootstrapped using Rust? What were your experiences?
How do you balance technical debt vs. shipping features in a solo project?
What strategies have worked for you in marketing such technical products?
I'm bootstrapping this project and would greatly appreciate any feedback, especially from those who've launched similar technical products or used unconventional tech stacks for MVPs. Check out Audioscrape at www.audioscrape.com and let me know your thoughts!
46 comments
[ 2.1 ms ] story [ 106 ms ] threadIf it's just you, then that reason alone justifies it.
Personally I wouldn't do it either.
Folders often just add an extra layer to search through. It's basically a search param. With Neovim and strict naming conventions, I've found managing everything in one file works quite well. Keyboard navigation can make folders feel like a hassle in the vi context. This setup has been effective so far, though potential downsides might appear later on.
No comment on your one-file approach one way or the other, but like all of us, you will need to deal with tree-shaped projects, I've found Harpoon to be a good solution for this. Global marks can only get you so far.
Good luck with Audioscape btw.
The LLM pipeline is built into the Rust code and makes calls to the OpenAI API.
I might be ignorance. But is it not safe? How do you back up your data?
As for backups, the setup is straightforward: just periodically copy the SQLite file to a secure location. Since it's a single binary and a database file, this keeps things simple and low-maintenance.
> Has anyone else bootstrapped using Rust? What were your experiences?
We scaled several websites to 6M+ MAUs on Actix/SQLx and ran that on the lowest tier VMs.
Rust is God Mode for efficient and scalable HTTP services. Moreover, the type safety and robust type system give us incredible confidence that our software is defect free.
While we currently have fewer users, I've also found Rust's type safety and robust system invaluable for building reliable software. In my experience, if it compiles, it just works—quite a contrast to dealing with runtime error minefields in Python, Java, or TypeScript.
I've put off learning rust for so long. I really tried to get into it once, and ended up learning clojure instead lol. Rust just had too many concepts at once for me to learn, probably because I've only ever used garbage-collected languages.
But hearing this type of stuff always makes me want to try again
Once you grasp Rust's concepts, you'll find the control and efficiency rewarding. It's worth the effort!
Some people used the share feature of Audioscrape to emphasize their points in discussions on X. For example, 'Here, this is what Zuckerberg said recently about Y <Link to moment>'
Yes, we are building a parsing platform in rust. (~50k loc) Stack: actix + diesel (async) for PG.
Getting the right project structure was not simple (that could deserve a blog post). Performance is super nice if you do heavy IO.
Beware of memory usage handling with actix.
Day to day dev is a joy, once it compile you can be confident it will work as expected.
Never .unwrap / panic !
Use clippy to check your code.
Once you have your project structure done, adding a new web handler is as fast as adding one in Django or Flask.
Similar setups (Rocket and Actix instead of Axum, Tera instead of Askama, Diesel instead of SQLx) and overall experience (incredibly cheap, reliable, and since these projects have been running a long time, amazingly easy to return to the codebases after months/years and make changes with a high level of confidence).
I distinctly remember how happy I felt the first time I realized that I had enough paying subscribers to offset the cost of the running the service!
[1]: https://notado.app
[2]: it had a decent amount of HN discussion last week - https://news.ycombinator.com/item?id=41697228
[3]: https://kulli.sh
I started with Rocket for Notado, but because there was a long period of pre v0.5 stagnation, I went with Actix for Kullish. These days I'd be happy starting a new project with either.
As for Tera over Askama, I don't think Askama was around when I started building Notado; Tera was the first templating engine I used in Rust and I learned its ins and outs pretty well, so now it's just the default thing that I reach for whenever I'm building a web app.
Just fyi I tried to add Criminal[1] and it seems like it was...partially successful[2]? The "Enter RSS URL" page loaded for a while and then stopped.
[1] https://thisiscriminal.com/episodes
[2] https://www.audioscrape.com/podcast/criminal
We hit the front page on Hacker News and received many submissions, which led to network errors when fetching some podcasts. I've just added retry logic and scheduling for new podcast fetches and pushed these changes to production.
The Criminal[1] podcast is now added. Due to the current demand, our transcription queue is a bit backed up, so transcription for this podcast will appear in a few days. Please be invited to have a look the next days again.
I'm actively working on securing more GPUs to help scale this process efficiently so in the future you don't have to wait that long.
Would it be interesting if I add e-mail "transcription ready" notifications for those who submit a new podcast?
[1] https://www.audioscrape.com/podcast/criminal
I think a notification feature makes a lot of sense, but it depends on how long the wait tends to be. In terms of setting expectations it might be better to display the current backlog and an estimate about when the transcription might be done (though of course both would be even better than either).
How would you expect to get an understanding of the backlog? Would a dedicated page for the entire backlog be helpful, or would you prefer to see which episodes are being transcribed on each podcast page?
Any insights on what would be most helpful for you would be greatly appreciated!
Having a big central page for all backlogs sounds cool, but I imagine I would probably care about the expected delay for a particular podcast / episode of a podcast most of the time?
Perhaps on the submission form include a low-resolution indication of that, so people's expectations are set before they enter a podcast link? Round it off to the nearest minute/hour/day, and format it appropriately:
"Processing times are currently around 3 hours"
or
"Processing times are currently around 17 minutes"
Besides the memory safety, type system etc, Rust gives you the confidence that you know it can scale in pretty much all scenarios in terms of performance.
What led you to choose Leptos for the frontend besides the shared code advantage?
There is also Rustler which helps facilitate calling Rust binaries from Elixir directly but I opted to deploy them separately.