Skip to content

Commit 0d44032

Browse files
committed
Update 1st group of articles to Table component
1 parent db31b2d commit 0d44032

16 files changed

Lines changed: 551 additions & 489 deletions

File tree

‎.vscode/settings.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
"decr",
6161
"dedup",
6262
"deprioritized",
63+
"Descr",
6364
"Dredd",
6465
"dsar",
6566
"DTEND",

‎_TODO.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,8 @@ https://mermaid.js.org/config/directives.html
213213
- Need a Q & A format to use in `blameless-postmortem-incident-analysis-systemic-causes`. Might be one of the list formats.
214214

215215
- We need to check for short form and deep article articles where the deep-dive index.pdf has a non-featured tag like "argo-cd" only in the pdf.mdx. In those cases, we should make sure the callout for the deep dive includes the name of that non-featured (technology) tag
216+
217+
218+
Our current articles have markdown tables. I want to refactor these into using our Table component. I'm going to copy and paste the markdown table into the chat window here. I'd like you to take it and update the content prop in the Table instance in src/pages/hero.astro so that the table renders using the same layout as the markdown table. Use the string variant in the tbody -> tr -> th element.
219+
220+
Each table will have the "figure" prop as a line below the table, prefixed with "Table: ". We should remove the "Table: " prefix from the figure string as this is used by our Markdown setup to identify figure captions.
105 KB
Loading
83 KB
Loading
Binary file not shown.

‎src/content/articles/alert-fatigue-reduction-triage-actionable-alerts/pdf.mdx‎

Lines changed: 120 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,59 @@ Export your alert definitions and firing history. Prometheus/Alertmanager stores
6868

6969
For each alert, capture:
7070

71-
| Field | Description | Why It Matters |
72-
|-------|-------------|----------------|
73-
| Alert Name | Identifier in monitoring system | Tracking and deduplication |
74-
| Firing Frequency | Alerts/week over last 90 days | Identifies noisy alerts |
75-
| Action Rate | % of firings requiring human action | Core signal for usefulness |
76-
| Owning Team | Team responsible for response | Accountability |
77-
| Last Modified | When alert was last updated | Staleness indicator |
78-
| Linked Runbook | URL to response documentation | Actionability check |
79-
80-
Table: Alert inventory fields for the audit process.
71+
<Table
72+
variant="vertical-column-delineation-table"
73+
content={{
74+
figure: "Alert inventory fields for the audit process.",
75+
thead: { th: ["Field", "Description", "Why It Matters"] },
76+
tbody: {
77+
tr: [
78+
{
79+
th: "Alert Name",
80+
td: [
81+
"Identifier in monitoring system",
82+
"Tracking and deduplication",
83+
],
84+
},
85+
{
86+
th: "Firing Frequency",
87+
td: [
88+
"Alerts/week over last 90 days",
89+
"Identifies noisy alerts",
90+
],
91+
},
92+
{
93+
th: "Action Rate",
94+
td: [
95+
"% of firings requiring human action",
96+
"Core signal for usefulness",
97+
],
98+
},
99+
{
100+
th: "Owning Team",
101+
td: [
102+
"Team responsible for response",
103+
"Accountability",
104+
],
105+
},
106+
{
107+
th: "Last Modified",
108+
td: [
109+
"When alert was last updated",
110+
"Staleness indicator",
111+
],
112+
},
113+
{
114+
th: "Linked Runbook",
115+
td: [
116+
"URL to response documentation",
117+
"Actionability check",
118+
],
119+
},
120+
],
121+
},
122+
}}
123+
/>
81124

82125
The "action rate" column is the most important and the hardest to populate. You'll need to cross-reference alert firings with incident tickets or on-call logs. If your tooling doesn't track this automatically, you'll need to reconstruct it from memory or start tracking it going forward.
83126

@@ -148,7 +191,13 @@ Two tiers work better: pages and notifications. A page wakes someone up or inter
148191
The decision is binary: does this require immediate human attention, or can it wait until someone is already working? If you can't answer that question clearly for an alert, the alert isn't well-defined.
149192
150193
```mermaid
194+
---
195+
title: Decision tree for page vs. notification classification
196+
---
151197
graph TD
198+
accTitle: Alert severity decision tree
199+
accDescr: Flowchart showing how to classify an alert as a Page or Notification. When an alert fires, check if there is user-facing impact. If no, it is a Notification. If yes, check if there is immediate revenue or safety impact. If yes, it is a Page. If no, check if the SLO burn rate is critical. If yes, it is a Page. If no, it is a Notification.
200+
152201
A[Alert Fires] --> B{User-Facing Impact?}
153202
B -->|Yes| C{Immediate Revenue/Safety?}
154203
B -->|No| D[Notification]
@@ -170,16 +219,23 @@ A page should meet all three criteria:
170219

171220
If an alert doesn't meet all three, it's a notification at most.
172221

173-
| Criterion | Page | Notification |
174-
|-----------|------|--------------|
175-
| User-facing functionality down | ✅ | |
176-
| SLO error budget exhausted | ✅ | |
177-
| Security incident in progress | ✅ | |
178-
| Capacity threshold (proactive) | | ✅ |
179-
| Background job failure | | ✅ |
180-
| Non-critical dependency degraded | | ✅ |
181-
182-
Table: Page vs. notification decision matrix.
222+
<Table
223+
variant="vertical-column-delineation-table"
224+
content={{
225+
figure: "Page vs. notification decision matrix.",
226+
thead: { th: ["Criterion", "Page", "Notification"] },
227+
tbody: {
228+
tr: [
229+
{ th: "User-facing functionality down", td: ["✅", ""] },
230+
{ th: "SLO error budget exhausted", td: ["✅", ""] },
231+
{ th: "Security incident in progress", td: ["✅", ""] },
232+
{ th: "Capacity threshold (proactive)", td: ["", "✅"] },
233+
{ th: "Background job failure", td: ["", "✅"] },
234+
{ th: "Non-critical dependency degraded", td: ["", "✅"] },
235+
],
236+
},
237+
}}
238+
/>
183239

184240
The hardest calls are proactive alerts—things that aren't broken yet but will be soon. Disk filling up, certificate expiring, capacity approaching limits. These should almost never be pages. If you have time to address it proactively, you have time to address it during business hours. Page-worthy means _right now_, not _sometime today_.
185241

@@ -334,13 +390,20 @@ A single burn rate window has a tradeoff: short windows catch acute incidents bu
334390

335391
Use multiple windows together. Alert when _both_ a short window and a long window show elevated burn rates. This filters out transient spikes (which only show in the short window) while still catching acute incidents quickly.
336392

337-
| Window | Burn Rate | Catches |
338-
|--------|-----------|---------|
339-
| 5m | 14.4x | Acute incidents, sudden failures |
340-
| 1h | 6x | Sustained degradation |
341-
| 6h | 1x | Slow-burn issues |
342-
343-
Table: Multi-window burn rate thresholds for a 99.9% SLO.
393+
<Table
394+
variant="vertical-column-delineation-table"
395+
content={{
396+
figure: "Multi-window burn rate thresholds for a 99.9% SLO.",
397+
thead: { th: ["Window", "Burn Rate", "Catches"] },
398+
tbody: {
399+
tr: [
400+
{ th: "5m", td: ["14.4x", "Acute incidents, sudden failures"] },
401+
{ th: "1h", td: ["6x", "Sustained degradation"] },
402+
{ th: "6h", td: ["1x", "Slow-burn issues"] },
403+
],
404+
},
405+
}}
406+
/>
344407

345408
The 5-minute/14.4x combination catches a complete outage within minutes. If your error rate jumps to 100%, burn rate hits 1000x—well above the 14.4x threshold. But the 1-hour window must also show elevated burn rate before the alert fires. A 30-second blip won't trigger anything.
346409

@@ -472,14 +535,21 @@ Avoid jargon in summaries. The alert will often be read on a phone, possibly by
472535
473536
Establish a cadence for reviewing alerts. Suggest monthly reviews of alert firing patterns and quarterly reviews of alert usefulness. Include what questions to ask in each review.
474537
475-
| Review Type | Frequency | Questions |
476-
|-------------|-----------|-----------|
477-
| Firing Review | Monthly | Which alerts fired most? What was the action rate? |
478-
| Usefulness Review | Quarterly | Do we still need this alert? Is the threshold still valid? |
479-
| Runbook Review | Quarterly | Is the runbook current? Did it help in recent incidents? |
480-
| Owner Review | Annually | Does the owning team still exist? Do they still own this service? |
481-
482-
Table: Alert maintenance review cadence.
538+
<Table
539+
variant="vertical-column-delineation-table"
540+
content={{
541+
figure: "Alert maintenance review cadence.",
542+
thead: { th: ["Review Type", "Frequency", "Questions"] },
543+
tbody: {
544+
tr: [
545+
{ th: "Firing Review", td: ["Monthly", "Which alerts fired most? What was the action rate?"] },
546+
{ th: "Usefulness Review", td: ["Quarterly", "Do we still need this alert? Is the threshold still valid?"] },
547+
{ th: "Runbook Review", td: ["Quarterly", "Is the runbook current? Did it help in recent incidents?"] },
548+
{ th: "Owner Review", td: ["Annually", "Does the owning team still exist? Do they still own this service?"] },
549+
],
550+
},
551+
}}
552+
/>
483553
484554
Monthly firing reviews catch the immediate problems: which alerts are generating noise, which have low action rates. Pull the data, identify the worst offenders, and either fix them or delete them.
485555
@@ -583,14 +653,21 @@ graph TD
583653

584654
Figure: Alert outcome tracking for health metrics.
585655

586-
| Metric | Healthy | Warning | Critical |
587-
|--------|---------|---------|----------|
588-
| Action Rate | &gt; 80% | 50-80% | &lt; 50% |
589-
| MTTA | &lt; 5 min | 5-15 min | &gt; 15 min |
590-
| Alerts per On-Call Shift | &lt; 10 | 10-25 | &gt; 25 |
591-
| On-Call Satisfaction | &gt; 7/10 | 5-7/10 | &lt; 5/10 |
592-
593-
Table: Alert health metric thresholds.
656+
<Table
657+
variant="vertical-column-delineation-table"
658+
content={{
659+
figure: "Alert health metric thresholds.",
660+
thead: { th: ["Metric", "Healthy", "Warning", "Critical"] },
661+
tbody: {
662+
tr: [
663+
{ th: "Action Rate", td: ["> 80%", "50-80%", "< 50%"] },
664+
{ th: "MTTA", td: ["< 5 min", "5-15 min", "> 15 min"] },
665+
{ th: "Alerts per On-Call Shift", td: ["< 10", "10-25", "> 25"] },
666+
{ th: "On-Call Satisfaction", td: ["> 7/10", "5-7/10", "< 5/10"] },
667+
],
668+
},
669+
}}
670+
/>
594671

595672
These thresholds aren't universal—adjust them based on your context. A small team with a simple service might target fewer than 5 alerts per shift. A large platform team might accept more. What matters is that you're tracking the numbers and trending in the right direction.
596673

‎src/content/articles/api-deprecation-sunset-headers-consumer-migration/index.mdx‎

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,21 @@ Run this analysis weekly throughout the deprecation period. The output becomes y
5252

5353
This data also creates organizational accountability. Build a simple dashboard showing migration progress. When leadership can see that 30% of traffic is still on the deprecated API with 45 days until sunset, they understand why the deprecation might need executive escalation—or why it is on track for success.
5454

55-
| Metric | Purpose | Alert Threshold |
56-
|--------|---------|-----------------|
57-
| Deprecated Traffic % | Overall migration progress | > 20% at T-30 days |
58-
| Active Consumer Count | Remaining migration work | > 5 at T-30 days |
59-
| New Consumer Sign-ups | Preventing new adoption | Any new consumer |
60-
| Traffic by Consumer | Identify largest blockers | Top 3 consumers |
61-
62-
Table: Key deprecation metrics with alert thresholds.
55+
<Table
56+
variant="vertical-column-delineation-table"
57+
content={{
58+
figure: "Key deprecation metrics with alert thresholds.",
59+
thead: { th: ["Metric", "Purpose", "Alert Threshold"] },
60+
tbody: {
61+
tr: [
62+
{ th: "Deprecated Traffic %", td: ["Overall migration progress", "> 20% at T-30 days"] },
63+
{ th: "Active Consumer Count", td: ["Remaining migration work", "> 5 at T-30 days"] },
64+
{ th: "New Consumer Sign-ups", td: ["Preventing new adoption", "Any new consumer"] },
65+
{ th: "Traffic by Consumer", td: ["Identify largest blockers", "Top 3 consumers"] },
66+
],
67+
},
68+
}}
69+
/>
6370

6471
One critical point: the moment you announce a deprecation, stop allowing new consumers to adopt the deprecated API. Every new adoption extends your deprecation timeline and increases your support burden. Block new API keys from accessing deprecated versions. Remove deprecated APIs from public documentation. Stop distributing SDK versions that use the deprecated API.
6572

@@ -71,15 +78,22 @@ This is where most deprecation strategies fail. They announce, they communicate,
7178

7279
Graduated enforcement breaks this cycle by applying increasing pressure over time. Each step is uncomfortable enough to motivate action but not so severe that it causes outages. Consumers who ignore soft warnings eventually hit hard consequences, but they have multiple opportunities to respond before that happens.
7380

74-
| Phase | Mechanism | Consumer Impact |
75-
|-------|-----------|-----------------|
76-
| Warning | Deprecation headers only | None (headers ignored by most) |
77-
| Logging | Log all deprecated calls | None (internal tracking) |
78-
| Rate Limiting | Reduce rate limits by 50% | Degraded performance |
79-
| Read-Only | Disable write operations | Partial functionality loss |
80-
| Removal | Return 410 Gone | Complete failure |
81-
82-
Table: Graduated enforcement progression.
81+
<Table
82+
variant="vertical-column-delineation-table"
83+
content={{
84+
figure: "Graduated enforcement progression.",
85+
thead: { th: ["Phase", "Mechanism", "Consumer Impact"] },
86+
tbody: {
87+
tr: [
88+
{ th: "Warning", td: ["Deprecation headers only", "None (headers ignored by most)"] },
89+
{ th: "Logging", td: ["Log all deprecated calls", "None (internal tracking)"] },
90+
{ th: "Rate Limiting", td: ["Reduce rate limits by 50%", "Degraded performance"] },
91+
{ th: "Read-Only", td: ["Disable write operations", "Partial functionality loss"] },
92+
{ th: "Removal", td: ["Return 410 Gone", "Complete failure"] },
93+
],
94+
},
95+
}}
96+
/>
8397

8498
Rate limiting is the most effective soft enforcement mechanism. It makes using the deprecated API painful without making it impossible. Consumers experience degraded performance—slower responses, occasional 429 errors—that motivates migration without causing complete failures.
8599

@@ -99,15 +113,22 @@ A single announcement email has approximately a 20% open rate on a good day. If
99113

100114
Effective deprecation communication requires multiple channels, repeated over time, with increasing urgency:
101115

102-
| Channel | Timing | Audience |
103-
|---------|--------|----------|
104-
| Blog/Changelog | Announcement | All developers |
105-
| Email | Announcement + monthly | Registered consumers |
106-
| API Headers | Every request | Active consumers |
107-
| Dashboard Banner | Continuous | Logged-in users |
108-
| Direct Outreach | T-90, T-30, T-7 days | High-traffic consumers |
109-
110-
Table: Multi-channel communication schedule.
116+
<Table
117+
variant="vertical-column-delineation-table"
118+
content={{
119+
figure: "Multi-channel communication schedule.",
120+
thead: { th: ["Channel", "Timing", "Audience"] },
121+
tbody: {
122+
tr: [
123+
{ th: "Blog/Changelog", td: ["Announcement", "All developers"] },
124+
{ th: "Email", td: ["Announcement + monthly", "Registered consumers"] },
125+
{ th: "API Headers", td: ["Every request", "Active consumers"] },
126+
{ th: "Dashboard Banner", td: ["Continuous", "Logged-in users"] },
127+
{ th: "Direct Outreach", td: ["T-90, T-30, T-7 days", "High-traffic consumers"] },
128+
],
129+
},
130+
}}
131+
/>
111132

112133
The escalation timeline ties communication to enforcement:
113134

0 commit comments

Comments
 (0)