Active vs. Passive Voice in Technical Writing: When to Use Each

When to use active and passive voice in technical documentation, API docs, commit messages, and error messages. Rules, examples, and a quick test to decide which voice to use.

One of the most common pieces of writing advice is: “Use active voice.” In most general writing, this is good advice. But in technical writing — API documentation, error messages, system logs, runbooks — the rule is more nuanced. Passive voice is not only acceptable but sometimes more accurate and professional.

This guide explains the difference, gives you a test for deciding which to use, and shows real examples from technical writing contexts.


The Fundamental Difference

Active voice: The subject performs the action.

The developer calls the API. The function returns a boolean.

Passive voice: The subject receives the action (the actor is omitted or pushed to the end).

The API is called. A boolean is returned.

The choice is not about right or wrong — it depends on what information is most important and what the reader needs to know.


The Quick Test: Two Questions

Before choosing a voice, ask:

1. Does the reader need to know WHO does the action?

  • Yes → Active voice
  • No → Passive is fine

2. Is the action more important than the actor?

  • Yes → Passive voice
  • No → Active voice

When to Use Active Voice

User Instructions and Step-by-Step Guides

When you are telling a user what they need to do, active voice is clearer and more direct.

“The config.yaml file should be edited to set the environment variables.”“Edit the config.yaml file to set the environment variables.”

“The request should be authenticated by including the Bearer token in the header.”“Authenticate your requests by including the Bearer token in the Authorization header.”

The second versions reduce ambiguity about who is responsible for the action.

Describing Function / Method Behavior in Imperative Style

Docstrings and function descriptions often use imperative active voice:

def send_notification(user_id: str, message: str) -> bool:
    """Send a push notification to the specified user.
    
    Returns True if the notification was delivered, False otherwise.
    """

The first line — “Send a push notification” — is imperative active. This is the standard style for function documentation.

README Instructions

## Getting Started

1. Clone the repository.
2. Install dependencies with `npm install`.
3. Copy `.env.example` to `.env` and configure your variables.
4. Start the development server with `npm run dev`.

Every step is active imperative. This is the most readable format for instructions.

Commit Messages (the Git convention)

Git commit messages use imperative active voice by convention:

“Add user authentication middleware”“Fix null pointer exception in payment handler”“Refactor database connection pool”“Remove deprecated /v1/users/batch endpoint”

“Added user authentication” (past tense — not the convention) ❌ “User authentication was added” (passive — not the convention)

The logic: a commit message completes the sentence “If applied, this commit will…”“If applied, this commit will Add user authentication middleware.”


When to Use Passive Voice

Describing System Behavior When the Actor Is the System Itself

When the system/application performs an action automatically, passive voice is often more natural — because the user does not need to know the mechanical details.

“The request is processed asynchronously.”“Logs are retained for 30 days.”“Duplicate requests are automatically deduplicated using the idempotency key.”“Passwords are hashed using bcrypt before storage.”

In each case, the important information is what happens, not who does it (it’s the system — everyone knows that).

Error Messages

Error messages should focus on what happened and what to do, not on assigning blame to the system:

“Your request could not be processed. Please check the request parameters and try again.”“The file could not be uploaded. Maximum file size is 10MB.”“Your session has expired. Please log in again.”

These use passive to describe the state of the system without blaming the user or sounding mechanical.

Security Documentation (Describing What Was Done to a System)

In incident reports and security advisories, passive voice is standard:

“An authentication bypass vulnerability was discovered in versions 2.1.0–2.3.4.”“User passwords were exposed due to an improperly configured S3 bucket.”“The vulnerability has been patched in version 2.3.5.”

These are not hiding who did things — the actor is genuinely secondary to the event itself.

Describing Automated Pipeline Steps

In CI/CD configuration documentation:

“Tests are run on every pull request.”“Docker images are built and pushed to ECR after a successful merge to main.”“Notifications are sent to the #deployments Slack channel on completion.”


Side-by-Side Comparison in Real Contexts

API Documentation

Context❌ Awkward✅ Natural
What endpoint doesThe system creates a new userCreates a new user account
What happens after requestThe system processes it asynchronouslyThe request is processed asynchronously
User instructionAuthentication should be provided by youAuthenticate using your Bearer token
Auto behaviorWe store logs for 30 daysLogs are retained for 30 days

Technical Documentation

ContextVoiceExample
Step-by-step instructionActive imperative”Run npm install to install dependencies.”
Default system settingPassive”HTTPS is enabled by default.”
User-triggered actionActive”Click Save to apply your changes.”
Background processPassive”Background jobs are processed every 60 seconds.”
WarningActive”Do not commit your .env file to version control.”

Common Grammar Issues with Passive Voice

The Dangling Passive (No Clear Subject)

“To install the package, the terminal should be opened.”

This is grammatically incorrect passive. Better: ✅ “To install the package, open the terminal.” (active imperative) or: ✅ “The terminal must be open before installing the package.” (clear passive)

The Long Passive Chain

Using passive in multiple consecutive sentences makes writing feel heavy:

“The request is received by the server. The payload is parsed by the middleware. The user is authenticated by the auth module. The response is generated by the handler.”

Break it up with active voice: ✅ “The server receives the request, which is parsed by the middleware. After authentication, the handler generates the response.”

Unnecessary Use of “by” Phrase

When using passive voice, you can include the agent with “by” — but in technical writing, this is often redundant.

“The timeout is configured by the system.” ← who else would configure it? ✅ “The timeout is configurable.”

“This feature was implemented by the engineering team.”“This feature was implemented in v2.4.” ← version is more useful than team name


Quick Reference

SituationVoice
User must perform an actionActive imperative
System does something automaticallyPassive (actor is clear, unimportant)
Describing function/method purposeActive imperative
Error message describing system statePassive
Security advisory describing what happenedPassive
Git commit messagesActive imperative
README installation stepsActive imperative
System behavior in API docsPassive
”You need to do X” instructionActive

Practice Exercises

Rewrite in the appropriate voice:

  1. “The id field should be included by you in every request.”
  2. “We automatically purge records older than 90 days.”
  3. “The user should authenticate their request by using the API key.”
  4. “The cache is invalidated by the system every 5 minutes.”
  5. “Database backups are created every night by the scheduled job.”

Suggested rewrites:

  1. “Include the id field in every request.”
  2. “Records older than 90 days are automatically purged.” (or keep active: precise voice is a style choice)
  3. “Authenticate your request using your API key.”
  4. “The cache is invalidated every 5 minutes.” (remove “by the system” — implicit)
  5. “Database backups are created every night.” (remove “by the scheduled job” — implicit)