Last updated: March 15, 2026
Structure your RFC with a 2-3 sentence summary, a concrete problem statement with real data, a detailed proposed solution with code examples, explicitly rejected alternatives, numbered open questions for reviewers, and a clear feedback deadline. Assign 2-3 specific reviewers by name with targeted questions for each, and frame your decisions as current thinking rather than final verdicts. This approach converts vague “looks good” responses into actionable technical feedback across time zones.
Prerequisites
Before you begin, make sure you have the following ready:
- A computer running macOS, Linux, or Windows
- Terminal or command-line access
- Administrator or sudo privileges (for system-level changes)
- A stable internet connection for downloading tools
Step 1: The Core Problem with Most Technical RFCs
Most RFCs fail not because the ideas are bad, but because the document itself is difficult to engage with. A typical problematic RFC might say:
“We should migrate to Kubernetes because it provides better scalability.”
This statement leaves reviewers with no context, no data, and no clear way to respond. They might agree or disagree, but they can’t provide meaningful technical feedback because there’s nothing specific to evaluate.
Instead, your RFC should frame every claim with evidence, every decision with context, and every recommendation with clear alternatives considered. The goal is to make reviewing your proposal the easiest path for busy engineers.
Step 2: Structuring Your RFC for Async Review
An effective technical RFC follows a consistent structure that reviewers can quickly navigate. Use these sections in order:
Step 3: Writing Techniques That Generate Better Feedback
Use Concrete Examples
Abstract proposals invite abstract responses. Include real code snippets, actual data, or specific scenarios:
# Instead of saying "the cache should handle failures gracefully"
# Show exactly what happens:
def get_user_session(user_id):
try:
return cache.get(f"session:{user_id}")
except CacheConnectionError:
# Fallback to database on cache failure
return db.get_session(user_id)
This concrete example immediately tells reviewers: you’re handling the failure case, but you’re aware there’s a fallback path. They can now provide specific feedback about whether this approach meets your availability requirements.
Frame Decisions as Questions
When presenting your preferred approach, frame it as your current thinking rather than a fait accompli:
“I’m proposing we use WebSockets for real-time updates because Server-Sent Events don’t support bidirectional communication. However, WebSockets require connection state management. Is the additional complexity worth it for our use case?”
This invites reviewers to challenge your assumptions without feeling like they’re rejecting your entire proposal.
Include Specific Success Criteria
Define what “success” looks like for your proposal:
- Performance: “API response time should decrease from 500ms to under 100ms”
- Reliability: “System should handle 10x current traffic without degradation”
- Developer Experience: “New engineers should be able to implement a feature in under 2 hours”
Concrete metrics give reviewers something concrete to evaluate against.
Step 4: Manage the Async Review Process
Writing a great RFC is only half the battle—you also need to manage the review process effectively.
Set Clear Deadlines
State explicitly when you need feedback by. Without a deadline, “I’ll review this later” becomes “I’ll review this never.” A reasonable timeline is 5-7 business days for significant proposals.
Use Explicit Reviewer Assignments
Don’t just dump your RFC in a channel and hope for feedback. Identify 2-3 specific reviewers whose expertise is relevant:
“@alice @bob — I’d specifically appreciate your thoughts on the security implications in section 3 and the performance benchmarks in section 4. @charlie — can you review the database migration plan?”
This makes feedback someone’s explicit responsibility rather than a vague request.
Create Space for Async Discussion
Some feedback requires back-and-forth. Plan for this from the start by:
- Setting up a dedicated Slack channel or thread for RFC discussion
- Creating a living document where you can incorporate feedback
- Scheduling an optional sync call if the discussion gets complex
Step 5: Common Async RFC Mistakes to Avoid
The Wall of Text
Long, unbroken paragraphs discourage review. Use headers, bullet points, and code blocks to create visual breaks. Aim for paragraphs of 2-3 sentences maximum.
Missing Context
Never assume reviewers remember previous discussions. If your RFC builds on an earlier decision, link to it. If it relates to another system, provide brief context.
Vague Language
Replace weak language with specific claims:
| Instead of… | Write… |
|---|---|
| “pretty fast” | “completes in under 50ms” |
| “better” | “reduces memory usage by 40%” |
| “several options” | “three options: A, B, and C” |
Forgetting the “Why”
The most common failure mode is explaining what you want to do without explaining why this is the right thing to do. Every technical decision should connect back to business goals, user needs, or engineering constraints.
Step 6: Example RFC Template
Here’s a practical template you can adapt:
# RFC: [Short Title]
### Step 7: Motivation
[Specific problem this solves, with concrete examples]
### Step 8: Proposed Solution
[Detailed technical approach with code examples]
### Step 9: Alternatives
- Option A: [description] — Rejected because [reason]
- Option B: [description] — Rejected because [reason]
### Step 10: Open Questions
- [Specific question for reviewers]
- [Another area needing input]
### Step 11: Success Criteria
- [Measurable outcome 1]
- [Measurable outcome 2]
### Step 12: Timeline
- Week 1: [milestone]
- Week 2: [milestone]
### Step 13: Feedback Requested By
[Date and tagged reviewers]
Step 14: Slack Automation with Workflows and Webhooks
Automating Slack notifications reduces manual status updates and keeps teams synchronized without extra meetings.
import requests
import json
from datetime import datetime
SLACK_WEBHOOK_URL = "https://hooks.slack.com/services/T.../B.../..."
def post_slack_message(channel, text, blocks=None):
payload = {"channel": channel, "text": text}
if blocks:
payload["blocks"] = blocks
response = requests.post(
SLACK_WEBHOOK_URL,
data=json.dumps(payload),
headers={"Content-Type": "application/json"},
)
return response.status_code == 200
# Rich block message for daily standup digest:
def post_standup_digest(updates):
blocks = [
{"type": "header", "text": {"type": "plain_text",
"text": f"Standup Digest — {datetime.now().strftime('%A %b %d')}"}},
{"type": "divider"},
]
for person, update in updates.items():
blocks.append({
"type": "section",
"text": {"type": "mrkdwn",
"text": f"*{person}*
{update}"}
})
return post_slack_message("#standups", "Daily standup digest", blocks)
# Schedule via cron:
# 0 9 * * 1-5 python3 /home/user/standup_digest.py
Webhooks are simpler than bot tokens for one-way notifications. Use Slack’s Block Kit Builder (api.slack.com/block-kit/building) to design rich message layouts.
Step 15: Slack Search Operators for Remote Teams
Advanced search operators cut through Slack noise to find decisions, files, and context quickly.
Useful search operator combinations:
from:@username in:#channel after:2026-01-01— find all messages from a person in a specific channelhas:link from:@boss before:2026-03-01— find links shared by your manager recently"deployment" in:#engineering has:pin— find pinned deployment-related messagesis:thread from:me— your threaded replies (useful for finding context you added)
# Slack CLI for programmatic search (requires Slack CLI installed):
slack search messages --query "from:@alice deployment" --channel engineering
# Export search results via API:
curl -s "https://slack.com/api/search.messages" -H "Authorization: Bearer xoxp-YOUR-TOKEN" --data-urlencode "query=deployment hotfix in:#engineering" --data-urlencode "count=20" | python3 -m json.tool | grep -A3 '"text"'
Bookmark searches you run repeatedly as saved searches in the Slack sidebar. This is faster than rebuilding the query each time for recurring audit needs.
Troubleshooting
Configuration changes not taking effect
Restart the relevant service or application after making changes. Some settings require a full system reboot. Verify the configuration file path is correct and the syntax is valid.
Permission denied errors
Run the command with sudo for system-level operations, or check that your user account has the necessary permissions. On macOS, you may need to grant terminal access in System Settings > Privacy & Security.
Connection or network-related failures
Check your internet connection and firewall settings. If using a VPN, try disconnecting temporarily to isolate the issue. Verify that the target server or service is accessible from your network.
Frequently Asked Questions
How long does it take to write async technical rfcs that get meaningful?
For a straightforward setup, expect 30 minutes to 2 hours depending on your familiarity with the tools involved. Complex configurations with custom requirements may take longer. Having your credentials and environment ready before starting saves significant time.
What are the most common mistakes to avoid?
The most frequent issues are skipping prerequisite steps, using outdated package versions, and not reading error messages carefully. Follow the steps in order, verify each one works before moving on, and check the official documentation if something behaves unexpectedly.
Do I need prior experience to follow this guide?
Basic familiarity with the relevant tools and command line is helpful but not strictly required. Each step is explained with context. If you get stuck, the official documentation for each tool covers fundamentals that may fill in knowledge gaps.
Can I adapt this for a different tech stack?
Yes, the underlying concepts transfer to other stacks, though the specific implementation details will differ. Look for equivalent libraries and patterns in your target stack. The architecture and workflow design remain similar even when the syntax changes.
Where can I get help if I run into issues?
Start with the official documentation for each tool mentioned. Stack Overflow and GitHub Issues are good next steps for specific error messages. Community forums and Discord servers for the relevant tools often have active members who can help with setup problems.
Related Articles
- How to Build Async Feedback Culture on a Fully Remote Team
- How to Write Clear Async Project Briefs for Remote Teams
- Async Decision Making with RFC Documents for Engineering
- How to Make Async Communication Inclusive for Non-Native
- How to Write Effective Async Messages for Remote Work Built by theluckystrike — More at zovo.one