Finopscraft started because I kept watching the same thing happen at every engineering team I worked with or talked to. The cloud bill would arrive at the end of the month. Someone would forward it to the engineering lead with a raised eyebrow. The engineering lead would spend two hours in Cost Explorer trying to figure out which service caused the overage. They'd find something, fix it, move on. Next month, repeat.
FinOps was a spreadsheet chore. Reactive, manual, disconnected from the engineering workflow where the actual decisions were being made. The tooling either didn't exist for teams at that scale, or it was priced and designed for much larger operations teams. I'm Megan Cho, and in July 2025 I decided to build the thing that should exist.
This is a post-mortem on the first 60 days of building it, written from Dallas in early October 2025, right after we shipped the first working version to a small set of beta users. Here's what we built, what we cut, and what we got wrong.
What the First 60 Days Actually Looked Like
It was two of us for the first month: me handling product, architecture, and frontend; a backend engineer handling data ingestion, the forecast model, and the AWS Cost Explorer API integration. Neither of us had a product manager. Neither of us had external funding. We were working out of a coworking space in Dallas with a very specific constraint: we needed something functional enough to show to beta users within 60 days, or the project would run out of personal runway.
The 60-day clock was real. It wasn't a motivational framing. It was a calendar with a date on it.
We set a single success criterion for day 60: can a new user connect their AWS account, see their current month-to-date spend by service, see a 30-day forecast, and receive a Slack notification when the forecast suggests the month will end 20% above last month? Everything else was a "nice to have" that lived in a Notion backlog we tried very hard to ignore.
The Architecture Decisions We Made in Week One
Some of these were good. Some weren't.
Good: Go for the ingestion layer, Python for the forecast engine. The AWS Cost and Usage Report (CUR) ingestion needs to handle variable-size billing data reliably without eating memory. Go was the right call there. The forecast engine was always going to be iterative data science work, so Python with pandas and statsmodels made sense. The boundary between them is a clean API call. Two months later we haven't had a reason to regret this split.
Good: Normalize the billing data into our own schema immediately on ingest. The CUR format is rich but not easy to work with for forecasting. We normalize to a per-day, per-service, per-tag cost row as the canonical data model. This means the forecast engine never has to know what a CUR file looks like. It made the multi-cloud extension path obvious when we got there.
Bad: Building the tag taxonomy UI in week two. We spent six days building a UI for configuring cost attribution tags. Nobody asked for it. Our first beta users connected their accounts, looked at the forecast, and found the tag UI confusing before they'd even understood what the core product did. We pulled it out of the onboarding flow entirely and hid it in settings. That six days should have been spent on the Slack notification reliability, which actually had a real bug we only found in week seven.
Bad: Our first forecast model was too sophisticated for the problem. We started with a full seasonal ARIMA with automatic parameter selection. It worked, but it took 45 seconds to run on a medium-sized account and the confidence intervals were wide enough to be meaningless for accounts with fewer than 6 months of history. We replaced it with a simpler linear trend plus EWMA for the first version. Accuracy was fine for the use case. We added the full seasonal model back later when we had enough user data to validate it was actually improving results.
What We Shipped on Day 60
The working definition of "version one" on day 60 was:
- AWS Cost Explorer API connection (OAuth2 flow, role-based access, no need for CUR files in v1)
- 30-day rolling cost ingestion at the service + region level
- 28-day forecast with linear trend plus EWMA smoothing
- Month-end projected spend with a percentage-over-last-month indicator
- Slack webhook integration with a configurable percentage threshold alert
- A bare-bones dashboard: current MTD spend by service, forecast line, anomaly flag when a service crossed 2 standard deviations from its 28-day average
What we did not ship: per-team tag attribution, waste detection, multi-cloud support, GCP or Azure connectors, the tag taxonomy UI we built and pulled, rightsize recommendations, savings plan coverage analysis, Jira integration, or any user management beyond a single login per account.
The waste detection list was long. We knew waste detection was a core part of the value proposition from the start. We cut it for v1 because the forecasting loop (connect, ingest, forecast, alert) was the minimum credible demo. You can't demo waste detection without first having the user trust that your underlying spend data is accurate. Forecasting accuracy is visible and testable. We needed to earn that trust first.
The First Beta Feedback: What We Got Wrong
We had five beta users on day 61. Three were engineering leads at growing product companies in the $80K-$200K/month AWS spend range. Two were individual contributors doing FinOps work as part of a broader infrastructure role.
The most consistent piece of feedback was that the forecast confidence interval was not visible enough. Users would look at the forecast line and ask "how sure are you?" We had the statistical uncertainty baked into the model, but the UI was showing a single line rather than a band. We added shaded confidence intervals in week nine and the "how sure are you" questions almost entirely stopped.
The second piece of feedback surprised us more. Two of the five users said the most useful thing in the first week wasn't the forecast at all: it was the anomaly alert that fired when their EC2 spend spiked 180% on a Monday because of a runaway autoscaling event. They'd known about it through CloudWatch alarms, but seeing it surfaced in cost terms ("this anomaly cost you an estimated $340 in the last 24 hours") added a dimension they didn't have before. We hadn't thought of that as the product's headline feature. They had.
What "Bootstrapped" Actually Meant for the Build
We made every infrastructure decision through the lens of "what's the cheapest option that doesn't create technical debt we'll regret?" The answer was usually serverless or managed services where the cost scales with usage, and the cheapest possible database tier that could handle our data model.
We spent zero dollars on marketing in the first 60 days. Beta users came from personal networks and one early post in a FinOps community forum. Our total infrastructure cost to serve five beta accounts was under $80/month. The forecast engine runs on Lambda with a scheduled EventBridge trigger; the ingestion layer is a Lambda behind API Gateway; the data lives in RDS Postgres on the smallest provisioned tier that could handle our query patterns.
We're not saying this is the right architecture forever. We're saying it let us ship fast without committing to scaling costs before we had paying customers. The constraint of bootstrapping is also a forcing function for product focus: you build exactly what you need and nothing else, because there's no budget for anything else.
Where We Are Now
Sixty days after that first ship, waste detection is live. We have a working taxonomy that classifies idle EC2 into orphaned instances, blue-green remnants, standby instances, and scheduling candidates. The tag attribution UI exists and is in the onboarding flow, but much lighter than the original version we built and discarded.
Multi-cloud is the next chunk of work. The internal data model was designed for it from day one, but the connectors for GCP Billing and Azure Cost Management take time to build correctly and test against real accounts. We're expecting that to ship in early 2026.
The 60-day constraint was the best product decision we made, even though it wasn't really a decision. It was just reality. If you're building something and you have unlimited time to add features before shipping, you will. The bill came in. The bill focused everything.