Stage 7 · Master
Observability & Developer Experience Metrics
DX Surveys & Feedback Loops
Quarterly developer NPS, in-app feedback widgets, friction logs. Close the loop: publish results, prioritize, ship improvements.
Why DX Surveys?
Metrics tell you what happened; surveys tell you why. Quantitative metrics (lead time, error rate) need qualitative context (frustration, confusion, delight). Surveys capture the developer experience that metrics miss.
| Signal Type | What It Captures | Limitations |
|---|---|---|
| Metrics (DORA, SLI) | Behavioral outcomes: speed, reliability, volume | No context on why, no sentiment |
| NPS Survey | Overall loyalty, likelihood to recommend | Lagging, low response rate, no specifics |
| In-App Feedback | Contextual friction at moment of use | Biased toward extremes (love/hate) |
| Friction Logs | Detailed workflow pain points | High effort, small sample, manual |
| Support Tickets | Explicit problems | Reactive, only captures blockers |
Quarterly NPS Survey
Net Promoter Score: 'How likely are you to recommend our platform to a colleague?' 0-10 scale. Promoters (9-10), Passives (7-8), Detractors (0-6). NPS = %Promoters - %Detractors.
# Platform Engineering Quarterly NPS Survey (Q1 2024)
## Core NPS
**On a scale of 0-10, how likely are you to recommend our platform to a colleague?**
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
## Follow-up (Required)
**What is the primary reason for your score?**
[Open text]
## Platform Dimensions (1-5 scale)
**How satisfied are you with each aspect?**
| Aspect | Very Dissatisfied | Dissatisfied | Neutral | Satisfied | Very Satisfied |
|--------|-------------------|--------------|---------|-----------|----------------|
| Scaffold / Getting Started | ☐ | ☐ | ☐ | ☐ | ☐ |
| CI/CD Pipeline | ☐ | ☐ | ☐ | ☐ | ☐ |
| Preview Environments | ☐ | ☐ | ☐ | ☐ | ☐ |
| Observability (Logs, Metrics, Traces) | ☐ | ☐ | ☐ | ☐ | ☐ |
| Secrets Management | ☐ | ☐ | ☐ | ☐ | ☐ |
| Documentation | ☐ | ☐ | ☐ | ☐ | ☐ |
| CLI Experience | ☐ | ☐ | ☐ | ☐ | ☐ |
| Portal / Catalog | ☐ | ☐ | ☐ | ☐ | ☐ |
| Support Responsiveness | ☐ | ☐ | ☐ | ☐ | ☐ |
| Platform Reliability | ☐ | ☐ | ☐ | ☐ | ☐ |
## Open Feedback
**What is the ONE thing we should improve?**
[Open text]
**What is the ONE thing we should keep doing?**
[Open text]
**Any specific feature requests?**
[Open text]
## Demographics (Optional)
- Team: [Dropdown]
- Role: [Developer / Tech Lead / EM / SRE / Other]
- Tenure: [<6mo / 6-12mo / 1-2yr / 2-5yr / 5+yr]
- Primary Language: [Go / Python / Java / Node.js / Other]
Standardized quarterly survey. Consistent questions enable trend analysis. Demographics enable segmentation.
In-App Feedback
Lightweight feedback at point of use: CLI commands, portal pages, error messages. Low friction, high context.
// components/FeedbackWidget.tsx
import { useState } from 'react';
export function FeedbackWidget({ page, userId }: { page: string; userId: string }) {
const [show, setShow] = useState(false);
const [rating, setRating] = useState<number | null>(null);
const [comment, setComment] = useState('');
const submit = async () => {
if (!rating) return;
await fetch('/api/feedback', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
page,
userId,
rating,
comment,
timestamp: new Date().toISOString(),
userAgent: navigator.userAgent,
}),
});
setShow(false);
setRating(null);
setComment('');
};
// Show widget 5% of page views, after 30 seconds
useEffect(() => {
if (Math.random() < 0.05) {
const timer = setTimeout(() => setShow(true), 30000);
return () => clearTimeout(timer);
}
}, [page]);
if (!show) return null;
return (
<div className="fixed bottom-4 right-4 z-50 bg-white rounded-lg shadow-lg p-4 border w-80">
<div className="flex justify-between items-center mb-2">
<h3 className="font-semibold">Quick feedback</h3>
<button onClick={() => setShow(false)} className="text-gray-400 hover:text-gray-600">✕</button>
</div>
<p className="text-sm text-gray-600 mb-3">How helpful was this page?</p>
<div className="flex gap-2 mb-3">
{[1, 2, 3, 4, 5].map((n) => (
<button
key={n}
onClick={() => setRating(n)}
className={`px-3 py-1 rounded ${rating === n ? 'bg-indigo-600 text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200'}`}
>
{n}
</button>
))}
</div>
<textarea
value={comment}
onChange={(e) => setComment(e.target.value)}
placeholder="Optional: what could be better?"
className="w-full p-2 border rounded text-sm mb-2"
rows={2}
/>
<button
onClick={submit}
disabled={!rating}
className="w-full bg-indigo-600 text-white py-2 rounded disabled:bg-gray-300 py-2 rounded"
>
Submit
</button>
</div>
);
}
Portal feedback widget: 5% sample rate, 30s delay, 5-star rating + optional comment.
Friction Logs
Structured, detailed walkthrough of a developer workflow by a platform team member (or new hire). Documents every friction point: confusion, errors, missing docs, context switches, wait times.
# Friction Log: [Workflow Name] - [Date] - [Author]
## Workflow
**Goal:** [e.g., "Create a new Go microservice with PostgreSQL and deploy to preview"]
**Persona:** [e.g., "New hire, 2 weeks at company, Go experience"]
**Date/Time:** [Start - End]
## Step-by-Step
| Step | Action | Expected | Actual | Friction (1-5) | Notes |
|------|--------|----------|--------|----------------|-------|
| 1 | Run `platform service create` | Interactive prompts | Worked, but team dropdown slow | 2 | Team list took 8s to load |
| 2 | Enter service name | Validation | "payment-api" accepted | 1 | |
| 3 | Select capabilities | Checkboxes | PostgreSQL, Kafka | 1 | |
| 4 | Confirm repo URL | GitHub URL | Typo in org name, unclear error | 4 | Error: "Invalid repo" - didn't say format |
| 5 | Wait for scaffold | Success message | Took 45s, no progress indicator | 3 | Spinner would help |
| 6 | Clone repo | `git clone` | Worked | 1 | |
| 7 | Open in VS Code | DevContainer prompt | Prompt appeared, build took 3min | 3 | First build slow, no cached layers |
| 8 | Make code change | Edit main.go | Worked | 1 | |
| 9 | Push to GitHub | `git push` | Worked | 1 | |
| 10 | Check preview env | URL in PR comment | No comment appeared | 5 | **Critical**: No feedback loop. Had to check ArgoCD manually. |
| 11 | Access preview URL | App loads | 404 - service not ready | 4 | No status indicator, had to check ArgoCD |
## Summary
**Total Time:** 18 minutes
**Total Friction Score:** 29/55 (53%)
**Critical Issues:** 2 (Step 10, 11)
**High Friction:** 2 (Step 4, 7)
## Recommendations
1. **Add progress indicator** to scaffold command (spinner + steps)
2. **Improve repo URL validation error** with example format
3. **Add GitHub PR comment** when preview env ready/failed
4. **Add preview env status badge** in PR (GitHub Check Run)
5. **Cache DevContainer layers** for faster first build
6. **Pre-load team list** in scaffold command (cache for 5min)
## Artifacts
- Screen recording: [link]
- Scaffold command output: [link]
- ArgoCD screenshots: [link]
Structured friction log captures step-by-step experience. Quantitative (1-5) + qualitative. Drives prioritized improvements.
Closing the Loop
Feedback without action destroys trust. Closing the loop means: acknowledge → prioritize → act → communicate. Every feedback item gets a public status.
- Acknowledge: Auto-reply to survey/feedback: 'Thanks! We read every response.'
- Triage: Weekly platform team review. Tag: bug, feature, docs, ux, wontfix.
- Prioritize: RICE score + feedback volume + strategic alignment.
- Act: Assign owner, create GitHub issue, add to sprint.
- Communicate: Monthly 'You Said, We Did' post in #platform-updates + changelog.
- Verify: Follow-up survey 3 months later: 'Did we fix [issue]?'
# You Said, We Did - January 2024
## 🎯 Top Feedback Themes (from Q4 NPS + In-App + Friction Logs)
| Theme | Volume | Sentiment | Status |
|-------|--------|-----------|--------|
| Scaffold speed | 47 mentions | Negative | ✅ Shipped v2.1 |
| Preview env visibility | 31 mentions | Negative | 🚧 In progress |
| CLI error messages | 19 mentions | Negative | ✅ Shipped v1.4 |
| Docs search | 12 mentions | Negative | 📋 Planned Q1 |
## ✅ Shipped This Month
### Scaffold Speed Improvements (v2.1.0)
**You said:** "Scaffold takes 45s with no progress indicator"
**We did:**
- Added spinner with step names (Validating → Rendering → Git → GitHub → ArgoCD)
- Parallelized template rendering + GitHub API calls
- Cached team list for 5 minutes
**Result:** Median scaffold time 45s → 12s (73% improvement)
### CLI Error Messages (v1.4.0)
**You said:** "Error 'Invalid repo' doesn't tell me the format"
**We did:**
- Added regex validation with example in error message
- Error: "Invalid repo URL. Expected: github.com/org/repo (got: github.com/myorg)"
- Added --dry-run flag to preview without creating
**Result:** CLI error-related support tickets down 60%
## 🚧 In Progress
### Preview Environment Visibility
**You said:** "No feedback when preview env ready/failed"
**We're doing:**
- GitHub Check Run for preview env (pending → success/failure)
- PR comment with preview URL + status badge
- ArgoCD sync status in Check Run details
**ETA:** February 15
## 📋 Planned (Next Quarter)
### Documentation Search
**You said:** "Can't find anything in docs"
**Plan:**
- Migrate to Algolia DocSearch
- Add search analytics (failed searches = content gaps)
- Rewrite top 20 failed-search topics
**Target:** March 31
## 📊 Metrics Impact
| Metric | Before | After | Change |
|--------|--------|-------|--------|
| Scaffold median time | 45s | 12s | -73% |
| CLI error ticket volume | 12/week | 5/week | -58% |
| Preview env success rate | 78% | 94% | +16pp |
| Platform NPS | 22 | 34 | +12 |
## 🗣️ Your Voice Matters
- **Survey:** [Q1 NPS Survey Link] (closes Feb 15)
- **In-App:** Click 💬 on any portal page
- **Friction Log:** Volunteer for 30-min walkthrough (swag + coffee)
- **Slack:** #platform-feedback for quick thoughts
*Every piece of feedback is read by the platform team. Thank you for making our platform better!*
Monthly public update closes the loop. Shows feedback → action → impact. Builds trust and participation.
Prioritization Framework
Not all feedback is equal. Prioritize using: Feedback Volume × Severity × Strategic Alignment × Effort. RICE adapted for platform: Reach (developers affected), Impact (friction reduction), Confidence (evidence strength), Effort (platform team weeks).
# Feedback Item: Scaffold progress indicator
reach: 150 # All 150 developers use scaffold
impact: 4 # High: eliminates 30s wait + confusion per use
confidence: 0.9 # Friction logs + survey + support tickets
effort: 2 # 2 engineer-weeks (frontend + backend)
rice: (150 * 4 * 0.9) / 2 = 270
# Feedback Item: Custom dashboard builder
reach: 20 # Only frontend teams
impact: 3 # Medium: nice to have
confidence: 0.5 # Low: no direct requests, just "would be nice"
effort: 8 # 8 engineer-weeks
rice: (20 * 3 * 0.5) / 8 = 3.75
# Decision: Prioritize scaffold progress indicator (270 vs 3.75)
RICE scoring for platform feedback. Quantitative comparison prevents loudest voice winning.
Treat feedback collection and response as a product: measure response rate, time-to-first-response, resolution rate, satisfaction with resolution. Platform team's 'customers' are developers — their feedback is your roadmap.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.