You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit b8da315
Browse filesBrowse the repository at this point in the historyBrowse files
A consumer might have a rate limit of 100 requests per second (prevents overwhelming your API with bursts) and a monthly quota of 10 million requests (prevents consuming resources beyond their plan tier). You need both. The rate limit is infrastructure protection. The quota is cost control.
Request count is universal—every API tracks it. But it's often a poor proxy for cost. A 200-byte health check and a 50MB data export both count as "one request," but their infrastructure impact differs by orders of magnitude. Add data transfer and compute time to capture the actual resource consumption.
55
62
@@ -224,15 +231,22 @@ Double-counting usage events leads to overbilling disputes and customer trust er
224
231
225
232
Quotas answer the question: "How much usage is too much?" But "too much" depends on context. A hard limit that rejects requests prevents runaway costs but creates a poor user experience. A soft limit that allows overages is forgiving but harder to predict financially. You need both, applied at different levels.
226
233
227
-
| Model | Behavior | Use Case |
228
-
|-------|----------|----------|
229
-
| Hard Limit | Reject requests over quota | Prevent runaway costs |
230
-
| Soft Limit | Allow overage, bill extra | Usage-based pricing |
Hard limits are common for free tiers and trial accounts—once you hit the cap, you're done until the next billing period. Soft limits work for paid plans where you want to allow growth but charge for it. Burst allowances let consumers handle legitimate spikes (a batch job that runs monthly) without hitting a hard wall.
238
252
@@ -258,12 +272,19 @@ Figure: Quota enforcement decision flow with soft limits and burst allowance.
258
272
259
273
Rate limiting and quota enforcement solve different problems. Rate limiting is "requests per second"—it protects infrastructure and ensures fairness. Quota enforcement is "requests per billing period"—it controls costs and enforces plan limits. You need both.
A consumer might have a rate limit of 100 requests per second but a monthly quota of 10 million requests. The rate limit prevents them from overwhelming your API with a sudden burst. The quota prevents them from consuming resources beyond their plan tier over the billing period.
269
290
@@ -467,15 +488,22 @@ Most internal APIs start with direct attribution (simple to explain) then move t
467
488
468
489
Picking a cost model is as much psychology as math. The model shapes behavior—per-request pricing encourages consumers to reduce calls, compute-based pricing encourages efficient code, tiered pricing encourages growth.
{ th: "Flat + Overage", td: ["$500/month + $0.001/request over 1M", "Predictable base + flexibility"] },
503
+
],
504
+
},
505
+
}}
506
+
/>
479
507
480
508
The "Flat + Overage" model is underrated for internal APIs. It gives teams predictable budgets (the $500/month base covers normal usage) while preventing abuse (overages are billed separately). Finance likes it because budgets are stable, and engineering likes it because there's flexibility for legitimate spikes.
481
509
@@ -561,14 +589,21 @@ Export this to CSV, send it to finance, and let them handle the budget transfers
561
589
562
590
There's a spectrum between "no cost visibility" and "full chargebacks." Most organizations benefit from moving gradually rather than jumping straight to chargebacks.
**Showback** means "here's what you're using, here's what it costs, but we're not moving money between budgets." It's pure visibility. Teams can see their consumption and optimize without financial pressure.
574
609
@@ -738,16 +773,23 @@ Consumers need to see their usage in real-time, not when the bill arrives. A goo
738
773
739
774
The essential panels:
740
775
741
-
| Panel | Visualization | Purpose |
742
-
|-------|---------------|---------|
743
-
| Current Period Usage | Gauge/Progress | How much quota used |
744
-
| Usage Trend | Time series | Daily/hourly usage pattern |
745
-
| Usage by Endpoint | Bar chart | Which APIs drive usage |
746
-
| Projected Month-End | Stat | Forecast based on current rate |
747
-
| Cost Breakdown | Pie chart | Where money is going |
748
-
| Alerts | List | Approaching limits, unusual patterns |
The layout matters. Put the most important information at the top—current usage and projected costs. Trends and breakdowns go below. Alerts go at the bottom unless they're critical (approaching quota), then promote them to the top.
753
795
@@ -979,14 +1021,21 @@ The most common objection: "This will create budget battles between teams." True
979
1021
980
1022
Jumping straight to hard enforcement will cause significant organizational friction and backlash. A phased rollout lets you see your usage, understand the patterns, and optimize before financial consequences kick in.
{ th: "Stuck on hook", td: ["\"Running PreSync hooks\" forever", "Hook Job not completing", "Check job logs, add `activeDeadlineSeconds`"] },
198
+
{ th: "OutOfSync loop", td: ["Syncs successfully, immediately OutOfSync", "Controller modifying resource", "Add `ignoreDifferences` for that field"] },
199
+
{ th: "Missing resource", td: ["\"secret X not found\"", "Dependency ordering", "Move dependency to earlier sync wave"] },
200
+
{ th: "CRD not found", td: ["\"server doesn't have resource type\"", "CRD applied too late", "Put CRD in wave -5"] },
201
+
],
202
+
},
203
+
}}
204
+
/>
191
205
192
206
The "stuck on hook" pattern connects directly to the intro story—my production incident was exactly this. The hook was waiting for a dependency that didn't exist yet. Once you know to check hook job logs with `kubectl logs -l job-name=<hook>`, the cause usually becomes obvious.
0 commit comments