<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Aayush Goel — Writing</title>
    <link>https://aayushgoel.dev/blog/</link>
    <atom:link href="https://aayushgoel.dev/feed.xml" rel="self" type="application/rss+xml" />
    <description>Notes on backend systems that have to survive production — ERP integration, messaging infrastructure, and the unglamorous work of making them reliable.</description>
    <language>en</language>
    <managingEditor>mail@aayushgoel.dev (Aayush Goel)</managingEditor>
    <webMaster>mail@aayushgoel.dev (Aayush Goel)</webMaster>
    <lastBuildDate>Thu, 05 Nov 2026 09:00:00 +0530</lastBuildDate>

    <item>
      <title>Elasticsearch was slow because the host was throttling CPU</title>
      <link>https://aayushgoel.dev/blog/latency-in-100ms-steps</link>
      <guid isPermaLink="true">https://aayushgoel.dev/blog/latency-in-100ms-steps</guid>
      <pubDate>Thu, 05 Nov 2026 09:00:00 +0530</pubDate>
      <author>mail@aayushgoel.dev (Aayush Goel)</author>
      <category>Engineering</category>
      <description>I spent a day tuning Elasticsearch queries. The slowdown was CPU throttling from our VPS host, triggered by a Logstash container that had crash-looped 41,687 times.</description>
    </item>

    <item>
      <title>Large exports fail as timeouts before they fail as too big</title>
      <link>https://aayushgoel.dev/blog/too-slow-is-too-big</link>
      <guid isPermaLink="true">https://aayushgoel.dev/blog/too-slow-is-too-big</guid>
      <pubDate>Mon, 26 Oct 2026 09:00:00 +0530</pubDate>
      <author>mail@aayushgoel.dev (Aayush Goel)</author>
      <category>Engineering</category>
      <description>My fallback for large Tally exports waited for a "too big" error. The biggest company never sent one. It timed out at Cloudflare's 120 seconds instead, and the fallback never ran.</description>
    </item>

    <item>
      <title>LLM latency: when the per-call floor is the bottleneck</title>
      <link>https://aayushgoel.dev/blog/the-floor-was-the-call</link>
      <guid isPermaLink="true">https://aayushgoel.dev/blog/the-floor-was-the-call</guid>
      <pubDate>Sat, 24 Oct 2026 09:00:00 +0530</pubDate>
      <author>mail@aayushgoel.dev (Aayush Goel)</author>
      <category>Engineering</category>
      <description>An LLM classifier took three seconds to answer even "confirm". Shrinking the output barely helped, because the model's fixed per-call cost was the floor. A faster model was right there, and I still didn't take it.</description>
    </item>

    <item>
      <title>Multi-agent LLM system in production: 3 human approval gates</title>
      <link>https://aayushgoel.dev/blog/five-agents-three-approval-gates</link>
      <guid isPermaLink="true">https://aayushgoel.dev/blog/five-agents-three-approval-gates</guid>
      <pubDate>Tue, 22 Sep 2026 09:00:00 +0530</pubDate>
      <author>mail@aayushgoel.dev (Aayush Goel)</author>
      <category>Engineering</category>
      <description>A multi-agent LLM system that spends real money on ads: every ad created paused, three human approval gates, and every model call logged.</description>
    </item>

    <item>
      <title>WhatsApp chatbot latency: from 10 seconds to 2 in Node.js</title>
      <link>https://aayushgoel.dev/blog/ten-seconds-to-two</link>
      <guid isPermaLink="true">https://aayushgoel.dev/blog/ten-seconds-to-two</guid>
      <pubDate>Tue, 22 Sep 2026 09:00:00 +0530</pubDate>
      <author>mail@aayushgoel.dev (Aayush Goel)</author>
      <category>Engineering</category>
      <description>A WhatsApp chatbot took ten seconds to reply. Twelve serial reads, a blocking typing indicator and an LLM call on the critical path. Getting it to two.</description>
    </item>

    <item>
      <title>Postgres not using your partial index? Why the planner skips it</title>
      <link>https://aayushgoel.dev/blog/the-index-postgres-quietly-stopped-using</link>
      <guid isPermaLink="true">https://aayushgoel.dev/blog/the-index-postgres-quietly-stopped-using</guid>
      <pubDate>Tue, 22 Sep 2026 09:00:00 +0530</pubDate>
      <author>mail@aayushgoel.dev (Aayush Goel)</author>
      <category>Engineering</category>
      <description>A refactor made catalogue search 54% slower at p90. The partial index no longer matched the query, so Postgres quietly skipped it. 281 ms to 29 ms.</description>
    </item>

    <item>
      <title>axios timeout not working? It's socket idle, not a deadline</title>
      <link>https://aayushgoel.dev/blog/your-timeout-is-not-a-timeout</link>
      <guid isPermaLink="true">https://aayushgoel.dev/blog/your-timeout-is-not-a-timeout</guid>
      <pubDate>Tue, 22 Sep 2026 09:00:00 +0530</pubDate>
      <author>mail@aayushgoel.dev (Aayush Goel)</author>
      <category>Engineering</category>
      <description>axios' timeout is a socket-idle timeout, not a deadline. A trickling response never goes idle, so it never fires. Plus a 26 MB parse that outran its own timer.</description>
    </item>

    <item>
      <title>Multi-tenant WhatsApp Cloud API: one number, many stores</title>
      <link>https://aayushgoel.dev/blog/multi-tenant-whatsapp-cloud-api</link>
      <guid isPermaLink="true">https://aayushgoel.dev/blog/multi-tenant-whatsapp-cloud-api</guid>
      <pubDate>Mon, 21 Sep 2026 09:00:00 +0530</pubDate>
      <author>mail@aayushgoel.dev (Aayush Goel)</author>
      <category>Engineering</category>
      <description>One WhatsApp Cloud API number serving many stores: resolving the tenant from a webhook that doesn't name one, and caching it without guessing wrong.</description>
    </item>

    <item>
      <title>Tally XML API with Node.js: a two-way sync that survives retries</title>
      <link>https://aayushgoel.dev/blog/tally-erp-two-way-sync</link>
      <guid isPermaLink="true">https://aayushgoel.dev/blog/tally-erp-two-way-sync</guid>
      <pubDate>Mon, 21 Sep 2026 09:00:00 +0530</pubDate>
      <author>mail@aayushgoel.dev (Aayush Goel)</author>
      <category>Engineering</category>
      <description>Tally has no REST API, answers HTTP 200 on failure, and its documented batching is a no-op. What two generations of sync taught me.</description>
    </item>

  </channel>
</rss>
