---
title: "Solid lumber"
description: "Three stock families with every thickness and width they are actually milled in — metric actuals, never nominal — and the rough allowances the cut list adds."
url: https://kaicad.barpom.xyz/docs/catalogue/solid-lumber
schema: "0.1"
source: packages/catalogue/data/materials/solid-lumber.yaml
---

# Solid lumber

```yaml
materials:
  - id: post_stock
    from: lumber.hardwood.s4s
    species: walnut
    thickness: 75
    width: 75
```

**Every size on this page is actual, not nominal.** These are what the board measures when a
merchant hands it over, which is the only size worth designing to. A thickness that is not on
the list is [`RES-009`](/docs/validation/error-codes#res-009), and the finding names the
nearest two that are — a 35 mm rail is a rail you cannot buy, and finding that out at the
timber yard is worse than finding it out here.

## `lumber.hardwood.s4s`

Hardwood, surfaced four sides.

| | |
| --- | --- |
| **Species** | `walnut` `white_oak` `red_oak` `ash` `maple` `cherry` `beech` `birch` `poplar` |
| **Thicknesses** | 19 · 25 · 32 · 38 · 50 · 63 · 75 mm |
| **Widths** | 50 · 63 · 75 · 100 · 125 · 150 · 175 · 190 · 215 · 240 · 290 mm |
| **Lengths** | 1800 · 2100 · 2400 · 3000 · 3600 mm |
| **Rough allowance** | length 50 · width 6 · thickness 3 mm |
| **Cost** | ≈ 4200 per m³ |

Boards above about 240 mm wide are increasingly hard to find in one piece and usually mean a
glue-up. The width check **warns** rather than errors — it is a procurement problem, not a
design error.

## `lumber.softwood.s4s`

Softwood, planed all round.

| | |
| --- | --- |
| **Species** | `pine` `spruce` `douglas_fir` `western_red_cedar` `larch` |
| **Thicknesses** | 18 · 20 · 25 · 32 · 38 · 45 · 50 · 63 · 75 mm |
| **Widths** | 40 · 45 · 70 · 95 · 120 · 145 · 170 · 195 · 220 · 245 mm |
| **Lengths** | 2400 · 3000 · 3600 · 4200 · 4800 mm |
| **Rough allowance** | length 50 · width 5 · thickness 2 mm |
| **Cost** | ≈ 900 per m³ |

These are **planed** sizes. The sawn size the board is sold under is larger and is not
modelled — a "2 × 4" is 45 × 95 here, because that is what you can measure.

## `lumber.hardwood.rough`

Hardwood, rough sawn. Same species as the surfaced family.

| | |
| --- | --- |
| **Thicknesses** | 25 · 32 · 38 · 50 · 63 · 75 · 100 mm |
| **Widths** | 100 · 125 · 150 · 175 · 200 · 225 · 250 · 300 mm |
| **Lengths** | 1800 · 2100 · 2400 · 3000 · 3600 mm |
| **Rough allowance** | length 75 · width 10 · thickness 6 mm |
| **Cost** | ≈ 3100 per m³ |

Sold rough, so the stated thickness is what you **start** with, not what you finish at. The
allowances are correspondingly larger — 6 mm on thickness, against 3 mm for surfaced stock,
because a rough board has to be flattened before it is anything.

Use this family when you are milling your own. Otherwise use `lumber.hardwood.s4s`.

## Rough allowances and the cut list

The allowance is the extra on each dimension the cut list asks for, so there is enough board
to trim both ends square, joint an edge and flatten a face that has moved.

A part with a finished blank of 2032 × 190 × 38 in `lumber.hardwood.s4s` appears on the cut
list as **2082 × 196 × 41** rough. That is what you buy; the blank is what you cut to.

Sheet goods carry much smaller allowances — 10 mm on length and width, nothing on thickness —
because a sheet arrives flat and stays flat.

## Choosing a size

Two habits worth having.

**Drive the width from the stock, not the other way round.**

```yaml
blank:
  length: deck_length
  width: rail_stock.width          # the full width of the board
  thickness: rail_stock.thickness
```

A rail that uses the full 190 mm of a 190 mm board wastes nothing and does not need ripping.

**Check the length against the available ones.** A 2400 mm part cut from a 2400 mm board
leaves no allowance for trimming. The next length up is the one you want, and the cut list's
rough length will tell you which that is.
