Build an Engagement Decay Analyzer: How Fast Do Posts Die?
You post a TikTok. It gets 10K views in the first hour. You celebrate.
24 hours later: 12K views. 48 hours: 12.1K. It’s dead.
Meanwhile, your competitor posted at the same time. First hour: 8K views. Seems worse. But 48 hours later: 45K. A week later: 200K. Their content has legs. Yours doesn’t.
The difference isn’t luck. It’s engagement decay rate — and almost nobody tracks it.
I built a tool that measures exactly how fast posts lose momentum and which content types have the longest shelf life. Here’s the whole thing.
The Stack
- Node.js – runtime
- SociaVault API – fetch post data over time
- Math – decay curve fitting
Why Decay Rate Matters More Than Total Engagement
Two posts, same creator, same niche:
| Metric | Post A | Post B |
|---|---|---|
| Views at 1 hour | 10,000 | 5,000 |
| Views at 24 hours | 12,000 | 20,000 |
| Views at 7 days | 13,000 | 80,000 |
| Decay rate | Fast (dies in hours) | Slow (grows for days) |
Post B wins by 6x despite starting slower. If you only measured “first hour performance,” you’d double down on Post A’s style. That’s the trap.
Slow-decay content gets picked up by the algorithm, appears in search results, and compounds. Fast-decay content spikes and vanishes.
Step 1: Collect Time-Series Data
You need engagement snapshots at multiple time points. Fetch the same post’s data repeatedly.
const axios = require('axios');
const API_BASE = 'https://api.sociavault.com/v1';
const API_KEY = process.env.SOCIAVAULT_API_KEY;
const api = axios.create({
baseURL: API_BASE,
headers: { 'x-api-key': API_KEY },
});
async function getPostInfo(platform, postId) {
const { data } = await api.get(`/${platform}/post/${postId}`);
return data;
}
async function getPosts(platform, username, limit = 30) {
const { data } = await api.get(`/${platform}/posts/${username}`, {
params: { limit },
});
return data.posts;
}
For decay analysis, we snapshot posts at known intervals after posting:
async function collectDecayData(platform, postId, postDate) {
const post = await getPostInfo(platform, postId);
const hoursOld = (Date.now() - new Date(postDate).getTime()) / (1000 * 60 * 60);
return {
postId,
hoursOld: Math.round(hoursOld),
views: post.viewCount || 0,
likes: post.likeCount || 0,
comments: post.commentCount || 0,
shares: post.shareCount || 0,
timestamp: new Date().toISOString(),
};
}
Step 2: Calculate Decay Curves
With multiple snapshots (or by comparing posts of different ages), calculate engagement velocity — how much engagement each post gains per hour.
function calculateDecayCurve(snapshots) {
// Sort by hours old
const sorted = snapshots.sort((a, b) => a.hoursOld - b.hoursOld);
const curve = [];
for (let i = 1; i < sorted.length; i++) {
const prev = sorted[i - 1];
const curr = sorted[i];
const hoursDiff = curr.hoursOld - prev.hoursOld;
if (hoursDiff <= 0) continue;
const viewsGained = curr.views - prev.views;
const likesGained = curr.likes - prev.likes;
curve.push({
fromHour: prev.hoursOld,
toHour: curr.hoursOld,
viewsPerHour: Math.round(viewsGained / hoursDiff),
likesPerHour: parseFloat((likesGained / hoursDiff).toFixed(1)),
velocityDrop: prev.hoursOld === 0 ? 0 :
parseFloat(((viewsGained / hoursDiff) / (curve[0]?.viewsPerHour || 1) * 100).toFixed(1)),
});
}
return curve;
}
Step 3: Estimate Decay Without Snapshots
Don’t have historical snapshots? You can estimate decay from a batch of recent posts by comparing age vs. total engagement.
function estimateDecayFromBatch(posts) {
// Group posts by age buckets
const buckets = {
'0-6h': [], '6-24h': [], '1-3d': [], '3-7d': [], '7-14d': [], '14-30d': [],
};
for (const post of posts) {
const hoursOld = (Date.now() - new Date(post.createdAt).getTime()) / (1000 * 60 * 60);
if (hoursOld <= 6) buckets['0-6h'].push(post);
else if (hoursOld <= 24) buckets['6-24h'].push(post);
else if (hoursOld <= 72) buckets['1-3d'].push(post);
else if (hoursOld <= 168) buckets['3-7d'].push(post);
else if (hoursOld <= 336) buckets['7-14d'].push(post);
else buckets['14-30d'].push(post);
}
// Calculate average engagement per hour for each bucket
const rates = {};
for (const [bucket, bucketPosts] of Object.entries(buckets)) {
if (bucketPosts.length === 0) continue;
const avgViews = bucketPosts.reduce((s, p) => s + (p.viewCount || 0), 0) / bucketPosts.length;
const avgHours = bucketPosts.reduce((s, p) => {
return s + (Date.now() - new Date(p.createdAt).getTime()) / (1000 * 60 * 60);
}, 0) / bucketPosts.length;
rates[bucket] = {
avgViewsPerHour: parseFloat((avgViews / avgHours).toFixed(1)),
sampleSize: bucketPosts.length,
};
}
return rates;
}
Step 4: Compute Half-Life
The “half-life” of a post = how many hours until it’s getting 50% of its peak engagement velocity. This is the single best metric for content longevity.
function calculateHalfLife(decayCurve) {
if (decayCurve.length < 2) return null;
const peakVelocity = decayCurve[0].viewsPerHour;
const halfPeak = peakVelocity * 0.5;
// Find when velocity drops below 50% of peak
for (const point of decayCurve) {
if (point.viewsPerHour <= halfPeak) {
return point.fromHour;
}
}
// Still above 50% — long-lived content
return decayCurve[decayCurve.length - 1].toHour;
}
function classifyDecay(halfLifeHours) {
if (halfLifeHours <= 2) return { type: 'Flash', emoji: '⚡', description: 'Dies within hours' };
if (halfLifeHours <= 12) return { type: 'Standard', emoji: '📊', description: 'Normal decay' };
if (halfLifeHours <= 48) return { type: 'Sustained', emoji: '🔥', description: 'Multi-day momentum' };
if (halfLifeHours <= 168) return { type: 'Evergreen', emoji: '🌲', description: 'Week-long legs' };
return { type: 'Viral', emoji: '🚀', description: 'Algorithm-boosted longevity' };
}
Platform benchmarks (approximate):
- TikTok: Average half-life ~4-8 hours. Viral posts: 48-72 hours.
- Instagram Reels: Average ~6-12 hours. Explore-boosted: 24-48 hours.
- Instagram Feed: Average ~2-4 hours. Very fast decay.
- YouTube: Average ~48-168 hours. Evergreen content: months.
- Twitter/X: Average ~0.5-2 hours. Fastest decay of any platform.
Step 5: Analyze Content Types
Which types of content decay slowest? Find the pattern.
function analyzeContentTypes(posts, decayData) {
const categories = {};
for (const post of posts) {
const type = categorizePost(post);
if (!categories[type]) {
categories[type] = { posts: [], halfLives: [] };
}
categories[type].posts.push(post);
if (decayData[post.id]) {
const curve = calculateDecayCurve(decayData[post.id]);
const halfLife = calculateHalfLife(curve);
if (halfLife) categories[type].halfLives.push(halfLife);
}
}
// Summarize each category
const summary = {};
for (const [type, data] of Object.entries(categories)) {
if (data.halfLives.length === 0) continue;
const avgHalfLife = data.halfLives.reduce((a, b) => a + b, 0) / data.halfLives.length;
summary[type] = {
postCount: data.posts.length,
avgHalfLife: parseFloat(avgHalfLife.toFixed(1)),
decay: classifyDecay(avgHalfLife),
avgViews: Math.round(
data.posts.reduce((s, p) => s + (p.viewCount || 0), 0) / data.posts.length
),
};
}
return summary;
}
function categorizePost(post) {
const caption = (post.caption || '').toLowerCase();
const hasQuestion = caption.includes('?');
const hasList = /d.s|•|→/.test(caption);
const isShort = caption.length < 50;
if (post.type === 'carousel' || post.mediaCount > 1) return 'Carousel';
if (post.type === 'reel' || post.duration) return 'Video/Reel';
if (hasQuestion) return 'Question/Poll';
if (hasList) return 'List/Tips';
if (isShort) return 'Short Caption';
return 'Long Caption';
}
Step 6: Compare Creators
async function compareCreatorDecay(platform, usernames) {
const results = [];
for (const username of usernames) {
const posts = await getPosts(platform, username, 30);
const decayRates = estimateDecayFromBatch(posts);
// Estimate overall content longevity
const avgViews = posts.reduce((s, p) => s + (p.viewCount || 0), 0) / posts.length;
const avgAge = posts.reduce((s, p) => {
return s + (Date.now() - new Date(p.createdAt).getTime()) / (1000 * 60 * 60);
}, 0) / posts.length;
results.push({
username,
postCount: posts.length,
avgViews: Math.round(avgViews),
avgPostAgeHours: Math.round(avgAge),
viewsPerHour: parseFloat((avgViews / avgAge).toFixed(1)),
decayRates,
});
}
// Rank by views per hour (proxy for content longevity)
return results.sort((a, b) => b.viewsPerHour - a.viewsPerHour);
}
Putting It All Together
async function runDecayAnalysis(platform, username) {
console.log(`n=== ENGAGEMENT DECAY ANALYSIS: @${username} ===n`);
const posts = await getPosts(platform, username, 50);
const decayRates = estimateDecayFromBatch(posts);
console.log('📉 Engagement Velocity by Post Age:');
for (const [bucket, rate] of Object.entries(decayRates)) {
console.log(` ${bucket}: ${rate.avgViewsPerHour} views/hour (n=${rate.sampleSize})`);
}
// Content type breakdown
console.log('n📊 Content Type Longevity:');
const typeAnalysis = analyzeContentTypes(posts, {});
for (const [type, data] of Object.entries(typeAnalysis)) {
console.log(
` ${data.decay.emoji} ${type}: ~${data.avgHalfLife}h half-life ` +
`(${data.decay.type}) — avg ${data.avgViews.toLocaleString()} views`
);
}
// Recommendations
console.log('n💡 Recommendations:');
const sorted = Object.entries(typeAnalysis).sort((a, b) => b[1].avgHalfLife - a[1].avgHalfLife);
if (sorted.length >= 2) {
console.log(` Best longevity: ${sorted[0][0]} (~${sorted[0][1].avgHalfLife}h half-life)`);
console.log(` Worst longevity: ${sorted[sorted.length - 1][0]} (~${sorted[sorted.length - 1][1].avgHalfLife}h half-life)`);
console.log(` → Post more ${sorted[0][0]} content, less ${sorted[sorted.length - 1][0]}`);
}
}
runDecayAnalysis('tiktok', 'target_creator');
Sample Output
=== ENGAGEMENT DECAY ANALYSIS: @target_creator ===
📉 Engagement Velocity by Post Age:
0-6h: 2,340 views/hour (n=3)
6-24h: 890 views/hour (n=5)
1-3d: 210 views/hour (n=8)
3-7d: 45 views/hour (n=7)
7-14d: 8 views/hour (n=4)
📊 Content Type Longevity:
🔥 Carousel: ~36h half-life (Sustained) — avg 47,200 views
📊 List/Tips: ~14h half-life (Standard) — avg 31,800 views
📊 Video/Reel: ~8h half-life (Standard) — avg 22,100 views
⚡ Short Caption: ~1.5h half-life (Flash) — avg 5,400 views
💡 Recommendations:
Best longevity: Carousel (~36h half-life)
Worst longevity: Short Caption (~1.5h half-life)
→ Post more Carousel content, less Short Caption
Carousels last 24x longer than short-caption posts. That’s not a small difference — it’s the difference between content that compounds and content that disappears.
Read the Full Guide
This is a condensed version. The full guide includes:
- Automated snapshot scheduling for precision decay curves
- Platform-specific decay benchmarks from 10,000+ posts
- Correlation between posting time and decay rate
- Visualization with Charts.js
Read the complete guide on SociaVault →
Building content analytics tools? SociaVault provides social media data APIs for TikTok, Instagram, YouTube, and 10+ platforms. Track posts over time, compare creators, and analyze content performance through one unified API.
Discussion
Do you track how long your content stays alive? Or do you only look at total engagement? Curious what metrics you optimize for 👇
webdev #api #nodejs #analytics #javascript
AI Assistance vs AI Agents: Understanding the Shift from Responses to Autonomous Systems
👋 Hey there, tech enthusiasts!
I’m Sarvar, a Cloud Architect with a passion for transforming complex technological challenges into elegant solutions. With extensive experience spanning Cloud Operations (AWS & Azure), Data Operations, Analytics, DevOps, Generative AI, and Agentic AI, I’ve had the privilege of architecting solutions for global enterprises that drive real business impact. Through this article series, I’m excited to share practical insights, best practices, and hands-on experiences from my journey in the tech world. Whether you’re a seasoned professional or just starting out, I aim to break down complex concepts into digestible pieces that you can apply in your projects.
Let’s dive in and explore the fascinating world of cloud technology together! 🚀
Here’s What Most People Get Wrong
ChatGPT can write your email. But it can’t send it. That’s the difference between an AI assistant and an AI agent, and honestly, most people have no idea there even is a difference.
I’ve been working with AI for a while now, and I keep seeing the same confusion everywhere. People use “AI assistant” and “AI agent” like they’re the same thing. They’re not. Not even close.
Here’s what you need to know: AI assistants tell you what to do. AI agents actually do it for you. That’s the whole game right there.
Let me break this down in a way that actually makes sense.
AI Assistants: The Smart Advisor
Think about the last time you used ChatGPT or asked Siri something. You asked a question, got an answer, and then you had to go do something with that answer. That’s an AI assistant.
An AI assistant is like having a really smart friend who knows everything but can’t actually touch anything in your world. They can tell you exactly what to do, step by step, but you’re the one who has to do it.
Here’s what they’re good at:
- Answering questions (and they’re really good at this)
- Giving you suggestions and advice
- Helping you think through problems
- Generating content like emails, code, or ideas
But here’s what they can’t do:
- Take any action in your systems
- Make decisions and execute them
- Complete tasks that need multiple steps
- Use tools or APIs on their own
Let me give you a real example. Say you ask an AI assistant: “What’s the weather today?”
You: "What's the weather today?"
Assistant: "It's 72°F and sunny in New York."
You: "Should I bring an umbrella?"
Assistant: "No, it's not going to rain today."
Perfect, right? You got your answer. But notice what didn’t happen – the assistant didn’t check your calendar, didn’t see you have a meeting at 3 PM, didn’t notice the forecast shows rain later, and definitely didn’t pack an umbrella for you. It just answered your question.
That’s the limitation. And for a lot of things, that’s totally fine! Sometimes you just need information.
Agentic AI: The Autonomous Doer
Now here’s where things get interesting. Agentic AI doesn’t just tell you what to do – it actually does it.
Think of it like this: if an AI assistant is your smart friend giving advice, an agentic AI is your trusted employee who you can hand a project to and they’ll just… handle it. They’ll figure out the steps, make the decisions, use whatever tools they need, and come back with results.
This is what makes agents different:
- They can access and use tools (APIs, databases, systems)
- They make decisions based on what they find
- They complete multi-step workflows autonomously
- They only ask you when they really need input
Here’s the same scenario but with an agent:
You: "Book me a flight to New York next week."
Agent: *searches multiple airlines*
*compares prices and times*
*checks your calendar for conflicts*
*finds the best option*
*books the ticket*
*adds it to your calendar*
*sends confirmation to your email*
"Done! I booked you on Delta flight DL123, Tuesday 9 AM, $287.
I saw you have a meeting at 2 PM that day, so this gives you time.
Confirmation is in your email."
See the difference? You gave one instruction, and the agent handled everything. It made decisions (which flight is best), used tools (booking system, calendar, email), and completed the entire workflow. You didn’t have to do anything except say what you wanted.
Let Me Show You the Real Difference
I think the best way to understand this is with a practical example. Let’s say you need to check on your servers (if you’re not technical, just think of this as checking if your website is working).
With an AI Assistant:
You ask: “I need to check my server status.”
The assistant responds:
"Sure! To check your server status, you can:
1. Log into your AWS Console
2. Navigate to the EC2 Dashboard
3. Look at the instance state column
Or if you prefer the command line, run:
aws ec2 describe-instances
Would you like help with anything else?"
Great advice! But now you have to go do all of that. You have to log in, navigate around, run commands, interpret the results. The assistant told you what to do, but you’re still doing all the work.
With an Agentic AI:
You say the same thing: “I need to check my server status.”
The agent responds:
*connects to your AWS account*
*checks all your servers*
*analyzes the data*
"I checked your 5 servers. Here's what I found:
- web-server-1: Running fine, healthy
- web-server-2: Running but CPU is at 89% (might need attention soon)
- database-1: Running fine, healthy
- api-server-1: STOPPED - this one is down
- backup-server: Running fine, healthy
I noticed api-server-1 is down. This could be affecting your API endpoints.
Want me to restart it for you?"
The agent didn’t just tell you what to do. It actually went and checked everything, found a problem, and is ready to fix it if you want. That’s the power of agentic AI.
Why This Matters in 2026
Look, I get it. For years, we’ve been calling everything “AI assistants” and it worked fine. But now we’re in 2026, and the technology has split into two very different paths.
AI assistants got better at answering. They understand context better, they give more accurate information, they can help with more complex questions. ChatGPT, Claude, and similar tools are incredibly good at what they do.
Agentic AI learned to act. They can now access your tools, make decisions, and complete entire workflows. They’re not just smart anymore – they’re capable.
And here’s the thing: most people are still using AI like it’s 2023. They’re asking questions and copying answers when they could be handing off entire tasks.
Let me give you some real examples of what’s possible now:
GitHub Copilot Workspace
You tell it: “Add user authentication to this app.”
Instead of just giving you code snippets, it can:
- Analyze your codebase
- Write code across multiple files
- Suggest database changes
- Draft API endpoints
- Generate tests
- Create a pull request
You still review everything and make the final decisions, but it handles the heavy lifting. That’s moving toward agentic behavior.
AWS Bedrock Agents
You can set up an agent to monitor your infrastructure. It can:
- Watch your servers continuously
- Detect when something goes wrong
- Analyze issues
- Take corrective actions (like restarting services)
- Log everything
- Alert you when it needs help
Instead of checking everything manually, you get a report: “Had 3 minor issues last night, all handled automatically.” The agent does the routine monitoring while you focus on bigger problems.
Modern DevOps Agents
Your deployment fails at 2 AM. An agent can:
- Detect the failure quickly
- Analyze the logs
- Identify the issue
- Roll back the deployment
- Alert the team with context
- Generate an incident report
You find out at 9 AM that there was a problem and it’s already been handled. Not perfect, but better than waking up to a crisis.
The Quick Comparison
If you’re still wrapping your head around this, here’s a simple table that breaks it down:
| What It Does | AI Assistant | Agentic AI |
|---|---|---|
| Answers your questions | ✅ Yes | ✅ Yes |
| Gives you information | ✅ Yes | ✅ Yes |
| Takes actions in systems | ❌ No | ✅ Yes |
| Uses tools and APIs | ❌ No | ✅ Yes |
| Makes decisions on its own | ❌ No | ✅ Yes |
| Handles multi-step tasks | ❌ No | ✅ Yes |
| Works autonomously | ❌ No | ✅ Yes |
| Needs your approval for everything | ✅ Yes | ⚠️ Sometimes |
The pattern is pretty clear, right? Assistants are great at the “thinking” part. Agents are great at the “doing” part.
So When Should You Use Each One?
This is the practical question everyone should be asking. Because here’s the truth: you don’t always need an agent. Sometimes an assistant is exactly what you want.
Use an AI Assistant When:
You want information or advice. If you’re trying to learn something, understand a concept, or get suggestions, an assistant is perfect. You’re not trying to automate anything – you just want to think through something with help.
Examples:
- “Help me write this email” (you’ll review and send it)
- “Explain how this code works” (you’re learning)
- “Give me ideas for my presentation” (you’re brainstorming)
- “What’s the best way to structure this database?” (you want advice)
You want to stay in control. Sometimes you don’t want anything happening automatically. You want to review every step, make every decision, and execute everything yourself. That’s totally valid, and assistants are perfect for this.
You’re working on creative or strategic tasks. Writing, designing, planning, strategizing – these are areas where you want AI to augment your thinking, not replace your decision-making.
Use Agentic AI When:
You have repetitive workflows. If you’re doing the same multi-step process over and over, that’s a perfect candidate for an agent. Let it handle the routine stuff while you focus on things that actually need your brain.
Examples:
- Monitoring systems and alerting on issues
- Processing incoming data and routing it correctly
- Handling customer support for common questions
- Running deployments and rollbacks
- Generating and sending reports
You need 24/7 operation. Agents don’t sleep. If you need something monitored or handled around the clock, an agent is your answer.
Speed matters. Agents can react in seconds. If you need fast response to events or issues, agents beat humans every time.
The task is well-defined. If you can clearly describe the steps and decision points, an agent can probably handle it. The more structured the workflow, the better agents perform.
The Real Business Impact
Let me give you a concrete example of what this looks like in practice.
I know a company that was spending about 2 hours every day manually checking their server infrastructure. Someone had to log in, check each server, look at metrics, make sure everything was healthy. Boring, repetitive, but necessary.
First, they tried an AI assistant approach. They used ChatGPT to help generate the commands they needed to run. It was helpful – instead of remembering all the commands, they could just ask “how do I check CPU usage?” and get the answer. But they still had to run everything manually. They saved maybe 15 minutes a day. Better than nothing, but not game-changing.
Then they built an agentic AI solution. They set up an agent that:
- Checks all servers every 5 minutes
- Analyzes the metrics automatically
- Alerts them when something is actually wrong
- Can restart services if configured to do so
- Generates a daily health report
Now? They spend maybe 10-15 minutes a day reviewing the report. The agent handles the routine monitoring. That’s about 1 hour and 45 minutes saved every day. Not revolutionary, but meaningful. And they catch issues faster because the agent is always watching.
That’s the difference between telling and doing.
What People Get Wrong About This
There’s a lot of confusion out there, so let me clear up some common misconceptions:
“All AI is agentic now”
No, it’s really not. Most of the AI you use every day is still assistant-level. ChatGPT, Claude, most chatbots – they’re assistants. They’re really good assistants, but they’re not agents. True agentic AI that can take actions in your systems is still relatively new and not as widespread as people think.
“Agents will replace all human work”
This is the fear everyone has, and it’s not realistic. Agents are good at repetitive, well-defined tasks. They’re not replacing strategy, creativity, complex decision-making, or anything that requires real judgment. They’re tools that handle routine work so humans can focus on more valuable tasks.
“AI assistants are outdated now”
Not at all. Assistants are perfect for tons of use cases. Not everything needs to be automated. Sometimes you want advice, not action. Sometimes you want to stay in control of every step. Assistants aren’t going anywhere.
“Agents are just better assistants”
This is the big one people get wrong. They’re not “better” – they’re fundamentally different. It’s like saying a car is a “better” bicycle. No, it’s a different tool for different purposes. Assistants and agents solve different problems.
“Agents are too risky to use”
There’s some truth to this concern, but it’s manageable. Yes, giving AI the ability to take actions in your systems requires careful setup. You need guardrails, monitoring, and clear boundaries. But we’ve figured this out. Modern agent frameworks have safety built in. You can limit what they can do, require approval for certain actions, and monitor everything. It’s not riskier than giving a new employee access to your systems – you just need proper controls.
The Safety Question Everyone Should Ask
Since we’re talking about AI that can actually do things in your systems, let’s address the elephant in the room: is this safe?
The honest answer is: it depends on how you set it up.
Here’s what you need to think about:
Guardrails: Good agent systems let you define exactly what the agent can and can’t do. You can say “you can restart servers, but you can’t delete anything” or “you can book flights under $500, but ask me about anything more expensive.” These boundaries are crucial.
Monitoring: You should be logging everything your agent does. Every action, every decision, every API call. This isn’t just for debugging – it’s for accountability and safety.
Approval workflows: For high-stakes actions, you can require human approval. The agent can do all the analysis and preparation, but it waits for your “yes” before executing anything critical.
Rollback capabilities: Things go wrong sometimes. Your agent should be able to undo its actions, or at least alert you immediately if something unexpected happens.
The key is this: you’re not giving the agent unlimited power. You’re giving it specific, controlled capabilities within boundaries you define. It’s like giving someone the keys to your car – you’re trusting them with something important, but you’re not giving them ownership of your entire life.
Where This Is All Heading
We’re in 2026, and we’re still early in the agentic AI era. Here’s what’s developing:
Multi-agent systems are emerging. Instead of one agent doing everything, you might have multiple specialized agents working together. One handles customer support, another manages infrastructure, another handles data analysis. They can coordinate to handle complex workflows.
The line is blurring. Some AI assistants are adding limited action capabilities. Some agents are getting better at explaining their reasoning. We’re moving toward hybrid systems that can adapt based on what you need.
It’s getting easier to build. Right now, building an agent requires technical skill. But we’re seeing more platforms that make it easier. Eventually, less technical people will be able to build agents for specific workflows.
Safety is improving. As more people use agents, we’re learning better ways to build in safety features, monitoring, and control mechanisms. The technology is maturing.
The future probably isn’t “assistants vs agents.” It’s more likely “assistants and agents working together.” You’ll use assistants for thinking and planning, and agents for executing and monitoring. They complement each other.
How to Actually Get Started
Alright, enough theory. Let’s talk about what you should actually do with this information.
If You Want to Start Using AI Assistants:
This is the easy path. You can literally start right now.
-
Pick a tool. ChatGPT, Claude, or any of the major AI assistants. Most have free tiers to start.
-
Learn to prompt well. The better you ask questions, the better answers you get. This is a skill worth developing.
-
Start with simple tasks. Use it for writing, brainstorming, learning. Get comfortable with what it can and can’t do.
-
Integrate if needed. If you’re technical, most assistants have APIs you can use in your applications.
Cost: $0-100/month depending on usage
Time to start: Literally right now
Complexity: Low – anyone can do this
If You Want to Build Agentic AI:
This is more involved, but not as hard as you might think.
-
Define your workflow clearly. What exact task do you want automated? What are the steps? What decisions need to be made? The clearer you are, the better your agent will work.
-
Choose your platform. AWS Bedrock Agents, LangChain, AutoGPT, or other agent frameworks. Each has pros and cons. Bedrock is good if you’re already on AWS. LangChain is good if you want flexibility.
-
Start small. Don’t try to automate everything at once. Pick one simple workflow and get that working first.
-
Build in safety from day one. Set clear boundaries on what the agent can do. Log everything. Start with requiring approval for actions, then relax that as you gain confidence.
-
Test thoroughly. Run your agent through every scenario you can think of. What happens when things go wrong? How does it handle edge cases?
-
Monitor and improve. Once it’s running, watch it closely at first. You’ll find ways to improve it based on how it actually performs.
Cost: $100-1000+/month depending on what you’re building
Time to start: Days to weeks
Complexity: Medium – you’ll need some technical skills or help
The Bottom Line
Here’s what you need to remember from all of this:
AI assistants are for thinking. They help you understand, plan, create, and learn. They’re your smart advisor who knows a lot but can’t touch anything.
Agentic AI is for doing. They handle workflows, take actions, make decisions, and complete tasks. They’re your capable employee who can handle projects independently.
Both are valuable. Both have their place. The question isn’t “which is better?” The question is “which solves my problem?”
Need answers? Use an assistant.
Need actions? Use an agent.
Need both? Use both.
We’re in 2026, and we’re just starting to figure out what’s possible with AI that can actually do things. The assistants made us smarter. The agents are making us more productive.
The real power comes from knowing when to use each one.
Quick Reference Guide
Still not sure which you need? Ask yourself these questions:
Does it just need to answer, or does it need to act?
- Just answer → Assistant
- Actually act → Agent
Do I want to stay in control of every step?
- Yes → Assistant
- No, I want it handled → Agent
Is this a one-time question or an ongoing workflow?
- One-time → Assistant
- Ongoing → Agent
Am I trying to learn something or automate something?
- Learn → Assistant
- Automate → Agent
Do I need this to work when I’m not around?
- No → Assistant
- Yes → Agent
Simple as that.
What This Means for Different People
If You’re a Developer:
Learn both. Understanding how to build assistants and agents is becoming an important skill. Start with assistants (easier), then explore agents (more complex). Focus on safety, monitoring, and good design patterns.
Developers who understand agentic AI will have an advantage as this technology matures.
If You’re Running a Business:
Look at your workflows. Where are people doing repetitive, multi-step tasks? Those are agent candidates. Where do people need information and advice? Those are assistant use cases.
Start with one agent for one workflow. Measure the impact. If it works, expand. Don’t try to automate everything at once.
And remember: the goal isn’t to replace people. It’s to free them up to do more valuable work.
If You’re Just Curious:
Try ChatGPT or Claude if you haven’t already. That’s an assistant. Play with it. See what it can and can’t do.
Then watch for agent capabilities showing up in tools you use. GitHub Copilot, AWS services, automation platforms – agents are being built into everything.
Understanding this difference will help you make sense of where AI is actually going.
Final Thoughts
The AI revolution isn’t just about smarter answers. It’s about AI that can actually do things.
For years, we’ve had AI that could think but not act. Now we have AI that can do both. That’s a fundamental shift, and most people haven’t caught up to it yet.
AI assistants made us more informed. They gave us access to knowledge and helped us think through problems. That’s valuable, and it’s not going away.
Agentic AI is making us more productive. It’s taking tasks off our plate and handling them autonomously. That’s powerful, and it’s just getting started.
The key is understanding which tool solves which problem. Don’t use an assistant when you need an agent. Don’t use an agent when you just need advice.
We’re at the beginning of the agentic AI era. The assistants aren’t going away – they’re just getting company. And together, they’re changing how we work.
The question isn’t whether you should use AI. The question is: which AI should you use, and for what?
Now you know the answer.
📌 Wrapping Up
Thank you for reading! I hope this article gave you practical insights and a clearer perspective on the topic.
Was this helpful?
- ❤️ Like if it added value
- 🦄 Unicorn if you’re applying it today
- 💾 Save for your next optimization session
- 🔄 Share with your team
Follow me for more on:
- AWS architecture patterns
- FinOps automation
- Multi-account strategies
- AI-driven DevOps
💡 What’s Next
More deep dives coming soon on cloud operations, GenAI, Agentic-AI, DevOps, and data workflows follow for weekly insights.
🌐 Portfolio & Work
You can explore my full body of work, certifications, architecture projects, and technical articles here:
🛠️ Services I Offer
If you’re looking for hands-on guidance or collaboration, I provide:
- Cloud Architecture Consulting (AWS / Azure)
- DevSecOps & Automation Design
- FinOps Optimization Reviews
- Technical Writing (Cloud, DevOps, GenAI)
- Product & Architecture Reviews
- Mentorship & 1:1 Technical Guidance
🤝 Let’s Connect
I’d love to hear your thoughts drop a comment or connect with me on LinkedIn.
For collaborations, consulting, or technical discussions, feel free to reach out directly at [email protected]
Happy Learning 🚀
Filter Assignments
Qn 1: Get all movies (films) that have a rental rate greater than $3.
Just filter rows where rental rate is greater than 3.
SELECT * FROM film WHERE rental_rate > 3;
Qn 2: Get all movies that have a rental rate greater than $3 and a replacement cost less than $20.
Apply two conditions
SELECT * FROM film WHERE rental_rate > 3 AND replacement_cost < 20;
Qn 3: Get all movies that are either rated as ‘PG’ or have a rental rate of $0.99.
Same as previous qn apply two condition and check for both.
SELECT * FROM film WHERE rating = 'PG' OR rental_rate = 0.99;
Qn 4: Show the first 10 movies sorted by rental rate (highest first).
Using order by clause I learnt last class and using desc to show the highest value first.
SELECT * FROM film ORDER BY rental_rate DESC LIMIT 10;
Qn 5: Skip the first 5 movies and fetch the next 3 sorted by rental rate in ascending order.
offset 5 is used to not show the first few valuees.
SELECT * FROM film ORDER BY rental_rate ASC OFFSET 5 LIMIT 3;
Qn 6: Skip the first 5 movies and fetch the next 3 sorted by rental rate in ascending order.
Similar to last qn.
SELECT * FROM film ORDER BY rental_rate ASC OFFSET 5 LIMIT 3;
Qn 7: Get all movies with a rental duration between 3 and 7 days.
using between clause to get the desired output.
SELECT * FROM film WHERE rental_duration BETWEEN 3 AND 7;
Qn 8: Get all movies where the title starts with ‘A’ and ends with ‘e’.
pattern matching thing works like this: ‘A%’ means starts with A. ‘%e’ means ends with e. Combine them both.
SELECT * FROM film WHERE title LIKE 'A%e';
Qn 9: Find all customers who do not have an email address listed.
emall not listed means it will be null.
SELECT * FROM customer WHERE email IS NULL;
Qn 10: Find all movies released in 2006 with a rental rate of $2.99 or $3.99, and their title starts with ‘S’. Display the top 5 results.
this was fun to solve. mixing the smaller queries i already tried to come up with this.
SELECT title, rental_rate, release_year FROM film WHERE release_year = 2006 AND rental_rate IN (2.99, 3.99) AND title LIKE 'S%' LIMIT 5;
Qn 11: Display 10 customers after skipping the first 20, sorted alphabetically by last name.
as seen earlier we use the offset clause to skip the first 20 values.
SELECT * FROM customer ORDER BY last_name ASC OFFSET 20 LIMIT 10;
Qn 12: Get the top 5 movies with the highest replacement cost, skipping the most expensive one.
highest cost means we need the list in reverse or descending order. for skipping most expensive use offset.
SELECT * FROM film ORDER BY replacement_cost DESC OFFSET 1 LIMIT 5;
Qn 13: Find all rentals that occurred between ‘2005-05-01’ and ‘2005-06-01’.
simple between clause does the job.
SELECT * FROM rental WHERE rental_date BETWEEN '2005-05-01' AND '2005-06-01';
Qn 14: Get all actors whose last names contain the letters “man”.
pattern matching with “man”
SELECT * FROM actor WHERE last_name LIKE '%man%';
Qn 15: Find all movies where the special features are not listed (i.e., special_features is NULL).
get the rows where value is null for special_features
SELECT * FROM film WHERE special_features IS NULL;
Qn 16: Find all movies where the rental duration is more than 7 days.
Filter where rental duration is greater than 7.
SELECT * FROM film WHERE rental_duration > 7;
Qn 17: Find the first 10 movies with a rental rate of $2.99 or $4.99, a rating of ‘R’, and a title containing the word “L”.
Combine multiple filters and search for a letter inside title.
SELECT * FROM film WHERE rental_rate IN (2.99, 4.99) AND rating = 'R' AND title LIKE '%L%' LIMIT 10;
Qn 18: Find all movies where the title starts with “A” or “B” and ends with “s”.
Use OR for starting letters and pattern for ending letter.
SELECT * FROM film WHERE (title LIKE 'A%s' OR title LIKE 'B%s');
Qn 19: Find all movies where the title contains “Man”, “Men”, or “Woman”.
Check if title contains any of the given words using OR.
SELECT * FROM film WHERE title LIKE '%Man%' OR title LIKE '%Men%' OR title LIKE '%Woman%';
Qn 20: Find all movies where the special features are not listed (i.e., special_features is NULL).
SELECT * FROM film WHERE special_features IS NULL;
Qn 21: Find all movies where the rental duration is more than 7 days.
SELECT * FROM film WHERE rental_duration > 7;
Qn 22: Find all movies that have a rental rate of $4.99 and a replacement cost of more than $20.
Apply AND condition for both rental rate and replacement cost.
SELECT * FROM film WHERE rental_rate = 4.99 AND replacement_cost > 20;
Qn 23: Find all movies that have a rental rate of $0.99 or a rating of ‘PG-13’.
Use OR since either rental rate or rating condition works.
SELECT * FROM film WHERE rental_rate = 0.99 OR rating = 'PG-13';
Qn 24: Retrieve the first 5 rows of movies sorted alphabetically by title.
Sort alphabetically and take first 5 rows.
SELECT * FROM film ORDER BY title ASC LIMIT 5;
Qn 25: Skip the first 10 rows and fetch the next 3 movies with the highest replacement cost.
Sort by replacement cost descending, skip 10, take next 3.
SELECT * FROM film ORDER BY replacement_cost DESC OFFSET 10 LIMIT 3;
Qn 26: Find all movies where the rating is either ‘G’, ‘PG’, or ‘PG-13’.
SELECT * FROM film WHERE rating IN ('G', 'PG', 'PG-13');
Qn 27: Find all movies with a rental rate between $2 and $4.
SELECT * FROM film WHERE rental_rate BETWEEN 2 AND 4;
Qn 28: Find all movies with titles that start with ‘The’.
Use LIKE to match titles starting with “The”.
SELECT * FROM film WHERE title LIKE 'The%';
Qn 29: Find the first 10 movies with a rental rate of $2.99 or $4.99, a rating of ‘R’, and a title containing the word “Love”.
Combine filters and search for specific word “Love” in title.
SELECT * FROM film WHERE rental_rate IN (2.99, 4.99) AND rating = 'R' AND title LIKE '%Love%' LIMIT 10;
Qn 30: Find all movies where the title contains the % symbol.
Escape special character % and search in title.
SELECT * FROM film WHERE title LIKE '%%%' ESCAPE '';
Qn 31: Find all movies where the title contains an underscore (_).
SELECT * FROM film WHERE title LIKE '%_%' ESCAPE '';
Qn 32: Find all movies where the title starts with “A” or “B” and ends with “s”.
SELECT * FROM film WHERE (title LIKE 'A%s' OR title LIKE 'B%s');
Qn 33: Find all movies where the title contains “Man”, “Men”, or “Woman”.
Use OR with LIKE to match multiple words.
SELECT * FROM film WHERE title LIKE '%Man%' OR title LIKE '%Men%' OR title LIKE '%Woman%';
Qn 34: Find all movies with titles that contain digits (e.g., “007”, “2”, “300”).
Use regex to check if title contains digits.
SELECT * FROM film WHERE title ~ '[0-9]';
Qn 35: Find all movies with titles containing a backslash ().
SELECT * FROM film WHERE title LIKE '%\%';
Qn 36: Find all movies where the title does contain the words “Love” or “Hate”.
Use OR to check if title contains either word.
SELECT * FROM film WHERE title LIKE '%Love%' OR title LIKE '%Hate%';
Qn 37: Find the first 5 movies with titles that end with “er”, “or”, or “ar”.
Match titles ending with specific suffixes and limit results.
SELECT * FROM film WHERE title LIKE '%er' OR title LIKE '%or' OR title LIKE '%ar' LIMIT 5;
Is DDD still relevant in the vibe-coding era?
It is not possible to deny that a massive shift has happened. It’s hard to say the exact percentage of code that is now generated by LLMs. But what is obvious – this number rapidly grows. A lot of people are questioning the role of a software engineer and whether such a profession will exist in a couple of years.
However, LLMs are not working autonomously. They need someone to orchestrate them, providing a specification and validating an outcome. The more precise the specification is, the better the result you can expect. Basically, this rule applies to any development process.
Moreover, an LLM produces much more suitable code when given an example. The example could be a short code snippet, but it would be much better if it followed the project’s codebase style and approaches.
Finally, the generated code should be reviewed and tested carefully.
Evolution of Communication
Language is a way to communicate with other people. And sometimes it is not an easy task. It happens to be quite difficult to express thoughts or to understand other people’s ideas. Language allows one to express something in an endless number of different ways. Speaking is not deterministic, but humans handle that complexity in most cases.
Computers, on the other hand, understand only 0 and 1. The problem is – people don’t.
Programming languages were designed to fill this communication gap. They have strict rules for expressing what needs to be done so it can be clearly translated into what the computer understands. The program will do exactly what you tell it to do via programming language.
But what happened recently is that we can now communicate with coding agents in any language, and the agent translates it to the programming language of our choice. And here comes a problem – speaking is too ambiguous. And if the code base is also too ambiguous, no agent will be able to generate proper and reliable code that fits your needs, especially business logic.
You tell it to make a change to tenant management, but there are places in code where it is called client.
You tell it to add some functionality for a buyer, but it is also called a consumer, purchaser, and, again, client.
You tell it to add a new entity – client, because this is how it was called in meetings, but there are already plenty of things named as client in the code.
And each time you have to explain what is what, and you may still miss some tiny detail.
Of course, the good-to-go approach is to tell the agent to collect knowledge about the domain. But it is hard to aggregate the domain knowledge if the domain is not clearly defined.
Meet your new colleague
In addition to overcoming difficulties in communication between teams, you now need to overcome difficulties in communication with AI Agents. To reduce the number of hallucinations, you need to provide it with clear instructions and a summary of project knowledge so it can rely on them instead of repeating the same research every time. You need to be precise with terminology and in describing the results you want to achieve. It is very similar to onboarding a new colleague to the project.
What is Domain-Driven Design?
Domain-Driven Design – is a concept of having code base that reflects the business logic. It unites two worlds – technical and product commands, so they can understand each other better and work together more efficiently. I often see that Domain-Driven Design is defined as a set of patterns. However, patterns are only tools to achieve the final goal, and it is not mandatory to follow all of them.
From an engineering perspective, use cases reflect what’s going on in real life, and the code becomes more than just a set of random get/set calls. Why is it a good thing? Any request for a change to business logic can be easily translated into an existing code base. The question, “How does this feature work?”, does not require a week of investigation. Of course, real life is much more complicated, and such a state cannot be reached from the decision to apply DDD to the project from day one. It is the process of evolution to become business-centric, not framework-centric or infrastructure-centric. It requires hard work, with both engineering and product teams involved, to define and shape the domain.
Is it still relevant?
So, what advantages does Domain-driven design provide for AI-first development?
- Writing in DDD-style makes code more readable -> review process will become easier and faster;
- The domain layer literally repeats domain logic -> easy to notice if some use case is missing or doesn’t do what is expected because the logic isn’t scattered throughout the project;
- Domain-centric code is easy to cover with unit tests that check domain logic, not just getters and setters -> code becomes easier to maintain and extend; easy to notice that something is broken;
- Ubiquitous language makes the communication easier not only with humans, but also with LLMs -> less confusion means less hallucinations;
- Bounded contexts could force making smaller changes -> change will be applied to a context, not affecting the whole project with unpredictable consequences;
Domain-driven Design solves the same problem as before – decreases ambiguity and brings clarity to the development process, but now with the new party involved. Product and engineering teams, along with AI-agents, share the same knowledge.
Would I still apply DDD to a project? Definitely.
It may seem like such concepts are now outdated. Why bother with such things when an AI agent can write code for us, fix bugs, and answer questions about the product? But all of these rely on an input context. When the input becomes messy, the quality of the outcome drops drastically. Same as with simple old manual engineering – you must keep the bar high to maintain high-quality results.
AI Didn’t Break Your Culture. It Exposed It.
An engineer pushes back on a decision. The response: “ChatGPT recommended something else.” The tell isn’t the recommendation. It’s that they reached for an oracle instead of an argument. You’re not watching an AI problem. You’re watching a culture problem that predates the model by years.
I’ve been the oracle.
The Oracle Was Always There
Before ChatGPT, it was Stack Overflow. Before Stack Overflow, it was the one senior engineer who had been around longest. Teams find oracles when they don’t have frameworks. They fill the decision vacuum with whatever authority is nearest.
ChatGPT is just the most accessible oracle ever built. It’s confident, available at 2am, and it never makes you feel stupid for asking. Of course engineers reach for it.
The question is what they’re replacing with it.
If your team has no shared framework for architectural decisions, no clear authority structure, no agreed-on method for weighing tradeoffs … “ChatGPT recommended something else” is just the latest version of “Google says” or “I read a blog post” or the last tech talk someone attended. The source changes. The abdication of thinking stays the same.
That’s the culture problem. And it was there long before the first API call.
One flavor of team gets hit hardest. The team that’s technically accomplished but has never had to articulate its reasoning under pressure. The team where the senior engineers make the calls and everyone else executes. The team where architecture reviews are about performance, not inquiry. Those teams look fine until the oracle arrives and the emperor’s new clothes problem becomes impossible to ignore.
A lot of engineering culture runs on borrowed credibility. Conference talks from FAANG engineers with entirely different constraints. Benchmarks run on workloads nothing like yours. Technical opinions absorbed as gospel without anyone stress-testing the assumptions. Teams learn to cite sources instead of building judgment. ChatGPT is the endpoint of that trajectory … a perfectly confident authority on everything, available for anything, with zero friction and no accountability for being wrong.
When a culture already runs on borrowed credibility, an always-available oracle doesn’t change behavior. It accelerates it.
What Culture Actually Does
I’ve been the oracle. Decisions on my team ran through me. The projects that worked were the ones I was close to. I read that as signal that I was adding value. It was a sign that I’d built a dependency, not a team. The engineers weren’t deferring to me because my judgment was better. They were deferring because I had never built a culture where their judgment was tested.
When ChatGPT arrived, teams like the one I used to run had an obvious replacement oracle. Different interface. Same problem underneath.
Culture is not your team values on a Confluence page. It’s not the engineering principles doc nobody reads after onboarding. It’s not the Slack channel with memes and the occasional win.
Culture is what happens when nobody’s watching. The shared understanding of how decisions get made, how tradeoffs get reasoned through, how an engineer pushes back on a bad idea without making it personal. The invisible scaffolding that holds the architecture together when you’re not in the meeting.
Principals’ dashboards looked great. Velocity up. Output up. Ask about unplanned work and the room went quiet. Nobody had a number. The dashboards measured what was easy to measure, not what was actually happening inside the codebase.
What was happening in teams where AI tooling ran without guardrails was exactly what you’d expect from a team without shared standards. Multiple HTTP client implementations pulling in different directions. Conflicting error-handling patterns across the same surface. Inconsistent approaches to the same category of problem, sometimes within the same file. Not because engineers were careless. Because there was no shared framework for what “right” looked like, and AI filled that vacuum at ten times the speed of any individual contributor.
The teams that thrived had done the work before AI arrived. Standards weren’t a reaction to the new tools. Code patterns documented. Architecture decisions written down with the “why” included, not just the outcome. When you hand those teams an AI coding assistant, it becomes a force multiplier. The output fits the system.
When you hand that same tool to a team with no shared framework, you get a junk drawer with a CI/CD pipeline.
What AI Actually Exposed
AI didn’t break your culture. It exposed teams that never built one.
Most leaders will tell you they have a culture. They’ll point to the Notion doc. The architecture review calendar. The two-week sprint cadence. That’s structure. Structure and culture are not the same thing.
Real culture is whether your engineers can defend a decision in their own words. Not quote what a tool recommended. Not point to a benchmark someone else ran. Construct the argument. Weigh the tradeoffs. Say “here’s what I considered, here’s what I chose, and here’s what I’m watching to know if I was wrong.”
If your engineers can do that, AI is a force multiplier.
If they can’t, you have a problem that predates the model.
The culture that produces “ChatGPT said so” as a decision argument is the same culture that produces decisions by committee, approval chains that substitute for judgment, and teams that stopped asking “why” because it was never welcomed in the room. AI just gave that culture a name and a quotable moment.
AI didn’t create teams that can’t think. It created a faster, more accessible oracle that made the problem visible.
Teach Them to Think
Architecture Decision Records written for the engineer who wasn’t in the room when the decision was made. Not bullet points justifying the choice after the fact … actual reasoning. Here’s what we considered. Here’s what we ruled out and why. Here’s what we’re watching to know if we got it wrong. That’s the document that builds judgment over time. ADRs written that way become the baseline for how engineers on your team actually make decisions, long before any AI model enters the picture. One ADR on session management saved us from a full migration that turned out to be unnecessary.
Code standards documented as reasoning, not rules. Here’s the choice, here’s what it costs, here’s when you should challenge it. The same standards that let an engineer recognize a bad architectural recommendation from an AI are the ones that let them recognize a bad recommendation from a colleague, or from themselves at 11pm under deadline pressure. You don’t build two separate frameworks for human decisions and AI decisions. You build one. You make it cheap to be wrong and expensive to hide it.
Review culture that interrogates “why” before it approves “what.” The mid-level engineer who asks “why are we building this?” in a planning meeting is worth more to the team than the senior who executes quietly and ships fast. That question is the signal you hire for. The engineer who asks why is the one building judgment instead of pattern matching. That is what you need when the pattern matcher in the room is an AI model that’s confident about everything and accountable for nothing.
Give them room to be wrong. Give them problems worth reasoning through. Give them the feedback loops to know when their judgment is off. Those are the engineers who lead teams within 18 months.
The same standards that let engineers recognize a bad AI recommendation are the ones that let them recognize a bad recommendation from a colleague, or from themselves at 11pm under pressure.
That’s on Us
If your engineers can’t defend a decision in their own words, the problem isn’t the tool they’re reaching for. You never built a culture where their judgment was trusted, tested, or developed.
That’s a leadership failure.
The fix starts with you. Not with the AI policy document. Not with the acceptable-use guidelines. With you.
With whether you ask “why” or just “when.” With whether your reviews create space for engineers to be wrong and learn, or create pressure to be right fast. With whether you’ve removed yourself as a dependency on good decisions being made, or whether your team still needs you in the room to trust itself.
A team that defers to ChatGPT over its own judgment is a team that’s been trained to defer to authority. Before the model arrived, that authority was you. I know it was me.
AI is going to keep getting better. The oracles will keep getting more confident, more accessible, more persuasive. The teams that win won’t be the ones with the best AI policies.
They’ll be the ones who built the culture where engineers can defend a decision in their own words before the oracle arrived. And the ones willing to reckon, right now, with what the oracle is exposing.
The next time an engineer says “ChatGPT recommended something else” in a review … don’t reach for the policy doc. Ask them to walk you through what they’re weighing. What are the tradeoffs? What are they watching?
That’s the conversation that builds culture. One exchange at a time, in the room where decisions actually happen.
Getting there isn’t a tooling problem. It never was.
That’s on us. All of us.
I write daily about engineering leadership at jonoherrington.com.
If I Had to Rebuild My Developer Career From Zero in 2026, I’d Do This
If I lost everything career-wise tomorrow and had to rebuild from zero, I would do it very differently than most advice on the internet suggests.
I would not start with a 9-month roadmap.
I would not buy five courses.
I would not obsess over the “perfect stack.”
I would definitely not wait until I felt ready.
I would optimize for proof.
That is the whole framework.
Not confidence.
Not credentials.
Not endless preparation.
Proof.
Step 1: Pick One Marketable Direction
Not ten.
One.
Examples:
- frontend for product teams
- backend for SaaS tools
- iOS apps with SwiftUI
- internal automation for small businesses
Most people stay stuck because they try to keep every possible path open.
That feels flexible.
It is actually paralyzing.
Specificity creates momentum.
Step 2: Build One Useful Project, Not a Portfolio Graveyard
I would build a single project with a real use case and document it properly.
Not a clone.
Not another todo app.
Something with context:
- who it is for
- what pain it solves
- what tradeoffs I made
- what I learned
One real project with clear explanation is worth more than six shallow demos.
Step 3: Learn in Public Just Enough to Be Visible
I would not try to become an influencer.
But I would publish useful artifacts:
- short lessons
- bug writeups
- architecture notes
- project updates
Because visibility matters.
Not vanity visibility.
Proof visibility.
The market needs a way to discover that you exist and that you can think.
Writing gives it that.
Step 4: Get Good at Written Communication Early
This is the unfair advantage most beginners ignore.
If you can write:
- a sharp README
- a clean project case study
- a clear bug report
- a thoughtful outreach message
you will feel more hireable faster.
Because now your skill is easier to trust.
Step 5: Target Environments Where Proof Beats Pedigree
I would not spend all my energy chasing the most competitive, prestige-heavy path first.
I would target places where visible skill matters:
- startups
- freelance clients
- small product teams
- founder-led companies
- communities where builders get noticed
Later, if I wanted brand-name companies, I could aim there with stronger proof in hand.
Step 6: Create a Weekly Output System
Not motivation.
Output.
Every week I would aim for:
- one build improvement
- one public artifact
- one outreach action
That means I am always increasing:
- skill
- proof
- surface area for luck
That last one matters more than people admit.
Luck finds active people faster.
Step 7: Stop Measuring Progress by Feeling
This is where many beginners lose months.
They keep asking:
“Do I feel ready?”
Wrong metric.
I would ask:
- what did I ship?
- what did I publish?
- what feedback did I get?
- what became easier this month?
Feelings fluctuate.
Evidence is calmer.
Final Thought
If I had to rebuild from zero in 2026, I would not try to look impressive early.
I would try to become undeniable in small, concrete ways.
One project.
One clear direction.
One useful public trail.
One repeatable system.
That is enough to create momentum.
And momentum is what most developer careers are really missing in the beginning.
I write about developer careers, proof-first growth, and building enough visible leverage to stop feeling invisible.
dirham v1.3.0 — A Universal Web Component for the UAE Dirham Symbol
The UAE Dirham now has an official Unicode codepoint — U+20C3 — accepted for Unicode 18.0. But operating systems won’t ship native font support until September 2026.
dirham bridges that gap. It maps the official glyph to U+20C3 via a custom web font, so your content is semantically correct today and future-proof for when native support arrives.
What’s new in v1.3.0
The headline feature is <dirham-price> — a Web Component that formats and displays Dirham amounts in any framework, no wrappers needed.
<script type="module" src="https://cdn.jsdelivr.net/npm/dirham/dist/web-component/index.js"></script>
<dirham-price amount="1250"></dirham-price>
<dirham-price amount="5000000" notation="compact"></dirham-price>
<dirham-price amount="500" use-code></dirham-price>
It supports 8 attributes: amount, locale, decimals, notation, use-code, symbol-size, weight, and currency.
Works everywhere
Vue:
<script setup>
import "dirham/web-component";
</script>
<template>
<dirham-price amount="1250" />
<dirham-price amount="5000000" notation="compact" />
</template>
Angular:
import { CUSTOM_ELEMENTS_SCHEMA, Component } from "@angular/core";
import "dirham/web-component";
@Component({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
template: `<dirham-price amount="1250"></dirham-price>`
})
export class AppComponent {}
Svelte:
<script>
import "dirham/web-component";
</script>
<dirham-price amount="1250"></dirham-price>
React still has dedicated components with full TypeScript support:
import { DirhamPrice } from "dirham/react";
<DirhamPrice amount={1250} />
<DirhamPrice amount={750} className="text-emerald-400 text-2xl" />
Full feature set
| Feature | How |
|---|---|
| React SVG component | <DirhamSymbol size={24} weight="bold" /> |
| React price component | <DirhamPrice amount={1250} notation="compact" /> |
| Web Component (any framework) | <dirham-price amount="1250"> |
| CSS web font | <i class="dirham-symbol"></i> |
| JS formatting |
formatDirham(1234.5) → ℃ 1,234.50
|
| Parsing |
parseDirham("℃ 1,234.50") → 1234.5
|
| Clipboard | await copyDirhamSymbol() |
| CLI | npx dirham copy |
| CDN | jsDelivr, zero install |
| 9 weight variants | thin → black |
| 5 font variants | sans, serif, mono, arabic, default |
| RTL support | Arabic locale with correct symbol placement |
Why U+20C3?
Other approaches use Private Use Area hacks or plain text substitution. This package uses the officially assigned codepoint, which means:
- Your content is semantically correct — search engines, screen readers, and parsers understand it
- When Unicode 18.0 ships natively (Sep 2026), the web font gracefully becomes unnecessary — zero migration
- The symbol behaves like
$,€, and£— it’s a real currency character
Links
- npm: npmjs.com/package/dirham
- Live demo: pooya.blog/dirham
- GitHub: github.com/pooyagolchian/dirham
npm install dirham
How to Get More GitHub Stars: The Definitive Guide (33K Stars Case Study)
How to Get More GitHub Stars: The Definitive Guide
We grew AFFiNE from 0 to 33,000 GitHub stars in 18 months. This guide covers every tactic we used — what worked, what failed, and what actually moves the needle.
Why I Wrote This
When I started marketing AFFiNE, I couldn’t find a comprehensive guide on growing GitHub stars. Most articles were surface-level fluff:
- “Write good documentation” (okay, but then what?)
- “Share on social media” (which platforms? how?)
- “Build a community” (how do you start with zero users?)
This guide is different. It’s the tactical playbook I wish existed when we started.
Table of Contents
| Section | What You’ll Learn |
|---|---|
| Part 1 | Why stars matter (and don’t matter) |
| Part 2 | The first 100 stars (bootstrap phase) |
| Part 3 | 100 to 1,000 stars (content + community) |
| Part 4 | 1,000+ stars (scaling + virality) |
| Part 5 | GitHub Trending strategies |
| Part 6 | Common mistakes to avoid |
Part 1: Why GitHub Stars Matter
The Real Value of Stars
Stars are credibility, not customers.
What stars actually give you:
- ✅ Social proof when pitching investors
- ✅ Trust signal for potential users
- ✅ Visibility on GitHub Trending
- ✅ Team motivation metric
- ✅ Contributor attraction
What stars DON’T give you:
- ❌ Guaranteed users or revenue
- ❌ Product-market fit
- ❌ A sustainable business
Use stars as a stepping stone, not a destination.
The Credibility Threshold
| Star Count | What It Signals |
|---|---|
| < 100 | “New project, unknown” |
| 100-500 | “Some traction, worth trying” |
| 500-1,000 | “Legitimate project” |
| 1,000-5,000 | “Established, active community” |
| 5,000+ | “Industry-recognized” |
| 10,000+ | “Major project” |
Your first goal: Cross the 1,000 star threshold as fast as possible.
Part 2: The First 100 Stars
This Phase Is “Artificial” (And That’s OK)
Your first 100 stars should come from people you know. Don’t pretend otherwise.
Why this matters:
- New visitors check star count before engaging
- < 100 stars = low conversion rate on everything else
- You need this baseline before content marketing works
Tactics for 0→100
1. Personal Network Outreach
Message everyone you know in tech:
“Hey! We just open-sourced our project. Would mean a lot if you could check it out and star it if you find it interesting.”
- Keep it personal, not mass-blast
- Target developers who might actually use it
- Follow up individually
2. Workspace/Conference Hustle
- Print QR code to your repo
- Walk around coworking spaces
- Chat with developers at conferences
- Ask during coffee/lunch breaks
3. Existing Communities
- Company Slack/Discord
- University alumni networks
- Previous colleague groups
- Online communities you’re already part of
More tactics: The Cold Start Problem for GitHub Projects: How to Get Your First 1,000 Stars
Part 3: 100 to 1,000 Stars
Shift to Organic Growth
Once you hit 100, your tactics should become authentic and scalable.
Content Strategy
Four types of content that work:
| Type | Example | Purpose |
|---|---|---|
| Direct | “Introducing [Project]” | Explain what you built |
| Tutorial | “Build X with [Project]” | Show practical usage |
| Listicle | “10 OSS tools for Y” | Reach broader audience |
| Building in Public | “How we solved X” | Build community |
Key principles:
- Every post needs a clear CTA (“Star us on GitHub”)
- Include repo link in multiple places
- Use visuals (GIFs, screenshots)
Content deep dive: Developer Marketing Playbook: How to Reach Technical Audiences in 2026
Distribution Channels
Tier 1 (High Impact):
- Reddit (r/programming, r/opensource, niche subreddits)
- Hacker News (unpredictable but high ceiling)
- Product Hunt (good for launches)
Tier 2 (Medium Impact):
- Dev.to, Hashnode, HackerNoon
- Twitter/X (dev community)
- Discord/Slack communities
Tier 3 (Long-term SEO):
- Your company blog
- GitHub Awesome Lists
- Documentation sites
Channel breakdown: GitHub Repo Promotion: 15 Channels That Actually Drive Stars
Awesome Lists Strategy
GitHub “Awesome” lists are curated collections (awesome-python, awesome-react, etc.).
How to get added:
- Find relevant awesome-* repos
- Read their contribution guidelines carefully
- Make sure your project meets their criteria
- Open a PR with proper formatting
Pro tips:
- Some lists require minimum stars, tests, or docs
- Chinese awesome lists have higher acceptance rates (75% in our experience)
- Start with smaller, niche lists before big ones
Part 4: Scaling to 1,000+
The Compound Effect
After 1,000 stars, growth accelerates. You’ll get:
- Organic discovery on GitHub
- Mentions in newsletters
- Unsolicited blog posts
- Contributor applications
Your job shifts from “pushing” to “amplifying.”
Community Building
Create a home for your users:
- Discord server (preferred for dev tools)
- GitHub Discussions
- Dedicated forum
Engage consistently:
- Respond to issues within 24 hours
- Thank contributors publicly
- Share community wins
Community tactics: Developer Marketing 101: How to Grow Your Open Source Project
Combining with Product Hunt
Product Hunt can accelerate GitHub growth dramatically.
The playbook:
- Build PH launch → drive traffic to GitHub
- Spike in stars → hit GitHub Trending
- Trending → more organic stars
- Leverage momentum for press/community
PH + GitHub synergy: Product Hunt for Open Source: The Step-by-Step Playbook
Part 5: GitHub Trending
Why Trending Matters
GitHub Trending page is massive exposure:
- Thousands of developers browse it daily
- One day on Trending = 500-2,000 new stars
- Creates cascading visibility
Factors That Affect Trending
| Factor | Impact |
|---|---|
| Star velocity | High — stars per hour/day |
| Recent activity | Medium — commits, issues, PRs |
| Language category | Medium — less competition in niche languages |
| Account signals | Low — but new accounts count less |
Trending Tactics
-
Coordinate your push — Launch content, notify community, post on social all in the same 24-48 hour window
-
Time it right — Weekdays, avoid holidays, mornings PT
-
Pick your language — “TypeScript Trending” easier than “All Languages Trending”
-
Sustain momentum — Don’t just spike; maintain activity for multiple days
Complete breakdown: GitHub Star Growth: 7 Proven Tactics That Got Us 33k Stars
Part 6: Common Mistakes
1. Launching Too Early
Promoting with < 100 stars = low conversion on everything.
Fix: Get your first 100 from your network before any public promotion.
2. One Big Push, Then Nothing
Growth requires consistency, not single events.
Fix: Plan ongoing content/promotion, not just launch day.
3. Ignoring Issues
Nothing kills a project’s reputation faster than unresponded issues.
Fix: Respond within 24 hours, even if just to acknowledge.
4. Poor README
Your README is your landing page. First impressions matter.
README checklist:
- [ ] Clear one-sentence description
- [ ] Screenshot or GIF at top
- [ ] Quick start guide (< 5 steps)
- [ ] Feature list
- [ ] Contributing link
- [ ] License
5. No Clear CTA
If you don’t ask for stars, you won’t get them.
Fix: Include “⭐ Star us on GitHub” in content, docs, and social posts.
The AFFiNE Journey: Timeline
| Month | Stars | Key Events |
|---|---|---|
| 0 | 0 | Launch |
| 1 | 1,000 | Product Hunt #1, initial PR |
| 3 | 5,000 | Reddit viral post |
| 6 | 10,000 | Consistent content strategy |
| 12 | 25,000 | HN front page, multiple Trending |
| 18 | 33,000 | Sustained organic growth |
Full case study: How I Got 33K GitHub Stars: The Complete Marketing Playbook
Complete Resource Library
GitHub Growth
- How I Got 33K GitHub Stars: The Complete Marketing Playbook
- GitHub Star Growth: 7 Proven Tactics That Got Us 33k Stars
- GitHub Star Growth: 10K Stars in 18 Months (Real Data)
- The Cold Start Problem for GitHub Projects
- GitHub Repo Promotion: 15 Channels That Actually Drive Stars
Product Launch
- Product Hunt for Open Source: The Step-by-Step Playbook
- Product Hunt Launch: The Complete 2026 Playbook for #1
- Open Source Launch Checklist: 127 Tasks
Developer Marketing
- Developer Marketing Playbook: How to Reach Technical Audiences in 2026
- Developer Marketing 101: How to Grow Your Open Source Project
- Open Source Marketing: The Complete Guide for 2026
Key Takeaways
- First 100 stars are artificial — Get them from your network
- Content + Distribution = Growth — Write once, distribute everywhere
- Consistency beats intensity — Weekly content > one viral post
- GitHub Trending is the multiplier — Coordinate your efforts for spikes
- Stars ≠ users — But they build the credibility to get users
Free Resources
📘 Gingiris Open Source Marketing — Complete OSS marketing playbook
📗 Gingiris Launch Playbook — Product launch strategies
📙 Gingiris B2B Growth — PLG and SLG growth tactics
Got questions? Drop a comment or find me on Twitter @iris_carrot.
Build a Real-Time Social Media App with InsForge, MiniMax, and Next.js
Introduction
In this tutorial, we will build a full-stack social platform where users post, like, repost, follow each other, get real-time notifications, and chat with an in-app AI assistant.
Here is what we will be building:
- A Next.js frontend with a real-time feed, post composer, profile pages, notifications, explore, and an AI chat screen
- InsForge as the backend platform, managing the database, auth, file storage, real-time pub/sub, and AI gateway from a single place
- MiniMax M2.7 via GitHub Copilot as the agent that builds the entire application through InsForge Agent Skills and MCP.
- Google Stitch for generating the design reference before the agent builds
- Deployment triggered from inside GitHub Copilot, with no manual steps outside the editor
By the end, you will have a working social platform template you can fork and adapt to whatever you are building next.
Let’s get started.
What Is InsForge
InsForge is an open-source backend platform that bundles a Postgres database, a REST API layer via PostgREST, an AI model gateway that routes to any OpenRouter-compatible model, a real-time pub/sub system, serverless edge functions, and a CLI, all into a single deployable platform. You can self-host it with Docker or use the managed cloud. You bring the application logic. InsForge handles what’s underneath.
What We Are Using InsForge For
Three things in particular make InsForge the right fit for a project like this one.
Agent Skills: When you run insforge create, the CLI installs a .agents/ folder into your project. That folder contains the InsForge SDK documentation, API patterns, and auth setup in a format the agent can read directly. Before the agent writes a single file, it reads that folder. This is why the build prompt can stay short. The agent already knows how to talk to InsForge before you type anything.
The AI gateway: InsForge manages the AI provider keys automatically on the backend, you don’t need to put an OpenRouter key in your frontend .env file. From there, any AI call in your frontend app using the SDK hits one InsForge endpoint and passes a model string. To swap models, you simply change that string; nothing else in the codebase needs to be touched. The backend gateway securely routes the request through OpenRouter, supporting models from OpenAI, Anthropic, Google, DeepSeek, X-AI, and more.
The PostgREST layer: Every table in your InsForge database is automatically a REST endpoint. The agent writes queries against the InsForge SDK. There is no data access layer to build, no custom API routes to wire up. You describe the schema, and the endpoints are there.
Setting Up the Project
Every InsForge project starts with the CLI. Install it once globally, log in, and you are set for every project you build after this.
npm install -g @insforge/cli
insforge login
That is a one-time setup. From here on, every time you want to start a new project, you create a folder and run insforge create inside it.
mkdir ripple
cd ripple
insforge create
The CLI asks you to pick a template. We picked Next.js. After that, it installs the Agent Skills, writes skills-lock.json, and asks if you want to set up deployment now. Say no for now. We will come back to that at the end.
One more thing, before you start building, install the MCP server. The quickest way is through the InsForge VS Code extension. Install it from the marketplace, and it will show you a one-click option to connect the MCP. Once done, you will see the MCP Connected indicator in the top-right corner of your InsForge dashboard, and your agent is ready to act.
Designing with Google Stitch
Before writing a single prompt, we used Google Stitch to design the UI for Ripple. We used this prompt to get started:
Build a social media app called Ripple. Amber gold (#F59E0B) as the primary color.
Screens: feed, composer, profile, notifications, Wave AI chat, auth screens.
Stitch exports a design.md file with the full design system, colors, typography, component structure, and screen layouts.
Copy that file and save it in your project root in VS Code. When you reference it in your agent prompt, the agent has all the visual context it needs upfront, so you are not going back and forth on colors or layout later.
With the design in place, we had everything the agent needed to build the UI and wire the backend in a single pass. Time to write the prompt.
Building the App
We used GitHub Copilot as the agent, running MiniMax M2.7*,* because it handles long multi-step tasks well and stays on track across a full project build. We gave it one prompt:
Build a social media app called Ripple using InsForge as the backend platform.
Use InsForge MCP Server for all operations.
Features:
- Auth: sign up, login with name, @handle, email, password
- Feed: post (called Ripple) with text + image/video upload, like (Wave),
repost (Spread), reply, bookmark
- Realtime feed updates
- Post composer with draft save
- Profile page with cover, avatar, bio, followers/following
- Notifications: likes, replies, follows, mentions
- Explore: trending topics, suggested users
- Wave AI: chat interface connected to InsForge AI gateway via OpenRouter
- Wave AI has collapsible right panel with chat history and bookmarks
- Deploy on InsForge
Follow the design system in design.md for colors, typography, and components.
Use InsForge for all backend. Read .agents folder for skills.
Before touching any file, the agent read .agents/skills/insforge/ to understand the InsForge SDK, then laid out the full database schema profiles, ripples, waves, spreads, follows, notifications, drafts, ai_chat_history, and more, and created a build plan for itself. Only after that did it start writing code.
The file structure was produced in one pass:
ripple/
├── src/app/
│ ├── feed/page.tsx
│ ├── profile/[handle]/page.tsx
│ ├── notifications/page.tsx
│ ├── ripple/[id]/page.tsx
│ └── wave/page.tsx
├── src/components/
│ ├── ripple/RippleCard.tsx
│ └── ripple/RippleComposer.tsx
├── src/lib/
│ ├── insforge.ts
│ └── auth-context.tsx
└── .agents/
└── skills/insforge/
What is worth noticing here is that insforge.ts is not a custom wrapper; the agent read the skill and knew exactly how to initialize the InsForge client.
Same with auth-context.tsx: it wired sessions directly to InsForge Auth without any manual setup from us. Now, all of this came from one prompt. But what the agent actually built inside each of these files, how it handled auth sessions, how it wired realtime, how AI talks to the InsForge gateway, that is where things get interesting. So let’s see exactly what agent built inside each of those files.
What InsForge Handled, Feature by Feature
Let’s start with auth, since that is what everything else depends on.
Auth
Authentication in Ripple runs entirely through InsForge Auth: sign up, email verification, login, and session management. All the state stays in a single React Context, the agent is generated and wired up in one pass.
Sign-up is a two-step flow. The agent calls insforge.auth.signUp(), checks if email verification is required, and stores the pending profile in localStorage until the OTP is confirmed. Once verified, it inserts the profiles record using the authenticated user ID.
const { data } = await insforge.auth.signUp({ email, password, name });
if (data?.requireEmailVerification) {
localStorage.setItem("ripple_pending_name", name);
return { requireEmailVerification: true };
}
// after OTP confirmed
await insforge.database.from("profiles").insert([{
id: data.user.id, name: pendingName, handle: pendingHandle, email,
}]);
The signup page tracks a step state that switches between the form and the verify screen. Login is simpler, one call to insforge.auth.signInWithPassword() and the session is set.
Database
With auth out of the way, the agent moved on to the database. InsForge runs on PostgreSQL under the hood, and every table gets automatically exposed as a REST endpoint through PostgREST, which means the agent never had to write a single custom API route.
The schema the agent built covers the full surface area of the app. The core tables are profiles, ripples, ripples_media, waves (likes), spreads (reposts), follows, notifications, and ai_chat_history for the Wave AI sessions. The notifications table also has a Postgres trigger attached to it, so every insert immediately fires a real-time broadcast over the WebSocket.
-- setup_trigger.sql
CREATE OR REPLACE FUNCTION notify_new_notification()
RETURNS TRIGGER AS $$
BEGIN
PERFORM pg_notify(
'new_notification',
json_build_object(
'id', NEW.id,
'user_id', NEW.user_id,
'type', NEW.type,
'actor_id', NEW.actor_id,
'ripple_id', NEW.ripple_id
)::text
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
Because PostgREST understands foreign keys, the agent could request deeply nested relational data in a single query rather than chaining multiple fetches. Here is the feed query from page.tsx, which pulls ripples alongside their author profiles, attached media, waves, and spreads in one request:
// page.tsx — fetching the main feed
const { data, error } = await insforge.database
.from("ripples")
.select(`
*,
profiles (*),
ripples_media (*),
waves (*),
spreads (*)
`)
.is("reply_to", null)
.order("created_at", { ascending: false })
.limit(50);
The profiles (*) in the select string is where PostgREST detects the foreign key between ripples.user_id and profiles.id and performs the join automatically on the backend, returning the author’s data nested inside each post object. The same pattern applies to waves and spreads, so the UI always knows the engagement state of a post without a second request.
Storage
The database takes care of structured data, but for every file, avatars, cover photos, and post media, the agent provisioned three separate InsForge Storage buckets: avatars, covers, and ripples.
InsForge Storage is S3-compatible and sits natively beside the auth and database layers, so the SDK handles uploads, hashing, and public URL generation in a single call without any custom middleware.
For profile photos, the agent used .uploadAuto(), which takes a File object and returns a public URL directly. After each upload resolves, it immediately writes that URL back to the profiles table in the database.
// profile/edit/page.tsx
if (avatar) {
const { data, error } = await insforge.storage
.from("avatars")
.uploadAuto(avatar);
if (error) throw error;
avatarUrl = data.url;
}
if (cover) {
const { data, error } = await insforge.storage
.from("covers")
.uploadAuto(cover);
if (error) throw error;
coverUrl = data.url;
}
await insforge.database
.from("profiles")
.update({ avatar_url: avatarUrl, cover_url: coverUrl })
.eq("id", user.id);
For post media, the pattern is slightly different because a single ripple can carry up to four attached images. The agent wrote a loop that runs after the post row is created, uploads each file to the ripples bucket, and inserts a matching record into ripples_media that binds the file URL back to the post’s ID.
// RippleComposer.tsx
for (const file of media) {
const { data: uploadData, error } = await insforge.storage
.from("ripples")
.uploadAuto(file);
if (error || !uploadData) throw error;
await insforge.database.from("ripples_media").insert([{
ripple_id: ripple.id,
bucket: uploadData.bucket,
key: uploadData.key,
url: uploadData.url,
type: file.type.startsWith("video") ? "video" : "image",
}]);
}
Realtime
With the database writing data correctly, the next thing the app needed was for that data to reach every connected client without a page refresh. InsForge Realtime runs on WebSockets, and the agent wired up four live channels: ripples for the global feed, ripples_media for media updates, trending_topics for live topic changes, and notifications:% for per-user alerts.
The feed component subscribes to ripples on mount and handles two event types: INSERT for new posts and UPDATE for engagement count changes.
// page.tsx — feed subscription
const response = await insforge.realtime.subscribe("ripples");
if (response.ok) {
insforge.realtime.on("INSERT", async (payload) => {
const newRipple = payload.new as Ripple;
if (!newRipple.reply_to) {
const { data } = await insforge.database
.from("ripples")
.select("*, profiles (*), ripples_media (*), waves (*), spreads (*)")
.eq("id", newRipple.id)
.single();
if (data) setRipples((prev) => [data as Ripple, ...prev]);
}
});
insforge.realtime.on("UPDATE", (payload) => {
const updated = payload.new as Ripple;
setRipples((prev) =>
prev.map((r) =>
r.id === updated.id
? { ...r, wave_count: updated.wave_count, spread_count: updated.spread_count }
: r
)
);
});
}
The INSERT payload only carries the raw new row, so the agent does a quick .select() with joins before pushing it into the state, same pattern as the feed query from the Database section. The UPDATE handler just patches the counts in-place without refetching the full post.
For notifications, the Postgres trigger from setup_trigger.sql does the broadcasting on the database side. When a new row hits the notifications table, the trigger publishes directly to notifications:{user_id} over the WebSocket, and realtime-context.tsx picks it up on the frontend to increment the bell count instantly.
AI Gateway
After real-time, the agent focused on the AI gateway. Ripple comes with an in-app AI called Wave AI. Instead of connecting directly to OpenAI or Anthropic, dealing with separate billing, and worrying about exposing keys on the frontend, it uses InsForge’s AI gateway. This gateway manages routing, authentication, and model access all in one place.
The gateway call follows the same shape as the OpenAI SDK, so it feels familiar:
const completion = await insforge.ai.chat.completions.create({
model: "anthropic/claude-sonnet-4-5",
messages: [
{
role: "system",
content: `You are Wave AI, a helpful assistant on the Ripple social platform. You are talking to ${profile?.name || "a user"}.`,
},
...pastMessages,
{ role: "user", content: userMessage.content },
],
});
const reply = completion.choices[0]?.message?.content;
Swapping the model is one line, change "anthropic/claude-sonnet-4-5" to "openai/gpt-4o" or any other model the gateway supports, and nothing else changes.
One thing the AI gateway doesn’t do on its own is remember past conversations. Every time you call insforge.ai.chat.completions.create, it only knows what’s in the messages array you pass. Close the tab and that’s gone.
So the agent added two database tables, ai_chat_sessions to group conversations, and ai_chat_history to store individual messages. Every time the user sends a message, it gets written to the database. Every time Wave AI replies, that gets written too. When you come back to the /ai page later, a useEffect fetches that session and loads all the messages back in. The conversation picks up exactly where it left off.
With auth, database, storage, realtime, and Wave AI all working, the app is ready to run, and it’s time to test it locally.
Running Locally
Before deploying, run the app locally to make sure everything works end-to-end.
npm install
npm run dev
Open http://localhost:3000, sign up with a test account, go through the full flow, auth, posting a Ripple, checking the feed. If your InsForge credentials are in .env.local, everything should work on the first run.
Note: InsForge takes care of all the backend wiring, but the frontend is yours to shape. I made a few tweaks to the UI, adjusting the layout and refining some interactions, to make it feel more like my own, and that is the nice part: the backend is handled, so you can spend your time on the experience instead.
Deploying from GitHub Copilot
Once everything worked locally, deploying took one prompt:
Deploy to InsForge.
The agent read the project config, picked up the credentials, and called the create-deployment MCP tool, all from inside Copilot. No browser dashboard, no separate deploy config.
It zipped the source, uploaded it, and InsForge ran npm install and npm run build in a container with the environment variables injected. The live URL came back in the terminal.
What’s Next
At this point, you have a fully working social platform running on InsForge. Auth, a real-time feed, media uploads, notifications, and an AI assistant, all live and deployable from inside GitHub Copilot.
From here, the project is yours to extend. Swap the AI model by updating one value in the InsForge dashboard. Replace the schema entirely, and the same SDK patterns, the same Agent Skills, and the same deployment flow all carry forward to whatever you build next. You can fork the project repo and start from there.
To learn more about InsForge, check out the GitHub repo.













