6 min read
On this page

Specs for Engineers

A spec is a communication artifact. Its purpose is to give engineers the information they need to build the right thing without making them guess about product intent, edge cases, or scope boundaries. The best specs are the ones that engineers read once, ask a few clarifying questions about, and then build against with confidence. The worst specs are the ones that leave engineers making product decisions in code because the PM did not think things through.

This is a guide to writing specs that engineers actually find useful, written from the perspective of what engineers need, not what PMs like to write.

What Engineers Need

After working with hundreds of engineers, the pattern is clear. Engineers need six things from a spec, and almost nothing else.

1. Clear Requirements

A requirement is a statement about what the system must do, written in plain language. Not a user story. Not a business justification. A simple declaration of behavior.

Good requirements:
  - The system sends a confirmation email within 60 seconds of
    account creation.
  - The search results page displays a maximum of 25 results per page.
  - Users can upload files up to 50MB. Files larger than 50MB are
    rejected with an error message.
  - The export generates a CSV file with columns: date, user_email,
    action, details.
  - Session timeout is 30 minutes of inactivity. On timeout, the
    user is redirected to the login page.

Bad requirements:
  - The system should be fast. (How fast?)
  - The search should return relevant results. (What is "relevant"?)
  - The user experience should be intuitive. (Untestable.)
  - We need to handle errors gracefully. (Which errors? How?)

Each requirement should be testable. If you cannot write a test for it, it is not a requirement. It is a wish.

2. Explicit Edge Cases

Edge cases are where most bugs live and where most specs fall short. Engineers think about edge cases naturally, but they should not have to make product decisions about them. That is the PM's job.

Feature: User can change their email address

Happy path:
  User enters new email, receives verification link, clicks link,
  email is updated.

Edge cases the spec must address:
  - User enters an email that already belongs to another account.
    What happens? (Reject with message? Merge accounts? Show a
    different error?)
  - User requests a change but never clicks the verification link.
    How long is the link valid? What happens after expiration?
  - User requests multiple email changes in quick succession.
    Does each request invalidate the previous one?
  - User changes their email while they have an active session on
    another device. Are other sessions invalidated?
  - User's new email is in a different domain. Does this affect
    team membership or SSO?
  - Email delivery fails (invalid address, mailbox full). How does
    the user know? Is there a retry?

You do not need to solve every edge case in advance. But you need to identify them. Writing "TBD - discuss with engineering" next to an edge case is far better than not mentioning it at all.

Stripe's internal specs are famous for their edge case coverage. Every payment flow spec explicitly addresses what happens on timeout, retry, partial failure, and concurrent requests. This discipline is why Stripe's API behaves predictably even in unusual situations.

3. What Is NOT Included

This is the single most useful section of a spec and the one PMs skip most often. Engineers need to know the boundaries of what they are building so they do not over-build or make incorrect assumptions.

Feature: Team permissions

NOT included (explicitly):
  - No cross-team permissions in this phase. Each team is isolated.
  - No permission inheritance (child teams do not inherit parent
    permissions).
  - No audit trail in v1 (planned for v2).
  - No API endpoint for permission management. Admin UI only.
  - No granular permissions below the feature level (e.g., no
    "can view but not edit" on individual records).
  - No mobile support. Web only.

Without this section, an engineer might spend two days building permission inheritance because it "seemed like it should be included." That is two days wasted because the PM did not draw a clear boundary.

4. Performance Expectations

Engineers need to know what "fast enough" means. Without explicit performance requirements, every engineer applies their own standard, which leads to either over-engineering or under-engineering.

Performance requirements:
  - Page load: first meaningful paint under 1.5 seconds on a
    standard broadband connection.
  - Search: results returned within 500ms for queries against
    up to 100,000 records.
  - File upload: progress indicator shown. Upload of a 50MB file
    completes within 30 seconds on a 10Mbps connection.
  - API response: p95 latency under 200ms for read endpoints,
    under 500ms for write endpoints.
  - Bulk operations: processing 500 records completes within
    2 minutes. Progress is communicated to the user.

These numbers do not need to be exact, but they need to exist. "Fast" means different things to different engineers. "Under 500ms at p95" is unambiguous.

5. Data Model Implications

When a feature changes what data the system stores or how it relates to existing data, engineers need to know. They will figure out the schema themselves, but they need to know what the product expects the system to remember.

Data implications:

New data the system must store:
  - Permission group: name, description, list of permissions,
    list of assigned users, created_by, created_at
  - Each user can belong to multiple permission groups
  - Permission changes must be recorded: who changed what, when,
    previous value, new value

Data relationships:
  - A permission group belongs to one team
  - A user can belong to multiple groups across different teams
  - Deleting a group does not delete its members

Data retention:
  - Permission change history retained for 2 years
  - Deleted groups are soft-deleted (retained for 90 days)

This is not a database schema. It is a description of what the product needs to persist and how it relates conceptually. The engineer turns this into a schema. But they need the product intent to do it correctly.

6. What They Do NOT Need

Engineers do not want PMs telling them how to build things. Providing implementation details in a spec signals distrust and limits the engineer's ability to find better solutions.

Do NOT include in the spec:
  - "Use React for the frontend." (Technology choice is engineering's
    domain unless there's a business constraint.)
  - "Store this in a PostgreSQL table with columns..." (The engineer
    will design the schema.)
  - "Use a background job queue for email sending." (The engineer
    will decide the architecture.)
  - "Cache the results for 5 minutes." (The engineer will determine
    the caching strategy based on the performance requirements.)
  - "Use a dropdown component for selection." (Unless the design
    mockup specifies this. Even then, be open to alternatives.)

The exception is when there is a genuine business or product constraint on implementation. "The export must generate a standard CSV file because our customers import it into Excel" is a legitimate requirement. "Use the csv library in Python" is not.

Spec Format

There is no single correct format. Some teams use documents, some use tickets, some use wikis. The format matters less than the content. That said, here is a format that works well.

Spec: [Feature Name]
Author: [PM name]
Status: Draft / In Review / Final
Last updated: [date]

## Context
[2-3 sentences. Why are we building this?]

## Requirements
[Numbered list of specific, testable requirements]

## Edge Cases
[List of edge cases with product decisions for each]

## Not Included
[Explicit list of what this feature does NOT do]

## Performance
[Latency, throughput, and scale expectations]

## Data
[What the system needs to store, relationships, retention]

## Open Questions
[Things not yet decided, with owners and deadlines]

## References
[Links to mockups, PRD, research, technical spikes]

Writing for Clarity

Engineers read specs to extract information quickly. Every sentence should be unambiguous and every requirement should be independently understandable.

Ambiguous: "The system should support multiple file types."
Clear: "The system accepts JPG, PNG, WebP, and PDF files.
        All other file types are rejected with the message
        'Unsupported file type. Please upload a JPG, PNG,
        WebP, or PDF file.'"

Ambiguous: "Users should be able to customize their dashboard."
Clear: "Users can add, remove, and rearrange widgets on their
        dashboard. Available widgets: activity feed, metrics
        summary, team calendar, recent documents. Maximum 8
        widgets per dashboard. Default layout: activity feed
        (top left), metrics summary (top right)."

Ambiguous: "Handle errors appropriately."
Clear: "On network timeout (>10s), show message: 'Connection
        lost. Your changes are saved locally and will sync
        when you reconnect.' Retry automatically every 30
        seconds. After 5 failed retries, show: 'Unable to
        connect. Please check your internet connection.'"

Collaborating on Specs

The best specs are not written by PMs in isolation. They are co-created through conversation.

Effective spec process:
  1. PM writes first draft with requirements, scope, and known
     edge cases (1-2 hours)
  2. PM and engineering lead review together (30-60 minutes)
     - Engineer identifies missed edge cases
     - Engineer flags technical risks or constraints
     - PM clarifies product intent where ambiguous
     - Both identify open questions
  3. PM updates spec based on discussion (30 minutes)
  4. Design reviews for UX consistency (if applicable)
  5. Final spec shared with full team before development begins

This process takes a few hours total and prevents weeks of rework. The 30-minute review with the engineering lead is the highest-leverage meeting in the entire product development cycle.

At Figma, specs go through a "crit" process where PMs, engineers, and designers review the spec together. This catches misalignment before code is written. The cost of finding a misunderstanding in a spec review is minutes. The cost of finding it after two weeks of development is days.

The Relationship Between PRD & Spec

A PRD and a spec are related but serve different audiences and purposes.

PRD:
  Audience: Everyone (PM, design, engineering, stakeholders)
  Focus: Problem, users, goals, scope
  Detail level: Moderate
  Changes: Relatively stable once development starts

Spec:
  Audience: Engineering (and QA)
  Focus: Requirements, edge cases, behavior, performance
  Detail level: High
  Changes: Evolves as design finalizes and edge cases are resolved

Some teams combine them into one document. This works for smaller features. For larger features, keeping them separate allows the PRD to stay concise while the spec goes into engineering-level detail.

Common Pitfalls

  • Specifying the solution instead of the requirement. "Use a modal dialog" is a solution. "Show a confirmation before the user deletes their account" is a requirement. Let design and engineering choose the implementation.
  • Missing the negative requirements. Specs that describe what the system does but never describe what it does not do. The "not included" section prevents scope creep and wasted effort.
  • Assuming engineers will "figure out" the edge cases. They will figure them out in code, making product decisions on the fly. Sometimes they will guess right. Sometimes they will not. Specify the edge cases.
  • Writing pixel-perfect design requirements before alignment on behavior. Getting agreement on what happens is more important than getting agreement on what it looks like. Behavior first, then visual design.
  • Not updating the spec when decisions change. If sprint planning resolves an open question, update the spec. If scope is cut, update the spec. A stale spec is worse than no spec because it actively misleads.
  • Over-specifying for small features. A one-day feature does not need a full spec. A verbal conversation and a well-written ticket may be sufficient. Match the formality to the complexity and risk.

Key Takeaways

Engineers need six things from a spec: clear requirements, explicit edge cases, what is not included, performance expectations, data model implications, and links to relevant references. They do not need implementation details, technology choices, or pixel-perfect designs before behavior is agreed upon. Write requirements that are specific and testable. Identify edge cases and make product decisions about them. Co-create specs with engineering through a review conversation. Keep the spec updated when decisions change. The goal is to give engineers the information they need to build the right thing with confidence.