<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sidharth Sangelia</title>
    <description>The latest articles on DEV Community by Sidharth Sangelia (@sidharth_sangelia).</description>
    <link>https://dev.to/sidharth_sangelia</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3458581%2Fc3175927-f4cd-4dad-b12f-04700b4bf241.JPG</url>
      <title>DEV Community: Sidharth Sangelia</title>
      <link>https://dev.to/sidharth_sangelia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sidharth_sangelia"/>
    <language>en</language>
    <item>
      <title>I'm Rebuilding My Old Invoice App and This Time I Actually Know What I'm Doing</title>
      <dc:creator>Sidharth Sangelia</dc:creator>
      <pubDate>Sun, 19 Apr 2026 19:12:33 +0000</pubDate>
      <link>https://dev.to/sidharth_sangelia/im-rebuilding-my-old-invoice-app-and-this-time-i-actually-know-what-im-doing-4bg7</link>
      <guid>https://dev.to/sidharth_sangelia/im-rebuilding-my-old-invoice-app-and-this-time-i-actually-know-what-im-doing-4bg7</guid>
      <description>&lt;p&gt;So I have this old project called Invoicepedia. Built it like 6 months ago when I was just starting to learn full stack. Next.js, Clerk, Neon, basic CRUD. The usual "I just learned how to connect a database" kind of project.&lt;/p&gt;

&lt;p&gt;I opened it recently and honestly it was rough. Delete button crashed the app sometimes. You could submit an empty invoice form with no validation. The Stripe integration was half working. I had both Drizzle and Prisma installed at the same time for some reason. Classic.&lt;/p&gt;

&lt;p&gt;I almost deleted it and moved on to something new.&lt;/p&gt;

&lt;p&gt;Instead I decided to actually fix it and turn it into something real.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Not Just Start a New Project
&lt;/h2&gt;

&lt;p&gt;Every time I start something new I spend like 3-4 days just on setup. Auth, database, environment variables, middleware, all that stuff before you even write a single line of actual product code. And by the time I'm done with setup I've already lost interest or I hit some weird error and just abandon the whole thing.&lt;/p&gt;

&lt;p&gt;Invoicepedia already had all of that. It was broken but the foundation was there. Auth worked. Database was connected. Routes existed.&lt;/p&gt;

&lt;p&gt;So I thought okay, why not just fix this one instead of starting from zero again. Worst case I learn something. Best case I actually ship something.&lt;/p&gt;




&lt;h2&gt;
  
  
  First Thing I Did Was Stop Adding Features
&lt;/h2&gt;

&lt;p&gt;Old me would have immediately started adding new stuff. Charts. Dark mode. AI features. Whatever sounded cool.&lt;/p&gt;

&lt;p&gt;This time I made a list of everything that was broken and fixed that first. No new features until the existing stuff actually worked properly.&lt;/p&gt;

&lt;p&gt;Removed dead dependencies. Rewrote the schema. Added proper Zod validation to every server action. Changed hard deletes to soft deletes because you should never hard delete financial records. Fixed the middleware. Added actual error handling.&lt;/p&gt;

&lt;p&gt;It took a week and nothing visually changed. The app looked the same. But after that week I wasn't scared to touch the codebase anymore and that felt different.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I'm Actually Trying to Build
&lt;/h2&gt;

&lt;p&gt;Yeah I know. Another invoice app. There's like 50 of them already.&lt;/p&gt;

&lt;p&gt;But here's the thing — most of them are either too expensive or too complicated for a normal freelancer. FreshBooks charges you $19-30 a month and limits your clients on the cheaper plans. Wave was free and then slowly started charging for things that used to be free. Invoice Ninja has so many features that the UI looks like a cockpit, a normal person opens it and immediately closes the tab.&lt;/p&gt;

&lt;p&gt;The people I want to use this are freelancers. Developers, designers, writers. People who just did some work, need to send an invoice, and want to get paid without learning accounting software.&lt;/p&gt;

&lt;p&gt;So the whole idea is just — do the basic things really well. Don't try to be QuickBooks. Don't try to be FreshBooks. Just be the thing a freelancer needs to send professional invoices and track who's paid them and who hasn't.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I'm Shipping First
&lt;/h2&gt;

&lt;p&gt;I made a list of like 10 features I want to build eventually. AI invoice generation, automated payment reminders, client portal, recurring invoices, expense tracking. The full thing.&lt;/p&gt;

&lt;p&gt;Then I looked at that list and realised if I wait until all of that is done I will never ship anything.&lt;/p&gt;

&lt;p&gt;So the first version is going to have three things:&lt;/p&gt;

&lt;p&gt;PDF generation — because an invoice app that can't produce a PDF is just a form.&lt;/p&gt;

&lt;p&gt;Email sending — so you can actually send the invoice to your client from inside the app instead of downloading it and attaching it to Gmail manually.&lt;/p&gt;

&lt;p&gt;A proper dashboard — right now it's just a table. I'm adding three metric cards at the top so when you open the app you see immediately how much you got paid this month, how much is still outstanding, and how many invoices are overdue. That's actually useful information.&lt;/p&gt;

&lt;p&gt;That's it. Ship those three. Get some users. See what they actually want next.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Goal is 5 Users
&lt;/h2&gt;

&lt;p&gt;Not 500. Not 5000. Five real people who use it and tell me what's wrong with it.&lt;/p&gt;

&lt;p&gt;I'll post updates as I build. What I'm adding, what's breaking, what people say when they actually try it. I don't have it all figured out, I'm figuring it out as I go.&lt;/p&gt;

&lt;p&gt;If you're a freelancer who's annoyed at paying too much for invoicing software, keep an eye on this. If you're a dev learning full stack, hopefully this is useful to see what an actual messy in-progress project looks like compared to the clean tutorial versions.&lt;/p&gt;




&lt;p&gt;Stack is Next.js 15, Prisma, NeonDB, Clerk, Tailwind, shadcn/ui.&lt;/p&gt;

&lt;p&gt;Happy to answer questions in the comments if anything here was interesting or you want to know more about specific decisions I made.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>webdev</category>
      <category>typescript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>HTTP Status Codes: A Developer's Real-World Guide🚦</title>
      <dc:creator>Sidharth Sangelia</dc:creator>
      <pubDate>Wed, 03 Sep 2025 16:46:18 +0000</pubDate>
      <link>https://dev.to/sidharth_sangelia/http-status-codes-a-developers-real-world-guide-3gd4</link>
      <guid>https://dev.to/sidharth_sangelia/http-status-codes-a-developers-real-world-guide-3gd4</guid>
      <description>&lt;p&gt;Hey fellow developers! 👋&lt;/p&gt;

&lt;p&gt;Last week, I spent three hours debugging what I thought was a complex authentication issue, only to discover it was a simple 422 error that I completely misunderstood. That frustrating evening made me realize how many of us know the "famous" status codes (hello, 404!) but struggle with the nuanced ones that could save us hours of debugging.&lt;/p&gt;

&lt;p&gt;So here's my attempt to break down HTTP status codes in a way that actually sticks. No dry documentation here – just real scenarios we face every day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wait, Why Should I Care About Status Codes?
&lt;/h2&gt;

&lt;p&gt;Before we dive in, let me tell you why this matters. Last month, our API was returning 200 OK for failed operations (yeah, I know...), and our frontend team was going crazy trying to figure out why their error handling wasn't working. The fix? Proper status codes. It's not just about following standards – it's about making your life and your team's life easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Categories That Actually Matter
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2xx - The "Everything's Fine" Family ✅
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;200 OK - The Reliable Friend&lt;/strong&gt;This is your bread and butter. GET request for user data? 200. Successful login? 200. But here's the thing – don't use 200 for everything just because it works.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Good use of 200&lt;/span&gt;
&lt;span class="nx"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;
&lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="nx"&gt;OK&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;

&lt;span class="c1"&gt;// Bad use of 200 &lt;/span&gt;
&lt;span class="nx"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nf"&gt;users &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;creating&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="nx"&gt;OK&lt;/span&gt; &lt;span class="c1"&gt;// Should be 201!  &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;201 Created - The Overachiever&lt;/strong&gt;I used to ignore this one until I realized how much cleaner my API responses became. Use 201 when you've successfully created something new. Your frontend developers will thank you because they can differentiate between "I got existing data" and "I just created something new."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Perfect 201 usage&lt;/span&gt;
&lt;span class="nx"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My awesome post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Some content here&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nl"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="nx"&gt;Created&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;456&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My awesome post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;created_at&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2024-01-15T10:30:00Z&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;204 No Content - The Strong Silent Type&lt;/strong&gt;This one's beautiful for DELETE operations and updates where you don't need to send data back. Clean, efficient, and tells the client "job done, nothing more to say."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Elegant 204 usage&lt;/span&gt;
&lt;span class="nx"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;
&lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt;
&lt;span class="c1"&gt;// No response body needed - the status says it all &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3xx - The "Look Elsewhere" Family 🔄
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;301 vs 302 - The Redirect Siblings&lt;/strong&gt;These two confused me for years. Here's how I remember them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;301&lt;/strong&gt;: "This moved permanently, update your bookmarks" (like when you change your domain)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;302&lt;/strong&gt;: "This moved temporarily, keep using the old URL" (like maintenance pages)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Real talk: Most of the time you'll use 301 for SEO-friendly redirects and 302 for temporary stuff.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;304 Not Modified - The Bandwidth Saver&lt;/strong&gt;This little gem enables caching magic. When implemented correctly, it can dramatically speed up your app. The client asks "has this changed since last time?" and you respond "nope, use your cached version."&lt;/p&gt;

&lt;h3&gt;
  
  
  4xx - The "You Messed Up" Family ❌
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;400 Bad Request - The Vague Complainer&lt;/strong&gt;This is the generic "something's wrong with your request" response. But here's a pro tip: always include helpful error messages in the response body.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Bad 400 response&lt;/span&gt;
&lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt; &lt;span class="nx"&gt;Bad&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid request&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;// Good 400 response&lt;/span&gt;
&lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt; &lt;span class="nx"&gt;Bad&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Validation failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;details&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Email format is invalid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Password must be at least 8 characters&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;401 vs 403 - The Permission Police&lt;/strong&gt;This distinction trips up so many developers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;401 Unauthorized&lt;/strong&gt;: "Who are you? Please log in."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;403 Forbidden&lt;/strong&gt;: "I know who you are, but you can't do this."&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of 401 as a bouncer asking for ID, and 403 as the same bouncer saying "sorry, members only."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;404 Not Found - The Celebrity&lt;/strong&gt;Everyone knows this one, but here's something interesting: sometimes returning 404 is a security feature. Instead of returning 403 for a private resource (which tells attackers it exists), return 404 to keep things secret.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;422 Unprocessable Entity - The Perfectionist&lt;/strong&gt;This one saved my sanity. Use 422 when the request is well-formed but semantically incorrect. Like when someone submits a perfectly formatted JSON with an email that passes regex validation but the domain doesn't exist.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 422 vs 400 example&lt;/span&gt;
&lt;span class="nx"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user@fakemaindomain.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Valid format, fake domain&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;age&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="c1"&gt;// Semantically wrong&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nl"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;422&lt;/span&gt; &lt;span class="nx"&gt;Unprocessable&lt;/span&gt; &lt;span class="nx"&gt;Entity&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid user data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;details&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Domain does not exist&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;age&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Age cannot be negative&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5xx - The "I Messed Up" Family 💥
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;500 Internal Server Error - The Nightmare&lt;/strong&gt;The universal "something went wrong on our end." Never let your users see these in production without proper error handling and logging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;502 Bad Gateway - The Middleman Problem&lt;/strong&gt;This usually means your server is trying to talk to another server (database, external API, microservice) and that conversation failed. Super common with microservices architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;503 Service Unavailable - The Planned Outage&lt;/strong&gt;Perfect for maintenance windows. Include a Retry-After header to tell clients when to try again.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Debugging Stories You'll Relate To
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Case of the Mysterious 502
&lt;/h3&gt;

&lt;p&gt;Last month, our checkout process started throwing 502s randomly. Turns out, our payment service was timing out, but our API gateway was returning 502 instead of 504. The fix? Proper timeout configuration and using 504 (Gateway Timeout) for actual timeout scenarios.&lt;/p&gt;

&lt;h3&gt;
  
  
  The 200 That Lied
&lt;/h3&gt;

&lt;p&gt;We had a "successful" user creation endpoint that always returned 200 OK, even when the email already existed. The frontend team was showing success messages for failed registrations. The lesson? Don't be afraid to use 409 (Conflict) for duplicate resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Authentication Maze
&lt;/h3&gt;

&lt;p&gt;Our mobile app was stuck in redirect loops because we were using 302 for OAuth redirects. Mobile apps don't handle redirects the same way browsers do. Switch to proper API responses with tokens instead of relying on redirects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Status Codes in the Real World
&lt;/h2&gt;

&lt;h3&gt;
  
  
  REST API Best Practices
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// User Management API&lt;/span&gt;
&lt;span class="nx"&gt;GET&lt;/span&gt;    &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;     &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;POST&lt;/span&gt;   &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;     &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="nx"&gt;created&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;GET&lt;/span&gt;    &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="nx"&gt;found&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;found&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;PUT&lt;/span&gt;    &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;updated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;found&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deleted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;found&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Error Handling Patterns
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Frontend error handling&lt;/span&gt;
&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;showSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User created successfully!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;422&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;showValidationErrors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;details&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;409&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;showError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User already exists&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;showError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Something went wrong. Please try again.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Tools That'll Save Your Sanity
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Browser DevTools
&lt;/h3&gt;

&lt;p&gt;Your best friend for debugging. The Network tab shows status codes for every request. Pro tip: right-click and "Copy as cURL" to test APIs directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Postman/Insomnia
&lt;/h3&gt;

&lt;p&gt;Perfect for API testing. Set up collections with different scenarios and expected status codes.&lt;/p&gt;

&lt;h3&gt;
  
  
  curl Commands
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check just the status code&lt;/span&gt;
curl &lt;span class="nt"&gt;-I&lt;/span&gt; https://api.example.com/users

&lt;span class="c"&gt;# Follow redirects&lt;/span&gt;
curl &lt;span class="nt"&gt;-L&lt;/span&gt; https://example.com/old-url

&lt;span class="c"&gt;# Show response headers and status&lt;/span&gt;
curl &lt;span class="nt"&gt;-v&lt;/span&gt; https://api.example.com/users 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Quirky Ones Worth Knowing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;418 I'm a Teapot&lt;/strong&gt; ☕Started as an April Fools' joke but is now used by some APIs to detect automated requests. Some developers use it for rate limiting with a sense of humor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;451 Unavailable for Legal Reasons&lt;/strong&gt;Named after the book "Fahrenheit 451," used when content is blocked due to legal restrictions. More relevant than ever in our current internet landscape.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Pitfalls I've Seen (And Made)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The "Everything is 200" Syndrome
&lt;/h3&gt;

&lt;p&gt;Don't do this. If something failed, don't return 200 with an error message in the body. Your HTTP client libraries are built to handle different status codes – use them!&lt;/p&gt;

&lt;h3&gt;
  
  
  Ignoring Response Bodies for Errors
&lt;/h3&gt;

&lt;p&gt;A 400 status code without explanation is useless. Always include helpful error messages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mixing Authentication and Authorization
&lt;/h3&gt;

&lt;p&gt;401 for authentication failures, 403 for authorization failures. Keep them separate in your head and your code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Not Monitoring Status Codes
&lt;/h3&gt;

&lt;p&gt;Set up alerts for unusual patterns in your status codes. A sudden spike in 5xx errors might indicate a problem before users start complaining.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing Your Status Codes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Best example for API testing&lt;/span&gt;
&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User API&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should return 201 when creating user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Test User&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should return 422 for invalid email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;invalid-email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Test User&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;422&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;details&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Status codes aren't just numbers – they're a communication protocol between your server and clients. Getting them right makes debugging easier, improves user experience, and makes your APIs more predictable.&lt;/p&gt;

&lt;p&gt;The next time you're building an API endpoint, take a moment to think: "What's the most appropriate status code for this scenario?" Your future self (and your teammates) will thank you.&lt;/p&gt;

&lt;p&gt;What's your most encountered status code? Mine's probably 422 – I'm apparently really good at sending semantically incorrect requests to my own APIs! 😅&lt;/p&gt;

&lt;p&gt;Drop a comment below with your status code war stories. We've all been there, and sharing these experiences helps us all become better developers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Useful Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml" rel="noopener noreferrer"&gt;HTTP Status Codes Registry&lt;/a&gt; - The official source&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://httpstatusdogs.com/" rel="noopener noreferrer"&gt;HTTP Status Dogs&lt;/a&gt; - Because learning should be fun&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" rel="noopener noreferrer"&gt;MDN HTTP Status Codes&lt;/a&gt; - Comprehensive documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>api</category>
      <category>backend</category>
    </item>
    <item>
      <title>From Web to Mobile: Completing My React Native Journey with Maximilian Schwarzmüller</title>
      <dc:creator>Sidharth Sangelia</dc:creator>
      <pubDate>Sat, 30 Aug 2025 12:04:59 +0000</pubDate>
      <link>https://dev.to/sidharth_sangelia/from-web-to-mobile-completing-my-react-native-journey-with-maximilian-schwarzmuller-4l</link>
      <guid>https://dev.to/sidharth_sangelia/from-web-to-mobile-completing-my-react-native-journey-with-maximilian-schwarzmuller-4l</guid>
      <description>&lt;p&gt;After weeks of dedication and hands-on coding, I’ve successfully completed Maximilian Schwarzmüller’s comprehensive React Native course on Udemy. As someone with a solid background in web development, this transition to mobile app development has been both challenging and incredibly rewarding.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Little Backstory
&lt;/h2&gt;

&lt;p&gt;I’ve always wanted to learn app development. Back in Class 12, I ambitiously tried setting up Android Studio, running the simulator, and building a simple app. What followed was an entire month of battling with environment variables, Java configurations, and errors I barely understood.&lt;/p&gt;

&lt;p&gt;By the end of that month, I honestly questioned whether Android development was really for me. The complexity of the setup alone felt like a huge barrier to entry.&lt;/p&gt;

&lt;p&gt;Looking back now, I can say this: &lt;strong&gt;React Native is a fantastic entry point into the mobile ecosystem.&lt;/strong&gt; It lowers the barrier, lets you leverage existing React skills, and still leaves room to grow into full native development later as the need arises.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Course Experience
&lt;/h2&gt;

&lt;p&gt;Maximilian’s teaching approach struck the perfect balance between practical implementation and conceptual understanding. Rather than overwhelming students with theory, he focused on building real applications while explaining the “why” behind each decision. This hands-on methodology made complex mobile development concepts much more digestible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Learning Milestones
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Understanding the Component Ecosystem
&lt;/h3&gt;

&lt;p&gt;One of the first major shifts was adapting to React Native’s component structure. Gone are the familiar HTML elements like div, p, and a. Instead, I learned to work with React Native’s specific components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;View instead of div&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Text for all text content&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TouchableOpacity for interactive elements&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Image for media display&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This wasn’t just a syntax change — it represented a fundamental shift in how mobile interfaces are constructed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Navigation Patterns
&lt;/h3&gt;

&lt;p&gt;Web development relies heavily on URLs and browser history, but mobile apps follow different patterns. The course covered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stack Navigator&lt;/strong&gt;: For hierarchical navigation where users drill down into content&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tab Navigator&lt;/strong&gt;: For parallel sections of an app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Drawer Navigator&lt;/strong&gt;: For side menu functionality&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each navigation pattern serves specific user experience goals that don’t directly translate from web development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Native Device Integration
&lt;/h3&gt;

&lt;p&gt;Perhaps the most exciting aspect of React Native is its ability to access native device features. The course introduced me to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Camera functionality&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Location services&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Device storage&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Push notifications (overview)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even in their simplest form, these integrations showed me the true power of mobile development — creating apps that live closer to users’ daily lives.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reinforced React.js Skills
&lt;/h2&gt;

&lt;p&gt;An unexpected benefit was how React Native deepened my React.js knowledge. Concepts like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Component lifecycle management&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;State management patterns&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Props and data flow&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hooks usage&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;… all became clearer when applied in a mobile context. It felt like practicing the same music scales on a different instrument — the repetition in a new setting gave me fresh perspective.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges and Realizations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Learning Curve
&lt;/h3&gt;

&lt;p&gt;While my React background helped, mobile development brought unique challenges:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Understanding platform-specific behaviors (iOS vs Android)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handling different screen sizes and orientations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adapting to mobile-first interaction patterns&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Debugging on physical devices vs simulators&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Beyond the Basics
&lt;/h3&gt;

&lt;p&gt;The course laid a strong foundation, but I know this is just the start. Areas I plan to explore further include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Native module configuration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced state management in mobile contexts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Performance optimization for mobile devices&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Looking Ahead
&lt;/h2&gt;

&lt;p&gt;This course gave me the confidence to start building mobile apps, while also showing me how much more there is to learn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Immediate Next Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Deep dive into push notifications&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Exploring advanced native modules&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Building more complex apps independently&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Understanding app deployment and store submissions&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Long-term Goals:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Mastering mobile-specific UX patterns&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Platform-specific optimizations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cross-platform best practices&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mobile analytics and performance monitoring&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Advice for Fellow Web Developers
&lt;/h2&gt;

&lt;p&gt;If you’re considering moving from web to mobile development:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Embrace the differences&lt;/strong&gt; — don’t force web patterns into mobile contexts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Start with the fundamentals&lt;/strong&gt; — get comfortable with React Native’s components&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Test on real devices&lt;/strong&gt; — simulators are great, but real-world usage is different&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Be patient with native features&lt;/strong&gt; — setup and testing can be tricky, but rewarding&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Completing this React Native course feels like opening a door into an entirely new dimension of development. Web will always be my foundation, but mobile offers unique opportunities to create apps that integrate seamlessly into people’s daily routines.&lt;/p&gt;

&lt;p&gt;The journey from web to mobile isn’t just about syntax or frameworks — it’s about understanding how people interact with technology in a more personal way.&lt;/p&gt;

&lt;p&gt;Huge thanks to Maximilian Schwarzmüller for putting together such a structured and practical course. For anyone on the fence about learning React Native, his teaching makes the transition much less intimidating.&lt;/p&gt;

&lt;p&gt;This is just the beginning of my mobile dev journey — and I can’t wait to see where it leads. 🚀 I will be sharing more of my learnings on &lt;a href="https://notebook.thesidharth.com" rel="noopener noreferrer"&gt;notebook.thesidharth.com&lt;/a&gt; soon.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What about you? Have you ever tried transitioning between development platforms? Share your story — I’d love to hear it.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>react</category>
      <category>learning</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Building My First AI-Powered App: From Whisper to Vercel Limits</title>
      <dc:creator>Sidharth Sangelia</dc:creator>
      <pubDate>Thu, 28 Aug 2025 19:17:50 +0000</pubDate>
      <link>https://dev.to/sidharth_sangelia/building-my-first-ai-powered-app-from-whisper-to-vercel-limits-1cf</link>
      <guid>https://dev.to/sidharth_sangelia/building-my-first-ai-powered-app-from-whisper-to-vercel-limits-1cf</guid>
      <description>&lt;p&gt;I thought building AI apps would be about training models and complex machine learning stuff, but as I dug deeper, I found out - why reinvent the wheel when you can solve 70-80% of tasks with existing models?&lt;/p&gt;

&lt;p&gt;Turns out, the real challenge wasn't the AI part. It was everything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Idea: What I Wanted to Build
&lt;/h2&gt;

&lt;p&gt;I'd been consuming tons of great video content on YouTube (both long and short form) and Instagram, and kept thinking: "This would make such a good blog post for better readability and SEO reach."&lt;/p&gt;

&lt;p&gt;So I came up with what seemed like a simple solution - a NextJS 15 web app where users could:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Upload a video&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get AI-generated transcript using OpenAI's Whisper-1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Transform it into SEO-optimized content using ChatGPT/Gemini&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download a ready-to-publish blog post&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;How hard could it be, right? OpenAI already has Whisper for transcription, other LLM models are readily available through APIs. Just connect the dots and boom - instant article creation.&lt;/p&gt;

&lt;p&gt;Plus, the blogging and content creation industry is booming. I thought if I could build this, maybe I could create some recurring revenue like the folks on Twitter always talk about.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ The Tech Stack (What I Thought I Needed)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Frontend &amp;amp; Backend:&lt;/strong&gt; Next.js seemed like the obvious choice - I could handle both frontend and backend with API routes and server actions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI Processing:&lt;/strong&gt; OpenAI's Whisper-1 for transcription, GPT-4/Gemini for content optimization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hosting:&lt;/strong&gt; Vercel, because... well, it's the easiest deployment ever.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File handling:&lt;/strong&gt; This became a whole saga (more on this below).&lt;/p&gt;

&lt;p&gt;Here's what I thought the flow would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// What I thought the flow would look like&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;processVideo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transcription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transcriptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;whisper-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blogPost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gpt-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
      &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Turn this into an SEO blog: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;transcription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;blogPost&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Spoiler alert: It wasn't that easy.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚡ First Reality Check: The 25MB File Upload Nightmare
&lt;/h2&gt;

&lt;p&gt;My initial plan was to use UploadThing (Theo's creation) since it had a generous free tier. But then I discovered Whisper-1 has a 25MB file limit per upload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Most decent-quality videos are way larger than 25MB.&lt;/p&gt;

&lt;p&gt;In development, I could easily test with small videos under 25MB, but for a production app that people would actually pay for? This was a major roadblock.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution attempt #1:&lt;/strong&gt; Extract audio from video (audio files are much smaller than video files).&lt;/p&gt;

&lt;p&gt;I found ImageKit.io, which could handle uploads, compression, and audio extraction. Perfect! I ditched UploadThing and dove into ImageKit's documentation.&lt;/p&gt;

&lt;p&gt;Spent hours implementing the audio extraction feature, writing code, testing locally. Everything looked good. Then came the moment of truth - testing the actual audio file extraction.&lt;/p&gt;

&lt;p&gt;Nothing worked.&lt;/p&gt;

&lt;p&gt;I added console.logs everywhere, thinking it was a code issue. After hours of debugging, I realized the problem: I'd exhausted ImageKit's free plan just from testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The kicker:&lt;/strong&gt; ImageKit's paid plan costs $80/month and provides way less processing power than I'd need for a robust app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution attempt #2:&lt;/strong&gt; Use FFmpeg on my own server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;New problem:&lt;/strong&gt; I'm a student without money for servers.&lt;/p&gt;

&lt;p&gt;So I decided to postpone the audio extraction feature and just put a strict 25MB limit for now. "I'll figure this out later," I told myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  💻 The API Integration That Worked... Until It Didn't
&lt;/h2&gt;

&lt;p&gt;I implemented all the API integrations and functions. Everything worked beautifully on localhost. The transcription was accurate, the content optimization was decent, and I was feeling pretty good about myself.&lt;/p&gt;

&lt;p&gt;Time to deploy and show my friends!&lt;/p&gt;

&lt;p&gt;I deployed to Vercel, shared the link with excitement, and... nothing worked.&lt;/p&gt;

&lt;p&gt;The app would start processing, show a loading state, and then just timeout with a 504 error.&lt;/p&gt;

&lt;p&gt;After a lot of head-scratching and debugging, I found the culprit: &lt;strong&gt;Vercel's function timeout limits&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;My processing pipeline was taking 60+ seconds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;File upload: ~10 seconds&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Audio processing: ~20 seconds&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Whisper transcription: ~30 seconds&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GPT optimization: ~15 seconds&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Google search time:&lt;/strong&gt; "vercel function timeout limit"&lt;/p&gt;

&lt;p&gt;The harsh reality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hobby plan:&lt;/strong&gt; 10 seconds&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pro plan:&lt;/strong&gt; 60 seconds&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enterprise:&lt;/strong&gt; 15 minutes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Quick math:&lt;/strong&gt; My processing takes 60+ seconds. Even the Pro plan wouldn't save me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bigger realization:&lt;/strong&gt; This isn't just a Vercel problem. AWS Lambda has 15-minute limits, Netlify has similar constraints. Serverless functions aren't meant for long-running tasks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❌ What I Built:  User Upload → Vercel 
   Function → Process (60s) → Timeout.

✅ What I Actually Needed:  User Upload → Queue 
   Job → Background Worker → Notify User   

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🤔 Understanding the Real Problem
&lt;/h2&gt;

&lt;p&gt;Here's what I learned about serverless architecture the hard way:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Serverless functions are great for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Fast responses (under 30 seconds)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Auto-scaling&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Quick API endpoints&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simple data processing&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Serverless functions are terrible for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Long-running AI processing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;File manipulation tasks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Complex workflows&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anything that takes time&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The fundamental issue:&lt;/strong&gt; I was trying to fit a long-running AI workflow into a request-response architecture. That's like trying to fit a truck through a car door.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔧 Solution Discovery: Enter Background Jobs
&lt;/h2&gt;

&lt;p&gt;Back to Google: "background jobs nodejs", "async processing for AI apps"&lt;/p&gt;

&lt;p&gt;I discovered several options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Inngest&lt;/strong&gt; - Developer-friendly, good free tier&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;BullMQ&lt;/strong&gt; - Redis-based, more complex setup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AWS SQS&lt;/strong&gt; - Powerful but overkill for my needs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Redis Queue&lt;/strong&gt; - DIY approach&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I chose &lt;strong&gt;Inngest&lt;/strong&gt; because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;It handles the infrastructure for me&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Great developer experience&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Built-in retries and error handling&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Free tier was sufficient for testing&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's the new architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;inngest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./inngest/client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// API endpoint just queues the job (fast!)&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/process-video&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jobId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;inngest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;video/process&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;videoUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;videoUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Processing started! We'll notify you when it's ready.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;jobId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;checkStatusAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/api/status/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;jobId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Actual processing happens in background (no time limits!)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;processVideo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inngest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;process-video&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;video/process&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Now I can take all the time I need&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transcription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;processWithWhisper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;videoUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;optimizeWithGPT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;transcription&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Notify user when done&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;notifyUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt; 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The difference:&lt;/strong&gt; Instead of making users wait for 60+ seconds (and timing out), I immediately return a "we're processing it" response and handle the heavy lifting in the background.&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 What I Actually Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Architecture Matters More Than I Thought
&lt;/h3&gt;

&lt;p&gt;You can't just throw AI processing into a standard web app architecture and expect it to work. AI apps have fundamentally different requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Long processing times&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unpredictable resource usage&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Need for progress tracking&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Error handling for expensive operations&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Research Infrastructure Constraints First
&lt;/h3&gt;

&lt;p&gt;I should have researched deployment limitations &lt;strong&gt;before&lt;/strong&gt; writing a single line of code. Now I know to ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;What are the timeout limits?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How much memory/CPU can I use?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What happens if processing fails halfway through?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How do I handle user notifications?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Hardest Part Isn't the AI
&lt;/h3&gt;

&lt;p&gt;I thought the challenging parts would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Getting good transcriptions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Optimizing content for SEO&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fine-tuning prompts&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Actually challenging parts:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;File upload and processing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Background job orchestration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User experience for async operations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Error handling and retries&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Infrastructure costs and scaling&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Local Development Can Be Misleading
&lt;/h3&gt;

&lt;p&gt;Everything worked perfectly on my MacBook Pro. But production environments have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Stricter resource limits&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Network latency&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Timeout constraints&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Different error conditions&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Test in production-like environments early and often.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔮 What I'm Building Next
&lt;/h2&gt;

&lt;p&gt;I'm currently rebuilding the entire app with background jobs as a first-class citizen:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;New tech stack:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Frontend:&lt;/strong&gt; Still Next.js, but with real-time progress indicators&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Background jobs:&lt;/strong&gt; Inngest for orchestration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Database:&lt;/strong&gt; Adding Supabase for job status tracking&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;File storage:&lt;/strong&gt; Moving to Cloudinary for better video handling&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Notifications:&lt;/strong&gt; WebSocket connections for real-time updates&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Timeline reality check:&lt;/strong&gt; What I thought would be a 2-week project is now a 3-month learning journey. And honestly? I'm more excited about it now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Other technologies I discovered:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Langchain &amp;amp; Langraph:&lt;/strong&gt; For more complex AI workflows&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Redis:&lt;/strong&gt; For caching and session management&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;WebSocket/Server-sent events:&lt;/strong&gt; For real-time progress updates&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Queue monitoring tools:&lt;/strong&gt; For debugging background jobs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  💭 Advice for Other Developers
&lt;/h2&gt;

&lt;p&gt;If you're building AI-powered apps, here's what I wish someone had told me:&lt;/p&gt;

&lt;h3&gt;
  
  
  Plan for Async from Day One
&lt;/h3&gt;

&lt;p&gt;Don't build a synchronous AI app and try to make it async later. Design your user experience around the fact that AI processing takes time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Show progress indicators&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Send email/push notifications when jobs complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Let users check status later&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handle failures gracefully&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Research Your Platform's Limits
&lt;/h3&gt;

&lt;p&gt;Before you write any code, understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Function timeout limits&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Memory constraints&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;File size restrictions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pricing for overages&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Start with Background Jobs
&lt;/h3&gt;

&lt;p&gt;Even if your AI processing is currently fast, it will get slower as you add features. Background jobs give you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Better user experience&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Easier scaling&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Retry mechanisms&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Progress tracking&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Infrastructure Is Harder Than AI
&lt;/h3&gt;

&lt;p&gt;Getting good results from OpenAI's APIs is pretty straightforward. Getting those results reliably delivered to users in production? That's the real challenge.&lt;/p&gt;

&lt;h3&gt;
  
  
  It's Totally Normal
&lt;/h3&gt;

&lt;p&gt;If you're struggling with infrastructure for AI apps, you're not alone. Every AI developer goes through this learning curve. The AI part is often the easy part.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What about you?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Have you hit similar serverless limitations while building AI apps? What solutions did you find?&lt;/p&gt;

&lt;p&gt;Are you currently building something with AI? What infrastructure challenges are you facing?&lt;/p&gt;

&lt;p&gt;Drop a comment below - I'd love to hear about your experiences and maybe we can help each other avoid these pitfalls!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Currently rebuilding this app the right way. Follow my journey as I document everything I learn about building production-ready AI applications.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>openai</category>
      <category>vercel</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
