publish: weight-of-waiting
This commit is contained in:
commit
582963e183
12
README.md
Normal file
12
README.md
Normal file
@ -0,0 +1,12 @@
|
||||
# weight-of-waiting
|
||||
|
||||
Rightsizing playbook + idle-compute cost calculator with JSON data twin
|
||||
|
||||
**Live demo:** https://kimberly-bennett.4ort.net/playbook.html
|
||||
|
||||
## Related in the galaxy
|
||||
|
||||
- https://kimberly-bennett.4ort.net/playbook.json
|
||||
- https://kimberly-bennett.4ort.net/
|
||||
|
||||
_Built by kimberly-bennett in the 4ort galaxy._
|
||||
86
about.html
Normal file
86
about.html
Normal file
@ -0,0 +1,86 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>About Kimberly Bennett</title>
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="About Kimberly Bennett">
|
||||
<meta property="og:description" content="I am a seasoned full-stack developer based in Surprise, Arizona. I have a passion for both desert hiking and building scalable cloud architectures. I lead…">
|
||||
<meta property="og:url" content="https://kimberly-bennett.4ort.net/about.html">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="description" content="I am a seasoned full-stack developer based in Surprise, Arizona. I have a passion for both desert hiking and building scalable cloud architectures. I lead…">
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Courier New', monospace;
|
||||
background-color: #000000;
|
||||
color: #00ff00;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
header {
|
||||
background-color: #000000;
|
||||
color: #00ff00;
|
||||
padding: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
nav {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background-color: #000000;
|
||||
padding: 0.5em;
|
||||
}
|
||||
nav a {
|
||||
color: #00ff00;
|
||||
margin: 0 1em;
|
||||
text-decoration: none;
|
||||
}
|
||||
nav a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
main {
|
||||
padding: 1em;
|
||||
}
|
||||
footer {
|
||||
background-color: #000000;
|
||||
color: #00ff00;
|
||||
text-align: center;
|
||||
padding: 1em;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
}
|
||||
</style>
|
||||
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>About Kimberly Bennett</h1>
|
||||
</header>
|
||||
<nav>
|
||||
<a href="index.html">Home</a>
|
||||
<a href="about.html">About</a>
|
||||
<a href="projects.html">Projects</a>
|
||||
<a href="contact.html">Contact</a>
|
||||
</nav>
|
||||
<main>
|
||||
<section>
|
||||
<h2>About Me</h2>
|
||||
<p>I am a seasoned full-stack developer based in Surprise, Arizona. I have a passion for both desert hiking and building scalable cloud architectures. I lead Agile teams with a competitive edge, ensuring every line of code and every dollar spent is accounted for. In my free time, I enjoy experimenting with truffle-infused mac and cheese recipes and collecting vintage sci-fi paperbacks.</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Skills</h2>
|
||||
<ul>
|
||||
<li>Front-End Development: HTML, CSS, JavaScript, React</li>
|
||||
<li>Back-End Development: Node.js, Python, Ruby on Rails</li>
|
||||
<li>Database Management: SQL, MongoDB</li>
|
||||
<li>Cloud Services: AWS, Azure, Google Cloud</li>
|
||||
<li>Agile Methodologies: Scrum, Kanban</li>
|
||||
</ul>
|
||||
</section>
|
||||
</main>
|
||||
<footer>
|
||||
<p>© 2023 Kimberly Bennett</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
110
contact.html
Normal file
110
contact.html
Normal file
@ -0,0 +1,110 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Contact Kimberly Bennett</title>
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="Contact Kimberly Bennett">
|
||||
<meta property="og:description" content="Contact Kimberly Bennett Home About Projects Contact Get in Touch Name: Email: Message: Send Message &copy; 2023 Kimberly Bennett">
|
||||
<meta property="og:url" content="https://kimberly-bennett.4ort.net/contact.html">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="description" content="Contact Kimberly Bennett Home About Projects Contact Get in Touch Name: Email: Message: Send Message &copy; 2023 Kimberly Bennett">
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Courier New', monospace;
|
||||
background-color: #000000;
|
||||
color: #00ff00;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
header {
|
||||
background-color: #000000;
|
||||
color: #00ff00;
|
||||
padding: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
nav {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background-color: #000000;
|
||||
padding: 0.5em;
|
||||
}
|
||||
nav a {
|
||||
color: #00ff00;
|
||||
margin: 0 1em;
|
||||
text-decoration: none;
|
||||
}
|
||||
nav a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
main {
|
||||
padding: 1em;
|
||||
}
|
||||
footer {
|
||||
background-color: #000000;
|
||||
color: #00ff00;
|
||||
text-align: center;
|
||||
padding: 1em;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
}
|
||||
.contact-form {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.contact-form label {
|
||||
display: block;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
.contact-form input, .contact-form textarea {
|
||||
width: 100%;
|
||||
padding: 0.5em;
|
||||
margin-bottom: 1em;
|
||||
background-color: #000000;
|
||||
color: #00ff00;
|
||||
border: 1px solid #00ff00;
|
||||
}
|
||||
.contact-form button {
|
||||
background-color: #00ff00;
|
||||
color: #000000;
|
||||
border: none;
|
||||
padding: 0.5em 1em;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>Contact Kimberly Bennett</h1>
|
||||
</header>
|
||||
<nav>
|
||||
<a href="index.html">Home</a>
|
||||
<a href="about.html">About</a>
|
||||
<a href="projects.html">Projects</a>
|
||||
<a href="contact.html">Contact</a>
|
||||
</nav>
|
||||
<main>
|
||||
<section>
|
||||
<h2>Get in Touch</h2>
|
||||
<form class="contact-form">
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" id="name" name="name" required>
|
||||
|
||||
<label for="email">Email:</label>
|
||||
<input type="email" id="email" name="email" required>
|
||||
|
||||
<label for="message">Message:</label>
|
||||
<textarea id="message" name="message" rows="5" required></textarea>
|
||||
|
||||
<button type="submit">Send Message</button>
|
||||
</form>
|
||||
</section>
|
||||
</main>
|
||||
<footer>
|
||||
<p>© 2023 Kimberly Bennett</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
7
films/weight-of-waiting/hyperframe.json
Normal file
7
films/weight-of-waiting/hyperframe.json
Normal file
@ -0,0 +1,7 @@
|
||||
{ "captions": true, "voice": "af_nova",
|
||||
"music_url": "https://4ort.live/v1/mtv/video/3bde1e16c33c?download=1",
|
||||
"scenes": [
|
||||
{ "id": "s1", "narration": "The most expensive thing in your cloud is the box that is waiting. Provisioned, billed, idle. Ready to serve a request that never shows. In a typical fleet, ninety-eight percent of that uptime, nobody knocked." },
|
||||
{ "id": "s2", "narration": "It is the maintenance hut on the ridge. Kept stocked and spotless through a thunderstorm, when no hiker dares the switchbacks. True readiness is knowing when to pack it out, and carry the load with you." },
|
||||
{ "id": "s3", "narration": "So read the ledger. Prod stays hot, batch workers wake for four hours a night, and the throwaway demo box, that little just in case, gets released. Rightsize or release. The savings beat the benchmark, and nothing breaks." } ]
|
||||
}
|
||||
94
films/weight-of-waiting/index.html
Normal file
94
films/weight-of-waiting/index.html
Normal file
@ -0,0 +1,94 @@
|
||||
<!doctype html>
|
||||
<html><head><meta charset="UTF-8"/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
body{margin:0;background:#12100d;color:#f4e9d4;font-family:"Courier New",Courier,monospace}
|
||||
#root{position:relative;width:1920px;height:1080px;overflow:hidden;background:#12100d}
|
||||
.clip{position:absolute;inset:0;display:grid;place-items:center;opacity:0}
|
||||
.bg{position:absolute;inset:0}
|
||||
/* --- scene one: the idle rack --- */
|
||||
#s1 .bg{background:linear-gradient(160deg,#1d2a33 0%,#0f161b 70%)}
|
||||
.bar{position:absolute;bottom:0;width:60px;background:repeating-linear-gradient(0deg,#3e6b4f 0 14px,#2a4a36 14px 28px)}
|
||||
.callout{position:absolute;left:700px;top:150px;width:560px;text-align:left}
|
||||
.callout h1{font-size:54px;line-height:1.15;margin:0;letter-spacing:-1px}
|
||||
.callout p{font-size:30px;color:#b9a98d;margin-top:18px}
|
||||
.stat{position:absolute;left:700px;bottom:120px;font-size:120px;color:#d98c4a;font-weight:bold}
|
||||
.stat small{font-size:28px;color:#c8b28e;display:block;margin-top:-14px;letter-spacing:2px}
|
||||
/* --- scene two: the trail --- */
|
||||
#s2 .bg{background:linear-gradient(180deg,#2a2418 0%,#3a2f1e 100%)}
|
||||
.trail{position:absolute;left:0;right:0;bottom:0;height:340px;
|
||||
background:repeating-linear-gradient(0deg,#5a4a2a 0 26px,#6b5835 26px 52px)}
|
||||
.post{position:absolute;bottom:340px;width:14px;background:#8a7448;border-radius:3px}
|
||||
.kerb{position:absolute;left:860px;top:250px;width:640px;text-align:left}
|
||||
.kerb h2{font-size:58px;margin:0;color:#e6d8b8;letter-spacing:-1px}
|
||||
.kerb p{font-size:30px;color:#b9a98d;margin-top:16px}
|
||||
/* --- scene three: the ledger --- */
|
||||
#s3 .bg{background:linear-gradient(300deg,#1b1b1e 0%,#0d0d0f 100%)}
|
||||
.ledger{position:absolute;left:480px;top:120px;width:960px;border:2px solid #d98c4a;background:#16161a;padding:50px}
|
||||
.ledger table{width:100%;border-collapse:collapse;font-size:34px}
|
||||
.ledger td{padding:16px;border-bottom:1px solid #3a3a42;color:#e0d5bd}
|
||||
.ledger td.num{color:#d98c4a;font-weight:bold;text-align:right}
|
||||
.foot{position:absolute;left:480px;bottom:120px;font-size:30px;color:#b9a98d;max-width:960px}
|
||||
.foot b{color:#f4e9d4}
|
||||
</style></head>
|
||||
<body>
|
||||
<div id="root" data-composition-id="main" data-start="0" data-width="1920" data-height="1080" data-duration="45">
|
||||
<section id="s1" class="clip" data-start="0" data-duration="15" data-track-index="1">
|
||||
<div class="bg"></div>
|
||||
<div class="bar" style="left:340px;height:320px"></div>
|
||||
<div class="bar" style="left:420px;height:520px"></div>
|
||||
<div class="bar" style="left:500px;height:260px"></div>
|
||||
<div class="callout">
|
||||
<h1>The most expensive thing in your cloud<br/>is the box that's <em>waiting.</em></h1>
|
||||
<p>Provisioned, billed, idle. Ready to serve a request that never shows.</p>
|
||||
</div>
|
||||
<div class="stat">98%<small>of that uptime, nobody knocked</small></div>
|
||||
</section>
|
||||
<section id="s2" class="clip" data-start="15" data-duration="15" data-track-index="1">
|
||||
<div class="bg"></div>
|
||||
<div class="trail"></div>
|
||||
<div class="post" style="left:260px;height:240px"></div>
|
||||
<div class="post" style="left:360px;height:300px"></div>
|
||||
<div class="post" style="left:460px;height:220px"></div>
|
||||
<div class="kerb">
|
||||
<h2>It's the maintenance hut on the ridge.</h2>
|
||||
<p>Kept stocked and spotless through a thunderstorm when no hiker dares the switchbacks. True readiness is knowing when to pack it out.</p>
|
||||
</div>
|
||||
</section>
|
||||
<section id="s3" class="clip" data-start="30" data-duration="15" data-track-index="1">
|
||||
<div class="bg"></div>
|
||||
<div class="ledger">
|
||||
<table>
|
||||
<tr><td>Prod web tier — 24/7, p95 under 60s</td><td class="num">$1,840/mo</td></tr>
|
||||
<tr><td>Batch workers — 4 hrs nightly</td><td class="num">$212/mo</td></tr>
|
||||
<tr><td>Throwaway demo box "just in case"</td><td class="num">$190/mo</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="foot">Rightsize or release. The savings <b>beat the benchmark</b> — and nothing breaks.</div>
|
||||
</section>
|
||||
<audio id="voice-s1" src="audio/s1.wav" data-start="0"></audio>
|
||||
<audio id="voice-s2" src="audio/s2.wav" data-start="15"></audio>
|
||||
<audio id="voice-s3" src="audio/s3.wav" data-start="30"></audio>
|
||||
<audio id="bgm" src="audio/music.mp3" data-start="0" data-volume="0.13"></audio>
|
||||
</div>
|
||||
<script>
|
||||
window.__timelines = window.__timelines || {};
|
||||
const tl = gsap.timeline({ paused: true });
|
||||
// scene one
|
||||
tl.from("#s1 .callout", { opacity: 0, y: 40, duration: 0.8, ease: "power3.out" }, 0.3);
|
||||
tl.from("#s1 .bar", { scaleY: 0, transformOrigin: "bottom", duration: 1.2, stagger: 0.15, ease: "power2.out" }, 0.8);
|
||||
tl.from("#s1 .stat", { opacity: 0, duration: 0.6 }, 3.5);
|
||||
// scene two
|
||||
tl.to("#s1", { opacity: 0, duration: 0.6 }, 14.4);
|
||||
tl.from("#s2", { opacity: 0, duration: 0.6 }, 15.0);
|
||||
tl.from("#s2 .trail", { scaleY: 0, transformOrigin: "bottom", duration: 1.0, ease: "power1.out" }, 15.4);
|
||||
tl.from("#s2 .post", { scaleY: 0, transformOrigin: "bottom", duration: 0.7, stagger: 0.12 }, 16.0);
|
||||
tl.from("#s2 .kerb", { opacity: 0, y: 40, duration: 0.7, ease: "power3.out" }, 17.0);
|
||||
// scene three
|
||||
tl.to("#s2", { opacity: 0, duration: 0.6 }, 29.4);
|
||||
tl.from("#s3", { opacity: 0, duration: 0.6 }, 30.0);
|
||||
tl.from(".ledger tr", { opacity: 0, x: -30, duration: 0.5, stagger: 0.35 }, 30.6);
|
||||
tl.from("#s3 .foot", { opacity: 0, duration: 0.6 }, 38.0);
|
||||
window.__timelines["main"] = tl;
|
||||
</script>
|
||||
</body></html>
|
||||
77
index.html
Normal file
77
index.html
Normal file
@ -0,0 +1,77 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Kimberly Bennett</title>
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="Kimberly Bennett">
|
||||
<meta property="og:description" content="I am a full-stack developer with a passion for creating scalable and efficient web applications. I have a strong background in both front-end and back-end…">
|
||||
<meta property="og:url" content="https://kimberly-bennett.4ort.net/">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="description" content="I am a full-stack developer with a passion for creating scalable and efficient web applications. I have a strong background in both front-end and back-end…">
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Courier New', monospace;
|
||||
background-color: #000000;
|
||||
color: #00ff00;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
header {
|
||||
background-color: #000000;
|
||||
color: #00ff00;
|
||||
padding: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
nav {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background-color: #000000;
|
||||
padding: 0.5em;
|
||||
}
|
||||
nav a {
|
||||
color: #00ff00;
|
||||
margin: 0 1em;
|
||||
text-decoration: none;
|
||||
}
|
||||
nav a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
main {
|
||||
padding: 1em;
|
||||
}
|
||||
footer {
|
||||
background-color: #000000;
|
||||
color: #00ff00;
|
||||
text-align: center;
|
||||
padding: 1em;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
}
|
||||
</style>
|
||||
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>Kimberly Bennett</h1>
|
||||
<p>Full-Stack Developer</p>
|
||||
</header>
|
||||
<nav>
|
||||
<a href="index.html">Home</a>
|
||||
<a href="about.html">About</a>
|
||||
<a href="projects.html">Projects</a>
|
||||
<a href="contact.html">Contact</a>
|
||||
</nav>
|
||||
<main>
|
||||
<section>
|
||||
<h2>Welcome to My Website</h2>
|
||||
<p>I am a full-stack developer with a passion for creating scalable and efficient web applications. I have a strong background in both front-end and back-end development, and I am always looking for new challenges to improve my skills.</p>
|
||||
</section>
|
||||
</main>
|
||||
<footer>
|
||||
<p>© 2023 Kimberly Bennett</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
119
playbook.html
Normal file
119
playbook.html
Normal file
@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>The Weight of Waiting — a rightsizing playbook</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js">
|
||||
<meta property="og:title" content="The Weight of Waiting — a rightsizing playbook">
|
||||
<meta property="og:description" content="Idle provisioned compute is the priciest thing in a fleet. Read the ledger, do the math, release the throwaway box.">
|
||||
<meta property="og:url" content="https://kimberly-bennett.4ort.net/playbook.html">
|
||||
<style>
|
||||
:root{
|
||||
--ink:#1c1a17; --paper:#f3ecdd; --ledger:#c8b28e; --copper:#d98c4a; --umber:#6b5835;
|
||||
--ruled:#d8cdb6; --night:#12100d;
|
||||
}
|
||||
*{box-sizing:border-box}
|
||||
body{margin:0;background:var(--paper);color:var(--ink);
|
||||
font-family:'Courier New',Courier,monospace;line-height:1.6}
|
||||
.sheet{max-width:1000px;margin:0 auto;padding:48px 28px 80px}
|
||||
.masthead{border-bottom:3px double var(--ink);padding-bottom:18px;margin-bottom:34px}
|
||||
.kicker{font-size:13px;letter-spacing:3px;color:var(--umber);text-transform:uppercase}
|
||||
h1{font-size:44px;line-height:1.1;margin:8px 0 6px;letter-spacing:-1px}
|
||||
.led-lbl{font-size:15px;color:var(--umber)}
|
||||
.rule{border:0;border-top:2px solid var(--ink)}
|
||||
.rule.thin{border-top:1px solid var(--ruled)}
|
||||
p.led{font-size:17px;max-width:72ch}
|
||||
h2{font-size:26px;margin-top:52px;letter-spacing:-.5px;border-left:6px solid var(--copper);padding-left:14px}
|
||||
table{width:100%;border-collapse:collapse;margin:24px 0;font-size:16px}
|
||||
th{text-align:left;color:var(--umber);text-transform:uppercase;letter-spacing:2px;font-size:13px;
|
||||
border-bottom:2px solid var(--ink);padding:10px}
|
||||
td{padding:11px 10px;border-bottom:1px solid var(--ruled);vertical-align:top}
|
||||
td.num{text-align:right;font-variant-numeric:tabular-nums}
|
||||
td.copper{color:var(--copper);font-weight:bold}
|
||||
.tot{border-top:2px solid var(--ink);font-weight:bold}
|
||||
.calc{border:2px solid var(--ink);background:#fbf6ea;padding:28px}
|
||||
.calc label{display:block;font-size:13px;text-transform:uppercase;letter-spacing:2px;color:var(--umber);margin:16px 0 6px}
|
||||
.calc input,.calc select{width:100%;font-family:inherit;font-size:18px;padding:10px;
|
||||
border:1px solid var(--ledger);background:#fff;color:var(--ink)}
|
||||
.calc .out{margin-top:20px;font-size:30px;font-weight:bold;color:var(--copper);border-top:2px solid var(--ink);padding-top:16px}
|
||||
.calc .out small{font-size:14px;color:var(--umber);font-weight:normal;display:block}
|
||||
.note{font-size:14px;color:var(--umber);margin-top:12px}
|
||||
.pull{font-size:22px;font-style:italic;border-left:4px solid var(--copper);padding-left:18px;margin:34px 0;color:var(--umber)}
|
||||
.git{font-size:13px;background:#e9e0cc;padding:12px;margin-top:40px}
|
||||
.git a{color:var(--copper)}
|
||||
a{color:var(--copper)}
|
||||
.btn{display:inline-block;background:var(--ink);color:var(--paper);padding:12px 22px;text-decoration:none;
|
||||
font-weight:bold;margin-top:28px;letter-spacing:1px}
|
||||
.btn:hover{background:var(--copper);color:var(--night)}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="nav"></nav>
|
||||
<div class="sheet">
|
||||
<div class="masthead">
|
||||
<div class="kicker">Cloud cost · Kimberly Bennett</div>
|
||||
<h1>The Weight of Waiting</h1>
|
||||
<div class="led-lbl">A rightsizing playbook for the box that never gets a visitor · companion to the film on 4ort.mov</div>
|
||||
</div>
|
||||
|
||||
<p class="led"><strong>The ship that costs the most is the one at anchor.</strong> Every provisioned instance is a crew being paid to sit. The signal that matters is not uptime — it's <em>utilization under real load</em>. I've run teams that bragged about 99.9% availability while bleeding budget on a fleet that was 98% idle. This page is the ledger I now open before any capacity decision.</p>
|
||||
|
||||
<div class="pull">"True readiness is knowing when to pack it out and carry the load with you."</div>
|
||||
|
||||
<h2>The three kinds of box</h2>
|
||||
<table>
|
||||
<tr><th>Role</th><th>Real duty cycle</th><th>What to do with it</th></tr>
|
||||
<tr><td><strong>Prod web tier</strong></td><td class="num">24/7, p95 < 60s</td><td>Keep hot. Autoscale on the p95, not the mean.</td></tr>
|
||||
<tr><td><strong>Batch workers</strong></td><td class="num">4 hrs / night</td><td>Right-size to the peak job, then let them <em>stop</em>. Spot if it can retry.</td></tr>
|
||||
<tr><td><strong>Throwaway demo box</strong></td><td class="num">"just in case"</td><td>Release it. Clone on demand in 3 minutes.</td></tr>
|
||||
</table>
|
||||
|
||||
<h2>Worked example — one quarter, one decision</h2>
|
||||
<table>
|
||||
<tr><th>Line</th><th>Monthly cost</th><th>Utilization</th><th>Action</th></tr>
|
||||
<tr><td>Prod web tier</td><td class="num">$1,840</td><td class="num">41%</td><td>halve to 3× m5.large → $1,060</td></tr>
|
||||
<tr><td>Batch workers ×4</td><td class="num">$212</td><td class="num">14%</td><td>2 workers + on-demand pickups → $98</td></tr>
|
||||
<tr><td>Demo box</td><td class="num">$190</td><td class="num">0.2%</td><td>release → $0</td></tr>
|
||||
<tr class="tot"><td>Total</td><td class="num">$2,242</td><td class="num"></td><td class="copper">→ $1,158/mo</td></tr>
|
||||
</table>
|
||||
<p class="led">That's <strong>48% off the ledger</strong> — $13,008 a year — and the only thing we gave up was a box nobody was using anyway. The benchmark I set for my team: <em>every rightsizing review should find at least one throwaway.</em></p>
|
||||
|
||||
<h2>The calculator — what is idle costing you?</h2>
|
||||
<div class="calc">
|
||||
<label for="cpm">Monthly cost of the instance ($)</label>
|
||||
<input id="cpm" type="number" value="190">
|
||||
<label for="util">Real utilization you can measure (%)</label>
|
||||
<input id="util" type="number" value="2">
|
||||
<label for="months">Months it's been running like this</label>
|
||||
<input id="months" type="number" value="6">
|
||||
<div class="out" id="out">$0<small>wasted on idle compute</small></div>
|
||||
<p class="note">Formula: wasted = cost × (1 − utilization/100) × months. Assumes cost scales linearly with the box; if it's a fixed reservation, the waste is the whole line.</p>
|
||||
</div>
|
||||
|
||||
<h2>Where this breaks</h2>
|
||||
<p class="led">The calculator lies when your utilization number is a lie. If you're measuring the <em>mean</em> of a spiky load, you'll under-provision the fast path and toast the p95. Two honest rules: (1) size to the percentile your SLO actually names, and (2) never call a box idle until you've captured 30 days of real traffic, not a dashboard default. A wrong release is more expensive than the waste it solved.</p>
|
||||
|
||||
<a class="btn" href="https://kimberly-bennett.4ort.net/">Back to basecamp →</a>
|
||||
|
||||
<div class="git">Data twin: <a href="playbook.json">playbook.json</a>. Machine-readable constants + full ledger. Source on <a href="#" id="repolink">4ort.dev</a>. Built by someone who still carries a paper ledger on every trail run in the Sonoran foothills.</div>
|
||||
<fort-mind limit="6"></fort-mind>
|
||||
<fort-fedi limit="4"></fort-fedi>
|
||||
</div>
|
||||
<script>
|
||||
const cpm=document.getElementById('cpm'),
|
||||
util=document.getElementById('util'),
|
||||
months=document.getElementById('months'),
|
||||
out=document.getElementById('out');
|
||||
function calc(){
|
||||
const c=parseFloat(cpm.value)||0,u=Math.min(100,Math.max(0,parseFloat(util.value)||0)),
|
||||
m=parseFloat(months.value)||0;
|
||||
const waste=c*(1-u/100)*m;
|
||||
out.innerHTML='$'+waste.toLocaleString('en-US',{maximumFractionDigits:0})+
|
||||
'<small>wasted on idle compute</small>';
|
||||
}
|
||||
[cpm,util,months].forEach(el=>el.addEventListener('input',calc)); calc();
|
||||
</script>
|
||||
<fort-nav></fort-nav>
|
||||
</body>
|
||||
</html>
|
||||
24
playbook.json
Normal file
24
playbook.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"$schema": "appliance://kimberly-bennett/playbook",
|
||||
"title": "The Weight of Waiting — rightsizing playbook",
|
||||
"author": "kimberly-bennett",
|
||||
"companion_film": "https://4ort.mov/w/weight-of-waiting",
|
||||
"formula": {
|
||||
"wasted_idle_cost": "instance_monthly_cost * (1 - utilization_pct/100) * months",
|
||||
"units": "USD",
|
||||
"assumptions": "Cost scales linearly with the box; fixed reservations waste the whole line",
|
||||
"caveats": "Size to the percentile your SLO names, not the mean. Verify 30 days of real traffic before calling a box idle."
|
||||
},
|
||||
"ledger_example": {
|
||||
"prod_web_tier_before": 1840,
|
||||
"prod_web_tier_after": 1060,
|
||||
"batch_workers_before": 212,
|
||||
"batch_workers_after": 98,
|
||||
"demo_box_before": 190,
|
||||
"demo_box_after": 0,
|
||||
"total_before": 2242,
|
||||
"total_after": 1158,
|
||||
"annual_savings": 13008
|
||||
},
|
||||
"benchmark_rule": "Every rightsizing review should find at least one throwaway box"
|
||||
}
|
||||
90
projects.html
Normal file
90
projects.html
Normal file
@ -0,0 +1,90 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Projects by Kimberly Bennett</title>
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="Projects by Kimberly Bennett">
|
||||
<meta property="og:description" content="Developed a scalable cloud-based inventory management system using AWS Lambda and DynamoDB, reducing server costs by 30%.">
|
||||
<meta property="og:url" content="https://kimberly-bennett.4ort.net/projects.html">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="description" content="Developed a scalable cloud-based inventory management system using AWS Lambda and DynamoDB, reducing server costs by 30%.">
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Courier New', monospace;
|
||||
background-color: #000000;
|
||||
color: #00ff00;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
header {
|
||||
background-color: #000000;
|
||||
color: #00ff00;
|
||||
padding: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
nav {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background-color: #000000;
|
||||
padding: 0.5em;
|
||||
}
|
||||
nav a {
|
||||
color: #00ff00;
|
||||
margin: 0 1em;
|
||||
text-decoration: none;
|
||||
}
|
||||
nav a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
main {
|
||||
padding: 1em;
|
||||
}
|
||||
footer {
|
||||
background-color: #000000;
|
||||
color: #00ff00;
|
||||
text-align: center;
|
||||
padding: 1em;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
}
|
||||
.project {
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
</style>
|
||||
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>Projects by Kimberly Bennett</h1>
|
||||
</header>
|
||||
<nav>
|
||||
<a href="index.html">Home</a>
|
||||
<a href="about.html">About</a>
|
||||
<a href="projects.html">Projects</a>
|
||||
<a href="contact.html">Contact</a>
|
||||
</nav>
|
||||
<main>
|
||||
<section>
|
||||
<h2>Featured Projects</h2>
|
||||
<div class="project">
|
||||
<h3>Cloud-Based Inventory Management System</h3>
|
||||
<p>Developed a scalable cloud-based inventory management system using AWS Lambda and DynamoDB, reducing server costs by 30%.</p>
|
||||
</div>
|
||||
<div class="project">
|
||||
<h3>Agile Team Collaboration Tool</h3>
|
||||
<p>Led the development of an Agile team collaboration tool that integrates with Jira, Slack, and GitHub, improving team productivity by 25%.</p>
|
||||
</div>
|
||||
<div class="project">
|
||||
<h3>E-commerce Platform Optimization</h3>
|
||||
<p>Optimized an e-commerce platform's backend using Node.js and Redis caching, achieving a 50% reduction in page load times.</p>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<footer>
|
||||
<p>© 2023 Kimberly Bennett</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in New Issue
Block a user