Picture a legacy ERP system where the order entry screen requires 47 clicks to process a single invoice. The backend is fast, the database is normalized, but the help desk receives 300 tickets a month from frustrated users. The system works, but nobody can use it. That’s the gap the System Usability Scale (SUS) quantifies. SUS is a 10-item questionnaire that produces a single score from 0 to 100, measuring how usable a system is from the user’s perspective. Originally published in 1986 by John Brooke, SUS has become the most widely used usability metric in software engineering because it is short, reliable, and technology-agnostic.
In this guide, you’ll learn how to implement SUS correctly in your applications, compute scores without rounding errors, and interpret results against industry benchmarks. We’ll cover database schema design for SUS responses, a Python scoring module, and common failure patterns that invalidate data.
Key Takeaways
- SUS converts 10 Likert responses into a 0–100 score using a specific recoding formula: odd items subtract 1, even items subtract from 5, sum, multiply by 2.5.
- A SUS score of 68 is the average across 500+ usability studies, not a passing grade; scores above 80.8 are considered excellent.
- To avoid invalid data, never rephrase SUS questions, never skip items, and never round before the final multiplication.
What Is the System Usability Scale?
The System Usability Scale (SUS) is a 10-item questionnaire designed to measure perceived usability of a system. It uses a five-point Likert scale ranging from Strongly Disagree to Strongly Agree. Each item alternates between positive and negative statements to reduce response bias. The result is a single number from 0 to 100—but that number is not a percentage. It is a normalized score derived from the raw responses.
Developers often confuse SUS with satisfaction surveys or feature-rating tools. SUS specifically targets usability: effectiveness, efficiency, and satisfaction in a given context. It does not measure whether users like the color scheme or whether a feature is missing. It answers one question: Can users accomplish their tasks without friction?
In software engineering, you can deploy SUS after usability tests of internal dashboards, admin panels, developer tools, or any user-facing interface. Because it takes less than two minutes to complete, it yields high response rates and can be embedded directly into an application.
The 10 SUS Questions Every Developer Should Memorize
The standard SUS questionnaire consists of these ten statements. Participants rate each on a scale of 1 (Strongly Disagree) to 5 (Strongly Agree). The polarity column indicates whether the statement is positive or negative—this matters for scoring.
| # | Statement | Polarity |
|---|---|---|
| 1 | I think that I would like to use this system frequently. | Positive |
| 2 | I found the system unnecessarily complex. | Negative |
| 3 | I thought the system was easy to use. | Positive |
| 4 | I think that I would need the support of a technical person to be able to use this system. | Negative |
| 5 | I found the various functions in this system were well integrated. | Positive |
| 6 | I thought there was too much inconsistency in this system. | Negative |
| 7 | I would imagine that most people would learn to use this system very quickly. | Positive |
| 8 | I found the system very cumbersome to use. | Negative |
| 9 | I felt very confident using the system. | Positive |
| 10 | I needed to learn a lot of things before I could get going with this system. | Negative |
When you expose these questions via an API, represent them as a JSON array. Each item should include an id, statement, and polarity to prevent mismatches on the client.
[
{"id": 1, "statement": "I think that I would like to use this system frequently.", "polarity": "positive"},
{"id": 2, "statement": "I found the system unnecessarily complex.", "polarity": "negative"},
{"id": 3, "statement": "I thought the system was easy to use.", "polarity": "positive"},
{"id": 4, "statement": "I think that I would need the support of a technical person to be able to use this system.", "polarity": "negative"},
{"id": 5, "statement": "I found the various functions in this system were well integrated.", "polarity": "positive"},
{"id": 6, "statement": "I thought there was too much inconsistency in this system.", "polarity": "negative"},
{"id": 7, "statement": "I would imagine that most people would learn to use this system very quickly.", "polarity": "positive"},
{"id": 8, "statement": "I found the system very cumbersome to use.", "polarity": "negative"},
{"id": 9, "statement": "I felt very confident using the system.", "polarity": "positive"},
{"id": 10, "statement": "I needed to learn a lot of things before I could get going with this system.", "polarity": "negative"}
]
SUS Scoring Formula: Step-by-Step Calculation
Scoring SUS is straightforward but error-prone if you skip the recoding step. For each response, you compute a item contribution:
- Odd-numbered items (1,3,5,7,9): contribution = raw response − 1
- Even-numbered items (2,4,6,8,10): contribution = 5 − raw response
Sum all ten contributions, then multiply by 2.5. The multiplication normalizes the total (which ranges from 0 to 40) to a 0–100 scale.
Example: Suppose a user gives responses [4,2,5,1,3,2,4,3,5,1] for items 1–10. Odd contributions: (4-1)+(5-1)+(3-1)+(4-1)+(5-1) = 3+4+2+3+4 = 16. Even contributions: (5-2)+(5-1)+(5-2)+(5-3)+(5-1) = 3+4+3+2+4 = 16. Total = 32. SUS score = 32 × 2.5 = 80.
def calculate_sus(responses: list) -> float:
"""
Calculate SUS score from a list of 10 responses.
responses: list of integers from 1 to 5, in order of items 1-10.
Returns: float SUS score between 0 and 100.
"""
if len(responses) != 10:
raise ValueError("Exactly 10 responses are required.")
for r in responses:
if r not in (1,2,3,4,5):
raise ValueError(f"Invalid response value: {r}. Must be 1-5.")
total = 0
for i, r in enumerate(responses, start=1):
if i % 2 == 1: # odd item
total += r - 1
else: # even item
total += 5 - r
return total * 2.5
# Example usage
responses = [4,2,5,1,3,2,4,3,5,1]
score = calculate_sus(responses)
print(f"SUS Score: {score}") # 80.0
Why SUS Uses Odd Numbered Statements and Recoding
The alternation of positive and negative items is a deliberate psychometric technique. If all statements were positive, respondents who rush or agree with everything would inflate their scores. Mixing polarities forces engagement and reduces acquiescence bias—the tendency to agree regardless of content.
Recoding negative items (reversing the scale) aligns them with positive items so that higher numbers always indicate higher usability. This makes the sum meaningful. Without recoding, a user who finds the system excellent would produce a low total because the negative items would be low.
Multiplying by 2.5 serves two purposes: it converts the 0–40 sum to a 0–100 range, making the number more intuitive for stakeholders, and it preserves the distribution shape. However, SUS is not a percentage. A score of 70 does not mean “70% usable.” It means the user’s responses, when transformed, landed at 70 on a scale defined by the instrument.
Understanding this design prevents developers from “simplifying” the questionnaire by making all items positive or changing the response labels. Any modification invalidates the instrument.
Statistical Validity: What the Research Actually Shows
SUS is one of the most validated usability questionnaires. A 2011 meta-analysis by Sauro and Lewis aggregated data from over 500 studies and found that SUS has a reliability coefficient (Cronbach’s alpha) above 0.90, indicating excellent internal consistency. This means the ten items measure the same underlying construct—usability—without excessive noise.
The same analysis established that the average SUS score across studies is 68. This figure has become the de facto benchmark: any product scoring below 68 falls below the 50th percentile. To contextualize, a system with a SUS score of 80 is in the top 10% of systems tested.
| Metric | Number of Items | Typical Score Range | Reported Reliability | Common Use Case |
|---|---|---|---|---|
| SUS | 10 | 0–100 | α > 0.90 | Quick usability snapshot |
| PSSUQ | 16 | 1–7 (mean) | α = 0.94 | Post-task or post-study |
| UMUX | 4 | 0–100 | α = 0.85–0.90 | Shorter alternative to SUS |
| NPS | 1 | -100 to 100 | Not applicable | Loyalty, not usability |
| CSAT | 1–3 | 1–5 (mean) | Varies | Overall satisfaction |
Note that SUS is unidimensional for practical purposes, even though factor analyses sometimes reveal two subscales (usability and learnability). The total score remains the recommended metric.
When to Use SUS: Appropriate Contexts in Software Projects
SUS works best as a periodic health check for a system after users have had enough exposure to complete real tasks. In a development lifecycle, you should collect SUS responses:
- After a usability test of a new feature or prototype
- At the end of a beta testing phase before general release
- Quarterly for internal tools to track usability drift
- When comparing two design alternatives during A/B testing
Do not use SUS to measure feature-specific feedback (“Was the export button easy to find?”), overall product satisfaction, or long-term engagement. Those require different instruments. Also avoid surveying the same users too frequently—response fatigue will lower quality and inflate scores due to acquiescence.
For developer-facing tools like APIs or CLIs, SUS still applies because it measures perceived usability of the interface, even if the “interface” is a command line. However, you may need to adapt the wording of items to fit the context without changing meaning—a practice that requires validation.
Capturing SUS Responses: API and Database Design
When you build SUS collection into your application, treat responses as structured data. A REST endpoint POST /api/sus-responses should accept a JSON payload with the ten raw responses and a session identifier. The backend validates that exactly 10 integers between 1 and 5 are present.
curl -X POST https://api.example.com/sus-responses \
-H "Content-Type: application/json" \
-d '{
"session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"responses": [4,2,5,1,3,2,4,3,5,1]
}'
For storage, use a normalized relational schema. Each row represents one item response from one user. This allows flexible aggregation and historical analysis.
CREATE TABLE sus_responses (
id BIGSERIAL PRIMARY KEY,
user_id UUID REFERENCES users(id) ON DELETE SET NULL,
session_id UUID NOT NULL,
question_id SMALLINT NOT NULL CHECK (question_id BETWEEN 1 AND 10),
response SMALLINT NOT NULL CHECK (response BETWEEN 1 AND 5),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_sus_responses_session ON sus_responses(session_id);
CREATE INDEX idx_sus_responses_created ON sus_responses(created_at);
If you need to store the entire submission as a JSON document (e.g., in a NoSQL store), keep the same data shape and validate on read. But the relational approach makes it easier to compute item-level statistics and detect response patterns.
Implementing SUS Calculation in Python and SQL
The Python function from the scoring section covers the core logic. For production systems, you will also need SQL aggregation to compute average SUS scores across users or time periods. The following query assumes the table from the previous section and computes the average SUS score per session.
SELECT
session_id,
(SUM(
CASE WHEN question_id % 2 = 1 THEN response - 1
ELSE 5 - response
END
) * 2.5) AS sus_score
FROM sus_responses
GROUP BY session_id
HAVING COUNT(*) = 10;
To get a rolling average over the last 30 days, wrap the above as a subquery:
SELECT AVG(sus_score) AS avg_sus_last_30_days
FROM (
SELECT session_id,
(SUM(
CASE WHEN question_id % 2 = 1 THEN response - 1
ELSE 5 - response
END
) * 2.5) AS sus_score
FROM sus_responses
WHERE created_at > NOW() - INTERVAL '30 days'
GROUP BY session_id
HAVING COUNT(*) = 10
) AS session_scores;
Interpreting SUS Scores: Benchmarks and Percentiles
Because SUS is not a percentage, raw scores are best interpreted via percentile ranks derived from the benchmark dataset of Sauro & Lewis. The most commonly used grade scale is:
| SUS Score Range | Grade | Percentile Range |
|---|---|---|
| 84.1 – 100 | A+ | 96th – 100th |
| 80.8 – 84.0 | A | 90th – 95th |
| 78.9 – 80.7 | A- | 85th – 89th |
| 77.2 – 78.8 | B+ | 80th – 84th |
| 74.1 – 77.1 | B | 70th – 79th |
| 72.6 – 74.0 | B- | 65th – 69th |
| 71.1 – 72.5 | C+ | 60th – 64th |
| 65.0 – 71.0 | C | 41st – 59th |
| 62.6 – 64.9 | C- | 35th – 40th |
| 51.7 – 62.5 | D | 15th – 34th |
| 0 – 51.6 | F | 0 – 14th |
These bands are based on the distribution of SUS scores across hundreds of studies. A score of 68 lands at the 50th percentile—average. A score of 80 is roughly the 90th percentile, which most teams consider excellent. When you report SUS results, always include the percentile or grade alongside the raw number to avoid misinterpretation.
Common Mistakes When Deploying SUS in Production
Most invalid SUS data comes from implementation mistakes, not from user behavior. The most damaging errors:
- Rephrasing questions to make them more “modern” or “contextual” without revalidation. The original wording is part of the instrument’s validity.
- Omitting the recoding step and simply averaging raw responses. That produces a meaningless number.
- Rounding item contributions before summation, which introduces up to 5 points of error.
- Allowing partial responses and then normalizing as if all ten were answered. SUS requires all ten responses to be valid.
- Changing the Likert labels (e.g., from “Strongly Disagree” to “Not at all”). The anchors affect response distribution.
To catch these errors, build automated tests for your scoring function. A unit test should verify that the response set [3,3,3,3,3,3,3,3,3,3] yields exactly 50, and that [5,1,5,1,5,1,5,1,5,1] yields 100.
Comparing SUS to Other Usability Metrics
SUS is not the only questionnaire available. Choosing the right one depends on your constraints: questionnaire length, target construct, and whether you need a benchmark. The following table summarizes key alternatives.
| Metric | Items | Score Range | Reliability | Time to Complete | Best For |
|---|---|---|---|---|---|
| SUS | 10 | 0–100 | α > 0.90 | ~2 min | General usability, benchmarking |
| PSSUQ | 16 | 1–7 (mean) | α = 0.94 | ~4 min | Post-task or post-study usability |
| UMUX | 4 | 0–100 | α = 0.85–0.90 | ~1 min | When survey fatigue is a concern |
| UMUX-LITE | 2 | 0–100 | α = 0.82–0.86 | <1 min | Extremely short usability measure |
| NPS | 1 | -100 to 100 | N/A | <30 sec | Loyalty, not usability |
| CSAT | 1–3 | 1–5 (mean) | Varies | <1 min | Overall satisfaction |
For most software teams, SUS hits the sweet spot between length, reliability, and benchmark availability. UMUX-LITE is a viable alternative if you need a two-item questionnaire and can calibrate its scores to SUS using a conversion formula (Sauro & Lewis provide one). However, SUS remains the default because of its extensive normative database.
Advanced: Building a SUS Analytics Dashboard
Once SUS data flows into your database, you need a dashboard to monitor usability over time. A typical architecture uses a relational store for raw responses, a materialized view for aggregation, and a frontend that queries the view via REST or GraphQL.
To avoid expensive real-time aggregation on large datasets, create a materialized view that precomputes SUS scores per session:
CREATE MATERIALIZED VIEW sus_session_scores AS
SELECT
session_id,
user_id,
(SUM(
CASE WHEN question_id % 2 = 1 THEN response - 1
ELSE 5 - response
END
) * 2.5) AS sus_score,
created_at
FROM sus_responses
GROUP BY session_id, user_id, created_at
HAVING COUNT(*) = 10;
CREATE INDEX idx_sus_session_scores_created ON sus_session_scores(created_at);
Refresh the view periodically (e.g., every hour) or after each batch of submissions. Then your dashboard query becomes trivial:
SELECT
DATE_TRUNC('week', created_at) AS week,
AVG(sus_score) AS avg_sus,
COUNT(*) AS sample_size
FROM sus_session_scores
GROUP BY week
ORDER BY week;
Further Reading on Software Development
This guide covered the System Usability Scale from a backend engineering perspective, but software development involves many intertwined disciplines. For more in-depth articles on building reliable, maintainable systems, check the full software development knowledge base.
Explore our complete Software Development directory for more guides.
The System Usability Scale is a lightweight, statistically robust tool that belongs in every software engineer’s measurement toolkit. When implemented correctly—with the original 10 items, proper recoding, and raw data storage—SUS gives you a comparable, longitudinal metric for product usability. The most common failures are avoidable: don’t rewrite questions, don’t skip validation, and don’t round early.
If your team is modernizing a legacy system and needs to introduce usability measurement or build analytics infrastructure for SUS data, NR Studio can help. We specialize in migrating legacy systems and instrumenting them with proper data pipelines. Request a migration consultation to discuss your stack and timeline.
NR Studio builds custom web apps, mobile apps, SaaS platforms, and internal tools for growing businesses. If you’re working through a technical decision, feel free to reach out — no commitment required.