<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[How We Built a Self-Hosted AWS Scheduler to Cut Dev Server Costs by 70%]]></title><description><![CDATA[How We Built a Self-Hosted AWS Scheduler to Cut Dev Server Costs by 70%]]></description><link>https://famirco.hashnode.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1593680282896/kNC7E8IR4.png</url><title>How We Built a Self-Hosted AWS Scheduler to Cut Dev Server Costs by 70%</title><link>https://famirco.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Sun, 20 Sep 2026 12:44:07 GMT</lastBuildDate><atom:link href="https://famirco.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How We Built a Self-Hosted AWS Scheduler to Cut Dev Server Costs by 70%
]]></title><description><![CDATA[Every developer knows the feeling: you spin up an AWS EC2 instance or an RDS database for testing, work on it for a few hours, and then log off. Two weeks later, you check your AWS Billing dashboard o]]></description><link>https://famirco.hashnode.dev/how-we-built-a-self-hosted-aws-scheduler-to-cut-dev-server-costs-by-70</link><guid isPermaLink="true">https://famirco.hashnode.dev/how-we-built-a-self-hosted-aws-scheduler-to-cut-dev-server-costs-by-70</guid><category><![CDATA[Devops]]></category><category><![CDATA[AWS]]></category><category><![CDATA[aws ec2]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[Docker]]></category><category><![CDATA[FastAPI]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Amir Dezyanian]]></dc:creator><pubDate>Sun, 28 Jun 2026 09:22:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a40e3c534d3d11adbe1cb74/8e1929d2-7ada-47a7-902c-cb36c1115266.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every developer knows the feeling: you spin up an AWS EC2 instance or an RDS database for testing, work on it for a few hours, and then log off. Two weeks later, you check your AWS Billing dashboard only to discover that the resource has been running 24/7, racking up hundreds of dollars in idle costs.</p>
<p>In a growing team, this issue scales rapidly. Forgotten staging environments and idle development servers can easily account for 60% to 80% of a company’s cloud computing waste.</p>
<p>To solve this, we looked at the existing solutions:</p>
<ol>
<li><p><strong>AWS Instance Scheduler</strong>: A powerful tool, but setting it up requires complex CloudFormation templates, DynamoDB tables, Lambda configurations, and heavy maintenance.</p>
</li>
<li><p><strong>SaaS Platforms</strong>: These services request extensive IAM permissions to your AWS accounts and charge monthly fees, which defeats the purpose of saving money.</p>
</li>
</ol>
<p>We wanted something simple, lightweight, visual, and secure. That's why we built <strong>CloudNap</strong>—an open-source, self-hosted AWS sleep scheduler that runs inside a single Docker container.</p>
<p>In this article, we'll walk through how it works, its architecture, and how it can help you automate cost optimization.</p>
<hr />
<h2>🛠️ The Architecture of CloudNap</h2>
<p>CloudNap is designed to be low-maintenance and easy to deploy:</p>
<ul>
<li><p><strong>FastAPI Backend (Python)</strong>: Handles REST API routing, manages configuration settings, and communicates with the AWS API using <code>boto3</code>.</p>
</li>
<li><p><strong>State-Based Self-Healing Engine</strong>: Driven by <code>APScheduler</code>, this background worker runs every minute to evaluate and enforce the target power state.</p>
</li>
<li><p><strong>SQLite Database</strong>: A simple, persistent database that stores your resources, sleep schedules, action logs, and manual overrides.</p>
</li>
<li><p><strong>React Frontend SPA (Vite)</strong>: A responsive cost-control dashboard styled using a premium light theme.</p>
</li>
</ul>
<hr />
<h2>🚀 Key Features That Solve Real Cost Problems</h2>
<h3>1. State-Based Self-Healing (Not Event-Based)</h3>
<p>Traditional schedulers often trigger a "stop" command at a specific time (e.g., exactly at 22:00 UTC). If your scheduler is down at that minute, or if a developer manually turns the instance back on at 22:05, the server will run all night.</p>
<p>CloudNap uses a <strong>range-based state evaluation</strong> model. Every minute, the scheduler checks if <code>now</code> falls inside a sleep window. If a developer manually starts an instance during its sleep window without setting an override, CloudNap automatically turns it back off (self-healing) within a minute.</p>
<h3>2. Flexible Sleep Schedules (One-time, Daily, Weekly)</h3>
<p>Developers can configure scheduling rules that fit their workflows:</p>
<ul>
<li><p><strong>One-time Sleep Windows</strong>: Specify a precise start and end date/time (e.g., from Friday 18:00 UTC to Monday 08:00 UTC).</p>
</li>
<li><p><strong>Recurring Sleep Windows</strong>: Configure daily or weekly repeat schedules (e.g., shutdown every day at 22:00, or run only on specific weekdays).</p>
</li>
</ul>
<h3>3. Resource Lease Expiry (TTL)</h3>
<p>When you hand over a server to a developer for a temporary project (e.g., a 2-week sprint), you can configure a <strong>Lease Expiry Date/Time (TTL)</strong>.</p>
<p>Once the lease expires, CloudNap automatically shuts down the instance, locks it in a stopped state, and prevents automated schedules from turning it back on.</p>
<h3>4. Interactive Manual Holds</h3>
<p>If a developer needs to work late, they don't have to delete their schedules. They can simply click <strong>"Stop Instance Manually"</strong> or <strong>"Start Instance Manually"</strong> to apply a state override. CloudNap locks that state and pauses automated schedules until the developer clicks <strong>"Resume Schedule"</strong>.</p>
<h3>5. Slack &amp; Telegram Integrations</h3>
<p>CloudNap sends real-time notifications for every action: schedule creations, manual overrides, and system-initiated shutdowns. You can configure credentials directly on the settings page and use the built-in <strong>"Test Connection"</strong> buttons to verify webhook and telegram bot configurations instantly.</p>
<h3>6. Developer-Friendly Mock Mode</h3>
<p>To encourage open-source contributions and local testing, CloudNap features a full AWS mock mode. By launching with <code>MOCK_AWS=true</code>, the application simulates active AWS instances and state transitions in memory. Developers can run and test the entire project without needing AWS credentials or incurring charges.</p>
<hr />
<h2>⚡ Quick Start: Running CloudNap</h2>
<p>You can launch the entire stack locally in less than 30 seconds using Docker Compose:</p>
<ol>
<li><p><strong>Clone the repository</strong>:</p>
<pre><code class="language-bash">git clone https://github.com/your-username/cloudnap.git
cd cloudnap
</code></pre>
</li>
<li><p><strong>Configure environment variables</strong>: Create a <code>.env</code> file in the <code>backend/</code> directory:</p>
<pre><code class="language-plaintext">MOCK_AWS=true
APP_PASSWORD=secret123
DATABASE_URL=sqlite:///./data/cloudnap.db
</code></pre>
</li>
<li><p><strong>Launch the container</strong>:</p>
<pre><code class="language-plaintext">docker compose up --build -d
</code></pre>
</li>
<li><p>Open <a href="http://localhost:8000">http://localhost:8000</a> and log in with your configured <code>APP_PASSWORD</code>.</p>
</li>
</ol>
<h2><strong>🤝 Open Source &amp; Contributing</strong></h2>
<p>CloudNap is open-source under the MIT License. We welcome pull requests, bug reports, and suggestions.</p>
<p>Check out the repository, star the project if you find it useful, and let us know what features we should build next!</p>
<p>👉 <strong>GitHub Repository</strong>: <a href="https://github.com/famirco/cloudnap">https://github.com/famirco/cloudnap</a></p>
]]></content:encoded></item></channel></rss>