Zum Inhalt springen

Technische RFCs schreiben, die das Team ausrichten

Strukturiere RFCs, die das Problem klar benennen, Alternativen bewerten, eine Lösung vorschlagen und das Team ausrichten — mit Vorlagen.

4 Min. Lesezeit
Ein technisches RFC-Dokument durchläuft die Review-Phasen vom Entwurf bis zur Annahme, mit Anmerkungen zum Feedback des Teams

Warum RFCs wichtig sind

Die teuersten Fehler im Engineering sind Architekturentscheidungen, die ohne ausreichenden Input getroffen werden. Ein RFC (Request for Comments) zwingt dich dazu, einen Vorschlag vollständig zu durchdenken, bevor du Code schreibst, und gibt den Beteiligten eine strukturierte Möglichkeit, ihn zu bewerten und zu verbessern. Das Dokument wird zu einem dauerhaften Protokoll darüber, warum bestimmte Entscheidungen getroffen wurden – unschätzbar wertvoll, wenn zwei Jahre später jemand fragt: „Warum haben wir das damals so gebaut?"

Der Aufbau eines RFCs

Jeder RFC beantwortet vier Fragen: Was ist das Problem? Welche Optionen gibt es? Was empfiehlst du? Welche Risiken bestehen? Halte die Struktur konsistent, damit die Leser wissen, wo sie Informationen finden, ohne das Dokument von vorn bis hinten lesen zu müssen.

markdownmarkdown
# RFC: [Title]
 
**Author:** [Name]
**Status:** Draft | In Review | Accepted | Rejected | Superseded
**Created:** YYYY-MM-DD
**Last Updated:** YYYY-MM-DD
**Reviewers:** [Names/Teams]
**Decision Deadline:** YYYY-MM-DD
 
## Summary
[2-3 sentences. What are you proposing and why?]
 
## Motivation
[What problem are we solving? Include data, metrics, user reports.
Why now? What happens if we do nothing?]
 
## Detailed Design
[The core proposal. Architecture diagrams, API contracts,
data models. Enough detail to evaluate feasibility.]
 
## Alternatives Considered
[At least 2 alternatives. For each: brief description,
pros, cons, and why it was not chosen.]
 
## Risks and Mitigations
[What could go wrong? How will you address each risk?]
 
## Rollout Plan
[How will this be deployed? Feature flag? Migration?
What's the rollback plan?]
 
## Open Questions
[Things you don't know yet. Decisions you want input on.]

Den Abschnitt „Motivation" schreiben

Der Motivationsabschnitt ist der wichtigste Teil. Wenn die Leser das Problem nicht verstehen oder ihm nicht zustimmen, können sie die Lösung nicht bewerten. Beginne mit Daten.

tstypescript
// ❌ Vague motivation — no data, no urgency
// "Our current caching solution has some issues and we should
//  consider upgrading to something better."
 
// ✅ Data-driven motivation with clear problem statement
// "Our Redis cache hit rate has dropped from 94% to 67% over
//  the past 3 months as our dataset grew from 2M to 8M keys.
//  P99 latency for the /api/products endpoint increased from
//  45ms to 380ms. The current single-node Redis instance uses
//  12GB of its 16GB limit. At current growth rate, we will
//  exceed capacity in 6 weeks.
//
//  Impact: 23% of product page loads now exceed the 500ms SLA.
//  Customer support tickets mentioning 'slow loading' increased
//  40% month-over-month."
 
interface MotivationChecklist {
  hasQuantifiedProblem: boolean;      // Metrics, not feelings
  hasTimelineContext: boolean;         // Why now?
  hasImpactAssessment: boolean;       // What happens if we don't act?
  hasStakeholderContext: boolean;      // Who is affected?
  hasCostOfInaction: boolean;          // What's the cost of doing nothing?
}

Alternativen ehrlich bewerten

Liste die Alternativen auf, die du tatsächlich in Erwägung gezogen hast. Wenn du sie zu schnell verwirfst, werden die Reviewer bezweifeln, dass du den Lösungsraum wirklich durchdacht hast. Benenne auch die Kompromisse deines eigenen Vorschlags.

tstypescript
interface Alternative {
  name: string;
  description: string;
  pros: string[];
  cons: string[];
  estimatedEffort: string;
  whyNot: string;
}
 
const alternatives: Alternative[] = [
  {
    name: "Redis Cluster",
    description: "Scale current Redis horizontally with cluster mode",
    pros: [
      "Minimal code changes — same client library",
      "Team already familiar with Redis operations",
      "Linear horizontal scaling",
    ],
    cons: [
      "Cross-slot operations not supported",
      "Requires resharding as data grows",
      "Higher operational complexity",
    ],
    estimatedEffort: "2-3 weeks",
    whyNot: "Recommended — see Detailed Design",
  },
  {
    name: "DynamoDB DAX",
    description: "Replace Redis with DynamoDB Accelerator",
    pros: [
      "Fully managed, no operational overhead",
      "Automatic scaling",
      "Strong consistency option",
    ],
    cons: [
      "Significant code rewrite — different API",
      "Vendor lock-in to AWS",
      "Higher per-request cost at our scale",
      "Team has no DynamoDB experience",
    ],
    estimatedEffort: "6-8 weeks",
    whyNot: "Migration cost and vendor lock-in outweigh managed benefits",
  },
  {
    name: "Application-level caching with TTL optimization",
    description: "Keep single Redis, optimize cache keys and TTLs",
    pros: [
      "No infrastructure changes",
      "Immediate improvement possible",
    ],
    cons: [
      "Does not address capacity growth",
      "Temporary fix — revisit in 3-6 months",
    ],
    estimatedEffort: "1 week",
    whyNot: "Band-aid that delays the inevitable scaling work",
  },
];

Der Rollout-Abschnitt

Vorschläge, die den Rollout ignorieren, sind unvollständig. Reviewer müssen wissen, wie die Änderung in Produktion gelangt und was passiert, wenn etwas schiefgeht.

tstypescript
interface RolloutPlan {
  phases: Phase[];
  rollbackPlan: string;
  successCriteria: Metric[];
  monitoringAdditions: string[];
}
 
const rolloutPlan: RolloutPlan = {
  phases: [
    {
      name: "Shadow mode",
      duration: "1 week",
      description:
        "Write to both old and new cache. Read from old. Compare results.",
      successCriteria: "< 0.1% divergence between old and new reads",
    },
    {
      name: "Canary — 5% read traffic",
      duration: "3 days",
      description:
        "Route 5% of cache reads to new cluster. Monitor latency and hit rate.",
      successCriteria: "P99 < 50ms, hit rate > 90%",
    },
    {
      name: "Gradual rollout — 25%, 50%, 100%",
      duration: "1 week",
      description: "Ramp read traffic. Each step holds for 24h before advancing.",
      successCriteria: "No degradation from previous stage",
    },
    {
      name: "Decommission old cache",
      duration: "1 week after 100%",
      description: "Stop writes to old cache. Remove old infrastructure.",
    },
  ],
  rollbackPlan:
    "Feature flag instantly routes all reads back to old cache. " +
    "Old cache remains warm during entire rollout period.",
  successCriteria: [
    { name: "cache_hit_rate", target: "> 90%", current: "67%" },
    { name: "p99_latency_ms", target: "< 50", current: "380" },
    { name: "error_rate", target: "< 0.01%", current: "0.3%" },
  ],
  monitoringAdditions: [
    "Dashboard comparing old vs new cache metrics",
    "Alert on hit rate drop below 85%",
    "Alert on P99 exceeding 100ms",
  ],
};

Der RFC-Review-Prozess

Setze eine Entscheidungsfrist und lege fest, wer freigibt. Offene Review-Zyklen, die sich über Wochen hinziehen, verfehlen ihren Zweck. Gib explizit an, welche Art von Feedback du dir wünschst.

tstypescript
interface ReviewProcess {
  feedbackPeriod: string;
  decisionDeadline: string;
  requiredApprovers: string[];
  feedbackGuidance: string[];
  decisionCriteria: string;
}
 
const reviewProcess: ReviewProcess = {
  feedbackPeriod: "5 business days",
  decisionDeadline: "2025-10-01",
  requiredApprovers: [
    "Platform team lead",
    "Backend team lead",
    "SRE on-call",
  ],
  feedbackGuidance: [
    "Are there failure modes not covered in Risks?",
    "Are the alternatives fairly evaluated?",
    "Is the rollout plan sufficient for the risk level?",
    "Does the timeline account for your team's dependencies?",
  ],
  decisionCriteria:
    "Accepted if all required approvers agree. " +
    "If no consensus by deadline, escalate to engineering director.",
};

Die wichtigsten Erkenntnisse

RFCs verhindern teure Architekturfehler, indem sie strukturiertes Denken erzwingen, bevor Code geschrieben wird. Stütze den Motivationsabschnitt auf Daten – Kennzahlen, Zeitrahmen und Auswirkungen – nicht auf Meinungen. Bewerte Alternativen ehrlich; sie oberflächlich abzutun, untergräbt deine Glaubwürdigkeit.

Füge einen detaillierten Rollout-Plan mit Rollback-Strategie und Erfolgskriterien hinzu. Lege explizite Review-Fristen und eine Liste der Freigebenden fest, um Entscheidungsblockaden zu vermeiden. Der RFC selbst wird so zu einem Entscheidungsprotokoll: Monate oder Jahre später kann jeder darin nachlesen, nicht nur was gebaut wurde, sondern warum dieser Ansatz den Alternativen vorgezogen wurde. Schreibe den RFC, den du dir gewünscht hättest, als du zuletzt ein System ohne jede Dokumentation geerbt hast.

Wilfredo Rujel

Wilfredo Rujel

Full-Stack-Softwareentwickler

Diesen Beitrag teilenX