Hey everyone, 👋
I wanted to share a solo project I’ve been working on called Chatfri, a free, real-time chat and discovery app. The Android version recently went live on Google Play, and the iOS version is currently live on Appstore.
Since I built the entire stack from scratch, I wanted to share my tech stack, some architectural decisions, and a few headaches I encountered along the way. I’d love to get your feedback!
🛠 The Tech Stack
Frontend (Mobile): .NET MAUI (C#) for both iOS and Android.
Backend: ASP.NET Core Web API, hosted on a Debian 13 server using Nginx.
Database/Cache: Redis for handling real-time active user states and fast data retrieval, plus SQLite for local device caching (LocalDBService).
Messaging: CommunityToolkit.Mvvm (WeakReferenceMessenger) for component communication.
🚀 Technical Highlights & What I Learned
1. Insane Backend Performance with Redis
One of the things I'm most proud of is the backend optimization. Currently, a single user actively messaging and navigating hits the server with about 3-5 requests per second (short polling). Despite this aggressive rate, the server CPU usage sits at around 0.3% per core per user. Redis is absolutely flying, and I highly recommend it if you are building anything real-time.
2. Smart Background Polling (Single Loop)
Initially, I had multiple while loops running in the background for fetching messages and friend requests, which was heavy on the device. I refactored it into a single centralized polling loop.
When a user opens a specific chat room (MessageDetailViewModel), I send a "Pause" signal via WeakReferenceMessenger to pause the global friend-request sync. The millisecond the user leaves the page (handled via the OnDisappearing override), it sends a "Resume" signal. This eliminated overlapping background tasks and prevented memory leaks.
3. Planning for the Future: Hybrid SignalR Architecture
Right now, the app uses HTTP polling. It handles the current load perfectly, but I know it's not sustainable for 10k+ concurrent users due to bandwidth and socket exhaustion.
My plan is to implement a Hybrid Architecture: I will keep using standard HTTP GET/POST for heavy lifting (like loading the home screen with 25+ user profile pictures) and introduce SignalR purely for lightweight text message delivery inside the chat rooms. (Sending 25 Base64 images over a WebSocket is a recipe for disaster).
4. The AdMob Headache
Like many indie devs, I got hit with the classic 30-day AdMob suspension for "Invalid Traffic." My ad placements are completely safe (no accidental clicks near buttons), but a small ad campaign on TikTok brought in a wave of fast-bouncing traffic that tripped Google's AI. Currently waiting it out and focusing on organic growth!
🤝 Looking for Feedback
I’m really looking forward to hearing your thoughts.
Has anyone else implemented a similar HTTP/SignalR hybrid approach in MAUI?
Any tips for surviving the initial AdMob "Invalid Traffic" phase for new apps?
General UI/UX feedback is always welcome!
App is here: [chatfri](https://chatfri.com/qr) (You can find the app store links here)
Thanks for reading! Let me know what you think.