A bid tab — short for bid tabulation — is the grid you build when a scope package comes back with 5 to 15 sub bids and you need to see them all at once. Bidders run across the top, line items run down the side, and a price sits in every cell. It looks like a spreadsheet anyone could read, and that is the trap: a tab is easy to look at and easy to misread. The cheapest column is not always the one you should award, and a clean-looking grid can hide a $200K scope hole. Reading a tab well means knowing which cells to trust, which to question, and how the rows relate to each other. If you want the full mechanics of building one, the construction bid tabulation page walks through it; this article is about reading a tab that already exists.
Anatomy of a bid tab
Strip a tab down and it has three structural parts. Get oriented to these before you read a single price.
Bidders across the top
Every column is one subcontractor's bid for the same scope package. A heavy-civil package typically returns 5 to 15 of them, plus a column or two you should always have: the engineer's estimate or your internal budget, and — on a well-built tab — a peer-median column. The bidder columns are usually ordered left to right by total price, lowest first, which is where the first misread happens. The leftmost column is the lowest number, not necessarily the lowest bid, because those totals may not be measuring the same scope yet.
Line items down the side
Each row is one scope item: "Unclassified Excavation," "12-inch RCP," "Mobilization," "Traffic Control." On a leveled tab these rows are your scope of work, in your order, with every bidder's price mapped onto your line whether or not the sub used your wording. On a raw tab the rows are whatever the first bidder happened to call things, and the other columns are stuffed in next to them as best anyone could. That difference — whose rows are these, really — decides whether the grid is honest.
The totals row
The bottom of the tab carries each bidder's total — the number everyone looks at first and trusts most. Treat it as the least trustworthy number on the page until you have read the rows above it. A total is a sum of cells, and if any cell is blank because the sub didn't price an item, the total is low for a reason that has nothing to do with the sub being cheap. The totals row is a conclusion. The line items are the evidence. Read the evidence first.
Reading across a row
The real work of reading a tab happens left to right, one line item at a time. Take a single row — say "12-inch RCP, 1,400 LF" — and read every bidder's unit price across it. Five subs cluster between $78 and $94 per linear foot; one sits at $41; one at $210. You have not done any math yet and the row is already talking to you. The cluster is the market. The $41 and the $210 are questions.
Computing the peer median
To turn that instinct into something you can defend, compute the peer median for the row: line up every bidder's unit price for that item, sort them, and take the middle value. Use the median, not the average, because one wild number — that $210 — drags an average around but barely moves a median. The median is the row's honest benchmark, the number a typical bidder charges for that work on this job. This is peer-median normalization, and it is what lets a tab work in any market without needing a published cost book: the bidders themselves define what the work is worth, and each price is read against that benchmark rather than against an outside table.
Spotting outliers
With the median in hand, the outliers name themselves. A price 2x the peer median or more, or half of it or less, is a bid outlier — the $41 (exactly 0.5x of an $82 median) and the $210 (2.6x) both qualify on our RCP row. An outlier is not automatically wrong; it is a flag that forces a look. The high one might be a sub who read a harder install into the plans, or a typo. The low one might be a real efficiency, or a quantity the sub misread that comes back as a change order the day they hit it. Watch for one more thing the median does not catch: a unit price of a dollar or less on a real item. That is an unbalanced bid — cost shifted off that line and parked where the sub expects the quantity to grow. Reading across rows, not just down columns, is the only way these surface.
Raw tab versus leveled tab
This is the distinction that separates a tab you can award from a tab that will hurt you. A raw tab is the grid you get by dropping each bid's numbers into columns as they arrived. It is fast to assemble and it is mostly a layout exercise — the prices are real, but nobody has checked that the rows line up across columns. A leveled tab is the same grid after the reconciliation work: every line item normalized to your scope, units converted so a per-CY price and a lump sum for the same work sit on the same row, and each bidder's coverage checked against the full scope so the blanks are visible and labeled.
The gap between the two is where money hides. On a raw tab, Sub A's $1.20M and Sub B's $1.35M look like a clean $150K spread. Level them and you find Sub A's column has no row for dewatering and no row for traffic control — items Sub B priced and Sub A didn't carry. Add those back at the peer median and Sub A is no longer low; it is low by exactly the amount of scope it left out. A raw tab told you A wins. A leveled tab told you A has a $190K hole. Same prices, same grid, opposite decision — which is why a tab is only as honest as the leveling behind it.
Why columns must measure the same scope
Everything above rests on one rule: a column comparison is only valid when the columns measure the same scope. When Sub A's total covers 38 scope items and Sub B's covers 41, the totals row is comparing a 38-item bid to a 41-item bid and calling the smaller one cheaper. It isn't cheaper; it is smaller. Leveling exists to force every column onto the same scope footing so that, when you finally read the totals row, you are comparing like to like.
Practically, this means three checks before you trust any column total. First, does every bidder have a price (or a noted exclusion) on every scope row? A blank is a gap, and a gap is a future change order with that sub's name on it. Second, are the units consistent down each row, so you are not reading dollars-per-cubic-yard against a lump sum? Third, did a sub add rows nobody else priced? Extras inflate a column the same way gaps deflate one, and both distort the comparison. Only after those checks does the totals row mean what it appears to mean.
A reading checklist
Put together, reading a finished tab is a short, repeatable pass:
- Confirm the rows are your scope. If the line items are one bidder's catalog instead of your scope of work, you are reading a raw tab — level it first.
- Scan for blanks. Every empty cell on a real scope row is a coverage gap. Note which column it belongs to.
- Read across each row. Find the peer median, then mark anything at 2x or more, or 0.5x or less, of it, and any unit price at a dollar or less.
- Check the mobilization row. Mobilization at 10% or more of a bidder's total is cash pulled forward — front-loaded, and worth a question.
- Compare totals against the field. A total 20% or more off the field's median total is usually a scope misunderstanding, not a deal or a gouge.
- Read the totals row last. Only after the rows check out does the bottom line tell you who is actually low.
None of these checks decides the award on its own. Each one turns a number into a question with a name attached, and the answers — not the leftmost column — are what you defend later.
What the software does to the tab
Bid Reasoner reads the sub bids a GC receives and builds the leveled tab for you. It lines up each bidder's line items against your scope of work by pay-item code and computes the peer median for every pay item that at least three bids price, so each outlier flag shows the median it was measured against — a baseline taken from the bids themselves, so it works in any US state with no government data required. It applies four deterministic pricing rules to every bid it has read — unbalanced unit prices at or below $1.00, peer outliers at 2x or more, or 0.5x or less, of the median (3+ bids), total-bid outliers 20% or more off the median total (3+ bids), and front-loaded mobilization at 10% or more of total — and runs a two-way scope-coverage gap analysis that surfaces the missing and extra items per bidder. Each pricing-rule flag names the pay item (or the bid total, or the mobilization share) and the numbers that tripped the rule, so you can check that line in the sub's bid yourself.
That is the point of reading a tab carefully in the first place: to award the bid that is actually lowest and responsible, not the one that merely looks lowest. If your tabs currently live in a spreadsheet you assemble by hand, the construction bid tabulation workflow is built to replace exactly that, leveling included, so the grid you read is one you can trust.