Researching Salary Ranges
Read at your own pace. Code execution, quizzes, progress tracking, and the AI tutor are available in the interactive view with JavaScript enabled.
From Mindset To Market
Why this lesson matters
In Introduction to Salary Negotiation, you framed negotiation as a normal business conversation—not a single scary number or a personal confrontation.
Now we move from mindset to evidence.
Before you decide what to ask for, you need to know the market range for the role: what employers are actually paying people with similar skills, level, location, and scope.
Think of it like evaluating a veteran developer’s production: one highlight reel is not enough. You want comparable data across teams, seasons, and conditions.

Define The Comparable
Research starts with matching the role
Salary data is only useful when the comparison is tight.
For a senior C++ engineer, these variables can change compensation dramatically:
- Level: senior, staff, principal, engineering manager
- Function: backend, embedded, infrastructure, quant, game engine, systems
- Location: remote, hybrid, city, country, cost-of-labor market
- Industry: fintech, defense, big tech, healthcare, media, startups
- Company stage: seed startup vs. public company
- Comp type: base salary, bonus, equity, total compensation
Your goal in this lesson is not yet to choose your personal minimum. That comes next. Your goal here is to build a defensible market range for the role.

Best Comparable
You are researching pay for a senior C++ backend engineer role at a financial technology company in New York City.
Which data point is the strongest comparable?
Build Source Stack
Use multiple sources, not one magic number
No single source is perfect. Strong research triangulates across several types of evidence.
Useful sources include:
- Job postings with salary bands — often the clearest current employer signal
- Compensation databases — levels.fyi, Glassdoor, Built In, Blind, Payscale, etc.
- Government or labor data — broader, slower-moving, but useful for baseline context
- Recruiter conversations — especially for current hiring-market ranges
- Peer network data — useful when specific and recent, but handle confidentially
- Company-specific reports — best when role and level match closely
A good stack gives you a range that is harder to dismiss: “I reviewed current postings, compensation databases, and recruiter input for comparable senior backend roles.”

Normalize The Data
Compare apples to apples
Salary research gets messy because sources report different things.
Before analyzing, normalize the data:
- Separate base salary from bonus and equity
- Convert hourly or contract rates to annual equivalents only when appropriate
- Note whether numbers are self-reported or employer-published
- Adjust for location only if the employer uses location-based pay
- Remove records that clearly do not match your level or function
For a coding-minded learner, treat this like cleaning an input dataset before running an algorithm.
```cpp
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
struct SalaryRecord {
std::string source;
int base;
int bonus;
int annualEquity;
};
int main() {
std::vector<SalaryRecord> records = {
{"Employer posting", 185000, 15000, 0},
{"Comp database", 178000, 22000, 35000},
{"Recruiter range", 190000, 20000, 25000}
};
std::cout << "Normalized total annual compensation estimates:\n";
for (const auto& r : records) {
int total = r.base + r.bonus + r.annualEquity;
std::cout << "- " << r.source << ": $" << total << "\n";
}
return 0;
}
```
One Number Trap
True or false:
If one salary site shows a top number of $260,000 for the role, you can treat $260,000 as the reliable market range by itself.
Use Robust Statistics
Look for the center and spread
Salary data often has outliers. A few very high total-comp packages can pull the average upward, while outdated or under-leveled records can pull it downward.
Useful summary points:
- Median: the middle value; often more stable than the average
- 25th percentile: lower end of common market range
- 75th percentile: upper end of common market range
- Outliers: values that need explanation before you rely on them
The goal is not mathematical perfection. The goal is a range you can explain clearly.
```cpp
#include <algorithm>
#include <iostream>
#include <vector>
int percentile(std::vector<int> values, double p) {
std::sort(values.begin(), values.end());
double index = p * (values.size() - 1);
int lower = static_cast<int>(index);
int upper = std::min(lower + 1, static_cast<int>(values.size() - 1));
double weight = index - lower;
return static_cast<int>(values[lower] * (1 - weight) + values[upper] * weight);
}
int main() {
std::vector<int> baseSalaries = {
165000, 172000, 178000, 182000, 187000,
190000, 196000, 205000, 215000, 260000
};
std::cout << "25th percentile: $" << percentile(baseSalaries, 0.25) << "\n";
std::cout << "Median: $" << percentile(baseSalaries, 0.50) << "\n";
std::cout << "75th percentile: $" << percentile(baseSalaries, 0.75) << "\n";
return 0;
}
```
Middle Value
In a sorted list of salary data, the middle value is called the ______.
Weight The Evidence
Some evidence deserves more confidence
Not every source should influence your thinking equally.
A current employer-posted range for the same level and location is usually stronger than an anonymous, three-year-old self-report. A recruiter’s range may be useful, but you still want to know whether it refers to base salary or total compensation.
You can mentally weight sources by asking:
- Is it recent?
- Is it role-specific?
- Is it level-specific?
- Is it location-specific?
- Is it transparent about base, bonus, and equity?
This keeps your research grounded instead of turning into a Stephen King-style mystery where the scariest number dominates the plot.
```cpp
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
struct SourceEstimate {
std::string name;
int low;
int high;
double confidenceWeight;
};
int main() {
std::vector<SourceEstimate> sources = {
{"Current job postings", 175000, 215000, 0.40},
{"Compensation database", 170000, 230000, 0.30},
{"Recruiter conversations", 185000, 225000, 0.20},
{"Older peer reports", 160000, 210000, 0.10}
};
double weightedMidpoint = 0.0;
for (const auto& s : sources) {
double midpoint = (s.low + s.high) / 2.0;
weightedMidpoint += midpoint * s.confidenceWeight;
}
std::cout << std::fixed << std::setprecision(0);
std::cout << "Weighted market midpoint estimate: $" << weightedMidpoint << "\n";
return 0;
}
```
Your Research Brief
Turn research into a negotiation asset
By the end of this step, create a short market brief you can actually use.
Include:
- Target role: title, level, function, location, industry
- Sources used: at least 3 credible categories
- Date range: when the data was collected
- Comp type: base salary vs. bonus vs. equity vs. total compensation
- Observed range: realistic lower and upper market bounds
- Most defensible midpoint: the number your evidence clusters around
- Caveats: mismatched levels, old data, unclear equity values, location uncertainty
This brief becomes the input for the next lesson, Determining Your Personal Salary Range, where you will connect market evidence to your own priorities and boundaries.
