Building a platform like SAS is easy when you have ten posts. It gets hard when you have ten thousand. Today, I dove deep into the guts of our discovery engine to solve a
problem every social dev faces: How do you keep the feed fresh without burying quality content?
The Error: The "Static" Trap
Initially, SAS was purely chronological. Newest on top. Simple, right? But it created a "Recency Bias" where a great story from yesterday vanished, while a mediocre "Hello
World" from five minutes ago took center stage.
Worse, the UI was breaking under the weight of its own features. When I added the Boosted badge, it sat right on top of the Follow button. On mobile, long usernames were
squishing profile pictures into tiny ovals.
The Fix: Math + Flexbox
We moved from a static order_by('-created_at') to a dynamic Computed Feed Score.
The logic is simple but powerful:
Score = (Likes * 1) + (Comments * 2) + Boost(100) - (HoursOld * 0.5)
* Weighting: Comments are 2x more valuable than likes because they represent active conversation.
* Time Decay: The - (HoursOld * 0.5) is the "gravity" that slowly pulls old posts down, ensuring the feed always feels alive.
On the UI side, I ditched absolute positioning for the badges. By refactoring the header into a nested flex structure with min-w-0 and shrink-0 properties, I guaranteed that
no matter how long a name is or how many badges a post has, the layout remains rock solid.
The Lesson: Protect the State
The biggest challenge wasn't the math—it was the State.
When a user marks notifications as read, or a new message arrives, the global "Bell" badge needs to reflect that instantly across all open tabs. We solved this by injecting
initial unread counts directly into the WebSocket connect handshake.
Pro-tip: Never rely on the frontend to "guess" the count. Always treat the server as the single source of truth, even for the smallest UI badges.
The Way Forward: Automation
We’ve now implemented a custom BaseCommand that runs in the background to recalculate these scores. The next step? Personalization.
Soon, your "Explore" feed won't just be what's trending globally; it’ll be a weighted mix of your favorite tags and the creators you interact with most.
What’s the toughest "simple" UI bug you’ve ever had to refactor? Let’s talk in the comments.
Loading thoughts...