<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Jungle Cleaner Blog</title>
    <link>https://junglecleaner.com/blog</link>
    <description>Notes on AWS cost, cleanup, and cutting your bill down to size.</description>
    <atom:link href="https://junglecleaner.com/blog/rss.xml" rel="self" type="application/rss+xml"/>
    <lastBuildDate>Sun, 30 Aug 2026 17:35:28 GMT</lastBuildDate>
    <item>
      <title>Don&apos;t be naive about AWS cost tools</title>
      <link>https://junglecleaner.com/blog/dont-expect-anything-than-bare-minimum-from-aws</link>
      <guid isPermaLink="true">https://junglecleaner.com/blog/dont-expect-anything-than-bare-minimum-from-aws</guid>
      <pubDate>Sun, 30 Aug 2026 12:00:00 GMT</pubDate>
      <description>AWS cost tools are off by default, take days to fill, and mostly sell Savings Plans. Don&apos;t expect Amazon to do more than the bare minimum on your bill.</description>
      <content:encoded><![CDATA[<p>When you talk to people about saving money on your AWS bill, often the knee-jerk reaction is to refer you to AWS tools like AWS Cost Optimization Hub and leave it at that. But do you really expect AWS to do everything in their power to help you save money? Obviously there is a clear conflict of interest here. AWS wants to look like the good guy, but at the end of the day they&#39;re going to do the bare minimum to save you money.</p>
<h2>Getting the AWS services configured</h2>
<p>Perhaps this is just AWS being AWS, but if you want to get the information you need to help you save you money, there are a few hoops you have to jump through. First you need to turn on AWS Cost Optimization Hub and AWS Compute Optimizer, because by default they are turned off. For small companies and individual builders, nine times out of ten you&#39;re not even going to be thinking about saving a few dollars here and or there, even if it would be pretty trivial, so most people don&#39;t bother turning them on.</p>
<p>Then you need to let the results trickle through which can take a day or two. So, again, even if you get around to turning them on, you might forget to go and check the results, because you&#39;re too busy trying to ship your next feature.</p>
<h2>Making sense of the data</h2>
<p>The AWS Compute Optimizer web UI is fairly easy to get to grips with, and while the recommendations it finds should definitely be actioned, do not expect them to be exhaustive. For example, only in June of 2026 did they add <a href="https://aws.amazon.com/blogs/aws-cloud-financial-management/announcing-six-new-idle-resource-recommendations-in-aws-compute-optimizer/">six new idle findings</a>, but obviously those findings existed for years, if not decades in some cases.</p>
<p>The Web UI for the Cost Optimization Hub and other AWS savings related interfaces like the recommendations in the Billing and Cost Management section I have always found to be a bit of a disaster, and the major focus is on trying to sell you saving plans, because surprise surprise, AWS wants to make money from you.</p>
<p>You might save money with the savings plan, but it also locks you in to a fixed spending pattern with AWS for a fixed amount of time. This then removes the incentive for you to optimize your workload: if you just bought ec2 5 instances for the next 2 years, whats the point of optimizing your setup so you only need 2 instances?</p>
<h2>When you should use savings plans</h2>
<p>You should only use saving plans when you&#39;re platform is mature enough that you know you&#39;re not going to be touching it, and you&#39;ve already exhausted all the optimization that you feel is worthwhile investing in. So for people building stuff on their own and small companies, I generally wouldn&#39;t recommend it, because almost certainly there&#39;s a better way to save money than using the savings plan. The first focus should always be optimizing your setup.</p>
<h2>Why you should use a non-AWS tool</h2>
<p>The reason you should rely on another company (not AWS) to help you save money with AWS is simple: your interests align. If the third party can save you money, then both of you are happy, whereas AWS really doesn&#39;t give much of a shit if they can save you money or not.</p>
<p>I built <a href="https://junglecleaner.com">Jungle Cleaner</a> to be a simple MCP-first tool to help you optimize your AWS setup, but there&#39;s lots of other companies out there that also do a much better job than AWS, so take your pick! Just don&#39;t expect AWS to break a sweat trying to lower your bill.</p>

]]></content:encoded>
    </item>
    <item>
      <title>OpenSearch Serverless NextGen: What&apos;s New, and How to Migrate from Classic</title>
      <link>https://junglecleaner.com/blog/opensearch-classic-to-nextgen-migration</link>
      <guid isPermaLink="true">https://junglecleaner.com/blog/opensearch-classic-to-nextgen-migration</guid>
      <pubDate>Wed, 08 Jul 2026 12:00:00 GMT</pubDate>
      <description>What actually changed in OpenSearch Serverless NextGen versus Classic, why it matters for cost, and how to migrate a collection without AWS-managed tooling.</description>
      <content:encoded><![CDATA[<p>AWS has rolled out a new generation of OpenSearch Serverless. If you&#39;re currently on Classic collections, it&#39;s worth understanding what&#39;s actually changed before deciding whether — and how — to move.</p>
<h2>The problem with Classic</h2>
<p>OpenSearch Serverless Classic was a great way to get started with OpenSearch without managing cluster sizing yourself. But it had one expensive catch: the <strong>minimum indexing and search capacity was fixed at 2 OCUs each</strong>, regardless of whether your index was doing anything. (An OCU, or OpenSearch Compute Unit, is the billing unit AWS uses for serverless compute and memory capacity — you&#39;re charged per OCU-hour whether or not it&#39;s actually processing anything.) For an always-on production workload that&#39;s a reasonable floor. For a staging environment, a side project, or anything with bursty or intermittent traffic, you&#39;re paying a constant baseline cost 24/7 for capacity you&#39;re mostly not using.</p>
<h2>What NextGen changes</h2>
<p>The headline feature: <strong>NextGen can scale down to zero</strong>. If nothing&#39;s querying or indexing, you stop paying for that capacity.</p>
<p>There&#39;s a real trade-off to know about before you migrate: scaling up from zero isn&#39;t instant. If your search capacity has scaled to zero, the first request back can see latency in the <strong>tens of seconds</strong> while it spins back up. For dev/staging that&#39;s a non-issue. For production, you&#39;ll want to keep at least <strong>1 unit of search capacity always on</strong> so user-facing queries never hit a cold start — you can still let indexing scale to zero if ingestion is intermittent.</p>
<p>The upside on the scaling side isn&#39;t just the zero floor. AWS reports NextGen scales roughly <strong>20x faster</strong> than Classic, in both directions — it reacts to load spikes faster, and it scales back down faster too, which is what actually turns &quot;can scale to zero&quot; into &quot;spends most of its time at zero&quot; instead of getting stuck at higher capacity from residual traffic.</p>
<p>NextGen also lets you set minimum and maximum capacity independently for indexing and search. So rather than a single fixed floor applying to both, you can, for example, let indexing scale to zero while keeping a minimum of 1 OCU on search — or cap maximum capacity on either side if you want a hard ceiling on cost regardless of load.</p>
<h2>Why this matters for cost</h2>
<p>In short: you&#39;re no longer stuck paying for a fixed floor of 2+2 OCUs whether you need it or not. You pay for roughly what you actually use. That&#39;s most impactful for dev, staging, and any environment with uneven or intermittent traffic — the exact cases where Classic&#39;s fixed minimum was hardest to justify.</p>
<p>Whether this is actually worth doing depends on your traffic pattern, though — a consistently busy production index may not see much of a difference. If you want a quick look at whether you&#39;d see real savings before committing to a migration, you can run the <a href="https://junglecleaner.com">Jungle Cleaner</a> MCP scan tool against your account — it looks at your current OpenSearch Serverless usage and estimates what you&#39;d save by moving to NextGen.</p>
<p><img src="https://junglecleaner.com/blog/opensearch-classic-to-nextgen-migration/jungle-cleaner-scan-screenshot.png" alt="Jungle Cleaner MCP scan running in Claude Code"></p>
<h2>Why the migration isn&#39;t a simple upgrade</h2>
<p>There&#39;s no in-place upgrade path. Collection generation (Classic vs. NextGen) is immutable in OpenSearch Serverless — you can&#39;t flip a setting on an existing collection. You have to:</p>
<ol>
<li>Create a brand-new NextGen collection group, then a collection inside it (with its own access, network, and encryption policies)</li>
<li>Copy your data across</li>
<li>Point your application at the new endpoint</li>
<li>Delete the old Classic collection once you&#39;ve confirmed the cutover worked</li>
</ol>
<p>AWS doesn&#39;t provide a first-party tool for step 2. Their own recommendation for cross-collection copies is to stand up an OpenSearch Ingestion pipeline — which means an IAM role, a data access policy, pipeline YAML, and its own OCU capacity, just for a one-time copy job. That&#39;s a lot of infrastructure for something you&#39;ll run once.</p>
<h2>Setting up the new NextGen group and collection</h2>
<p>We&#39;ve put together a simple example stack — a single Lambda connecting to the index — showing how to provision a NextGen collection with sensible defaults (access policy, network policy, encryption policy): <strong><a href="https://github.com/JungleCleaner/aws-cleanup-scripts/blob/main/infra-examples/opensearch-nextgen.yaml">opensearch-nextgen.yaml</a></strong>. If you&#39;re setting this up with a coding agent, it&#39;s worth pointing it at our template as a guide rather than letting it write the policies from scratch — agents often trip up on NextGen because their training data cuts off before these settings existed, so they&#39;ll confidently reach for Classic-era configuration that doesn&#39;t apply.</p>
<h2>Migrating the data</h2>
<p>Once your NextGen collection exists and is up and running, use our open source migration script to copy everything over:</p>
<p><strong><a href="https://github.com/JungleCleaner/aws-cleanup-scripts/blob/main/migrate-opensearch-classic-to-nextgen.py">migrate-opensearch-classic-to-nextgen.py</a></strong></p>
<p>A few things worth knowing about how it works:</p>
<ul>
<li><strong>No <code>_reindex</code>.</strong> Serverless doesn&#39;t support <code>_reindex</code> with a remote source, so the script copies documents directly — opening a Point-in-Time on the source index, paginating with <code>search_after</code>, and writing batches via <code>_bulk</code>. This is the same fundamental approach an Ingestion pipeline uses under the hood, minus the setup overhead.</li>
<li><strong>It&#39;s idempotent.</strong> Documents are written to the target with their original <code>_id</code>, so re-running the script never creates duplicates — it just overwrites with identical content. This matters in practice: if new data gets written to the old collection while you&#39;re mid-migration, you can point your application at the new collection and then simply run the script again to pick up anything that landed after your first pass.</li>
<li><strong>Mappings and analyzers come across too.</strong> Custom field mappings and analyzers are copied before data, so the target index doesn&#39;t end up with OpenSearch guessing field types via dynamic mapping.</li>
<li><strong>Failures don&#39;t kill the run.</strong> Any document that fails after a retry gets logged to a separate file instead of aborting — one bad document won&#39;t block migrating the other few million.</li>
</ul>
<p>Basic usage:</p>
<pre><code class="language-bash">python3 migrate-opensearch-classic-to-nextgen.py \
  --source-collection-id &lt;classic-collection-id&gt; \
  --target-collection-id &lt;existing-nextgen-collection-id&gt; \
  --region us-east-1
</code></pre>
<p>Add <code>--dry-run</code> first to see index and document counts without copying anything.</p>
<h2>After the migration</h2>
<p>Once you&#39;ve cut your application over to the NextGen endpoint and confirmed traffic is flowing correctly, delete the old Classic collection to stop paying for it:</p>
<pre><code class="language-bash">aws opensearchserverless delete-collection --id &lt;classic-collection-id&gt;
</code></pre>
<p>To help you clean it up, use the <a href="https://junglecleaner.com">Jungle Cleaner</a> MCP cleanup tool, which will identify the exact commands you (or your agent) needs — it verifies the old Classic collection has had no read or write activity since your cutover before suggesting removal, so you&#39;re not deleting anything that&#39;s still quietly in use somewhere.</p>
<p><img src="https://junglecleaner.com/blog/opensearch-classic-to-nextgen-migration/jungle-cleaner-cleanup-screenshot.png" alt="Jungle Cleaner MCP cleanup tool verifying no activity before removal"></p>
<h2>FAQ</h2>
<p><strong>What&#39;s new in OpenSearch Serverless NextGen?</strong>
NextGen can scale indexing and search capacity down to zero, and scales roughly 20x faster than Classic in both directions. Classic had a fixed minimum of 2 OCUs each for indexing and search, regardless of usage.</p>
<p><strong>Can I upgrade a Classic collection to NextGen in place?</strong>
No. Collection generation is immutable — you must create a new NextGen collection and migrate data into it.</p>
<p><strong>Will I lose data during migration?</strong>
Not if you follow the standard cutover order: create the new collection, run the migration script, verify data and application behavior against the new endpoint, and only then delete the old collection.</p>
<p><strong>What happens if search scales to zero in production?</strong>
The first query after a cold start can take tens of seconds to respond. Keep at least 1 unit of search capacity provisioned in production to avoid this; indexing capacity is generally safer to let scale to zero.</p>
<p><strong>Does the migration script support incremental re-runs?</strong>
Yes — it&#39;s idempotent by document ID, so re-running it after cutting over your application catches any writes that happened during the migration window.</p>
<p><strong>How do I install Jungle Cleaner?</strong>
Go to <a href="https://junglecleaner.com">junglecleaner.com</a> and follow the instructions there to install the MCP tool.</p>
]]></content:encoded>
    </item>
    <item>
      <title>AWS Database Savings Plans: Panacea or Pain in the Bum?</title>
      <link>https://junglecleaner.com/blog/database-savings-plans-coverage-gaps</link>
      <guid isPermaLink="true">https://junglecleaner.com/blog/database-savings-plans-coverage-gaps</guid>
      <pubDate>Tue, 31 Mar 2026 12:00:00 GMT</pubDate>
      <description>Database Savings Plans promise up to 35% off across sixteen AWS database services, but coverage is limited to Gen 7+ instances — here are the gaps that shrink your effective discount.</description>
      <content:encoded><![CDATA[<p>AWS announced Database Savings Plans in December 2025 as a panacea to your database spending woes: commit to a fixed hourly dollar figure, and get up to 35% off usage across almost every managed database service you run — Aurora, RDS, DynamoDB, ElastiCache, DocumentDB, Neptune, Keyspaces, Timestream, DMS, and (since March 2026) OpenSearch.</p>
<p>One savings plan, sixteen services, no upfront payment, happy days! That sounds amazing, but unfortunately, you&#39;re gonna be hard pushed to cut 35% — or even 20% — off your database spending, thanks to some sneaky little caveats that Amazon doesn&#39;t make immediately obvious.</p>
<h2>The marketed deal: sixteen services, one simple savings plan</h2>
<p>Open the <a href="https://aws.amazon.com/savingsplans/database-pricing/">Database Savings Plans pricing page</a> and you&#39;ll find usage broken across the services covered by the plan:</p>
<ul>
<li>Aurora and RDS Instances</li>
<li>Aurora Serverless v2</li>
<li>Aurora DSQL</li>
<li>DynamoDB</li>
<li>ElastiCache for Valkey Instances</li>
<li>ElastiCache for Valkey Serverless</li>
<li>Amazon DocumentDB Instances / Serverless</li>
<li>Neptune Instances / Serverless / Analytics</li>
<li>Keyspaces</li>
<li>Timestream</li>
<li>DMS Instances / Serverless</li>
<li>Amazon OpenSearch Service</li>
</ul>
<p>Amazon sells it as a commitment to spending a certain dollar amount per hour for the whole year for all these services. It doesn&#39;t matter if you spin up new databases, spin down old ones, move stuff between services, or switch regions — the saving remains. Unfortunately, the devil&#39;s in the detail, because <em>not everything</em> is covered by the plan, which means it could be that most of your usage is actually excluded!</p>
<h2>The catch: only newer and more expensive instance families</h2>
<p>The pain in the bum that AWS doesn&#39;t advertise is that it only supports <strong>Gen 7 and newer</strong> instance families. Scan the full RDS/Aurora list and you won&#39;t find a single row for:</p>
<ul>
<li><strong>db.t4g</strong> — AWS&#39;s own recommended burstable family for dev/test and small production workloads, and Graviton2-based, not some ancient relic</li>
<li>db.t3 / db.t3g</li>
<li>db.m5 / db.r5</li>
<li>db.m6 / db.r6 (non-Graviton or earlier Graviton generations)</li>
</ul>
<p>There&#39;s also a floor on size, not just generation — no savings for us peasants on the smaller instance types. Scan the eligible Gen 7+ families and the smallest size you&#39;ll find is <code>.large</code>; there&#39;s no <code>.medium</code>, <code>.small</code>, or <code>.micro</code> variant anywhere in the m7g/r7g/m8g/r8g/m9g lineup. If you&#39;re running anything that&#39;s excluded from the plan it will never apply to that instance.</p>
<p>And this isn&#39;t just related to RDS — AWS&#39;s own Savings Plans FAQ states plainly that Database Savings Plans only offer coverage for Generation 7 and newer instances. So the same exclusions apply to DocumentDB, Neptune, OpenSearch, and DMS too. Any usage on those services that&#39;s still pre-Gen-7 gets zero benefit from a Database Savings Plan commitment, just like RDS.</p>
<p>ElastiCache adds an extra restriction on top: coverage is Valkey-only, so even a Gen 7+ Redis OSS or Memcached node doesn&#39;t qualify — you need both the newer generation <em>and</em> the Valkey engine. Timestream has its own narrow scope too, limited to InfluxDB instances specifically.</p>
<p>That last point about T-class is kind of a big deal. T-class instances are how a huge number of teams run dev, staging, QA, and small production databases — precisely the &quot;not core revenue, but still on the AWS bill every month&quot; workloads that make ideal Savings Plan candidates. Under Database Savings Plans, none of that spend is eligible, no matter how large a commitment you buy — and the same logic extends to any pre-Gen-7 instance sitting inside DocumentDB, Neptune, OpenSearch, or DMS.</p>
<h2>Serverless Savings Baby</h2>
<p>The two services that dodge this entirely are DynamoDB and Keyspaces — they&#39;re throughput/capacity-based rather than instance-based, so there&#39;s no &quot;generation&quot; to be excluded from. And every serverless offering gets the same free pass: Aurora Serverless v2, Aurora DSQL, ElastiCache Serverless for Valkey, DocumentDB Serverless, Neptune Serverless, DMS Serverless, and OpenSearch Serverless are all covered from the first hour you spin them up, with no instance-generation check to clear. If your workload lives on any of these, the generational cliff simply doesn&#39;t apply to you.</p>
<h2>Compute Only!</h2>
<p>There&#39;s another caveat here that&#39;s just as easy to miss as the generation cliff: Database Savings Plans only ever discount compute usage. Storage and backup costs sit outside the plan entirely, no matter how eligible the instance sitting next to them is.</p>
<p>That is a big deal because storage and backup can be a big slice of the total — provisioned IOPS on RDS/Aurora, snapshot storage, continuous backups, and for DynamoDB specifically, on-demand storage and backup charges. None of that gets touched by your commitment, even if the compute portion is fully Gen 7+ and otherwise perfectly eligible.</p>
<p>When it comes to DynamoDB, it&#39;s easy to assume &quot;DynamoDB is covered&quot; means the whole bill is covered. It isn&#39;t — only the request/throughput (compute) side gets discounted. Storage and backup keep billing at full price no matter how large a commitment you buy.</p>
<h2>Things to think about before you commit</h2>
<p>Database Savings Plans are a fixed 1-year commitment. There&#39;s no early exit and no ability to reduce it if your workload composition doesn&#39;t match what you assumed. That makes the coverage gap a real financial risk, not a footnote:</p>
<ul>
<li><strong>If your stack is mostly Gen 7+ already</strong>, this is close to a no-brainer — flat 20%+ savings with total flexibility to change instance type, engine, or region without losing the discount.</li>
<li><strong>If you&#39;re spending a lot on t4g, t3, m5, or r5</strong>, that portion gets zero benefit from a Database Savings Plan commitment. You&#39;d either need to upgrade those instances to a Gen 7+ family first (itself a cost change, before any discount applies) or accept that your commitment will be sized against a smaller pool of eligible usage than your total database bill suggests.</li>
<li><strong>There&#39;s no t-class equivalent in the Gen 7+ range</strong> — AWS hasn&#39;t shipped a burstable t7g/t8g/t9g family, so &quot;just upgrade the generation&quot; isn&#39;t a drop-in option here the way it is for Aurora r7g → r8g. Moving off T-class means moving to a non-burstable family entirely, which is a different cost and performance profile, not a like-for-like swap.</li>
<li><strong>If a decent portion of your bill is already spent on the eligible serverless services</strong>, the sizing exercise is much simpler, but baseline only the compute portion of that spend. Strip out storage and backup charges first (DynamoDB storage/backup, snapshot storage, and the like), then find the level your remaining serverless compute usage never drops below, month over month, and commit against that floor.</li>
</ul>
<h2>The practical takeaway</h2>
<p>Before sizing a Database Savings Plan commitment, don&#39;t just total your eligible-sounding database spend from Cost Explorer — cross-reference it against the actual instance types you&#39;re running. A commitment built against your full database bill, without checking generational eligibility first, will systematically overestimate your effective coverage. The gap between &quot;total database spend&quot; and &quot;Database Savings Plan-eligible database spend&quot; is exactly the kind of thing that&#39;s invisible until the first invoice lands with a lower discount than expected.</p>
<p><em>Curious whether your own AWS account has hidden non-eligible instances sitting inside what looks like Database Savings Plan-covered spend? <a href="https://junglecleaner.com">Jungle Cleaner</a> checks for exactly this kind of coverage gap automatically.</em></p>
]]></content:encoded>
    </item>
  </channel>
</rss>
