Beancount.io LogoBeancount.io

Custom Cabinet and Millwork Shop Bookkeeping: ASC 606, Job Costing, and Section 179

14 min readMike ThriftMike Thrift
Custom Cabinet and Millwork Shop Bookkeeping: ASC 606, Job Costing, and Section 179

A 2,400-square-foot custom kitchen with frameless inset doors, walnut veneer panels, and dovetailed drawer boxes can take ten weeks to design, build, finish, and install. During those ten weeks, a cabinet shop pays for hardwood lumber, sheet goods, hardware, finish materials, CNC time, edgebander time, bench labor, finisher labor, and installer labor — all before the homeowner writes the final check. If the bookkeeping for that job lives on a yellow legal pad and a stack of supplier invoices, the shop owner has almost no idea whether the project is making money until weeks after the truck leaves the driveway.

That gap between "we delivered it" and "we know what it cost" is what separates millwork shops that grow into eight-figure operations from those that stay perpetually one bad job away from a payroll crisis. This guide walks through the accounting and bookkeeping practices that custom cabinet and architectural millwork shops need to recognize revenue properly under ASC 606, allocate machine-hour burden to each job, hold customer deposits as the liabilities they actually are, track hardwood yield loss against grade and species, capitalize equipment under Section 179, and read the throughput-per-linear-foot KPIs that lenders and acquirers care about.

Why Custom Millwork Accounting Is Different From Carpentry

A finish carpenter who installs pre-built cabinets has relatively simple bookkeeping. Revenue is per job, labor is on the truck, and materials are a markup on supplier invoices. A custom cabinet shop is a manufacturer that also happens to install — and manufacturing accounting has more moving parts.

Specifically, a millwork shop has to account for:

  • Long-lead contracts that span weeks or months, requiring revenue to be recognized over time rather than at delivery.
  • Customer deposits taken at design approval, lumber order, and pre-finish stages that are not revenue until the performance obligation is satisfied.
  • Raw material inventory in dozens of species, sheet thicknesses, and grades that lose 20-50 percent of their volume to defect cull, ripping, and rounding.
  • Machine-hour burden on CNC routers, beam saws, edgebanders, and finish lines that must be loaded onto each job to know its true cost.
  • Bench labor versus finisher labor versus installer labor, each with different productive hours per week and different burden rates.
  • Reserves for callback and warranty repairs that may surface six months after the homeowner has moved in.

Get those mechanics right and the financial statements actually mean something. Get them wrong and every job looks profitable on the invoice while the bank account quietly drains.

Recognizing Revenue Under ASC 606 Percentage-of-Completion

The default revenue recognition framework under U.S. GAAP is ASC 606, which asks a sequence of five questions: Is there a contract? What are the performance obligations? What is the transaction price? How is the price allocated? When are the obligations satisfied?

For custom cabinetry, the answer to the fifth question is usually "over time." A custom kitchen has no alternative use to the shop — those frameless walnut doors will not fit anybody else's wall — and the shop typically has a contractual right to payment for work performed to date. Both conditions are tests under ASC 606 that, when met, require revenue to be recognized over time rather than at a single point of delivery.

The Cost-to-Cost Input Method

The most common way millwork shops measure progress is the cost-to-cost input method: the percentage of total estimated costs incurred to date determines the percentage of revenue recognized. If a kitchen has an estimated total cost of $24,000 and the shop has incurred $9,000 of that, then 37.5 percent of the contract revenue is recognized.

A few practical traps:

  • Uninstalled materials don't count as progress. Under ASC 606, sheet goods sitting on the rack waiting to be cut do not represent progress toward satisfying the performance obligation. If the customer hasn't taken control of those materials, you generally cannot include their cost in the numerator of the cost-to-cost calculation. Many shops handle this by tracking lumber and sheet inventory separately and only moving cost into the job once material is processed.
  • Pre-contract design costs for a job that hasn't been signed should not be capitalized as work-in-process. They are typically marketing or design expense until the contract is executed.
  • Change orders modify both the transaction price and the estimated total cost. Re-run the percentage immediately when a change order is approved, or the percentage drifts and revenue gets misstated.

The Practical WIP Schedule

A work-in-process schedule for a millwork shop typically tracks, for each open job:

ColumnWhat it means
Contract priceSigned value including approved change orders
Estimated total costMaterials + labor + machine burden + sub-installer
Cost to dateActual incurred through period end
Percent completeCost to date / estimated total cost
Revenue earned to dateContract price × percent complete
Billings to dateTotal invoiced (deposits + progress + final)
Over/under billingEarned minus billed

The over/under billing column is what your lender will read first. Over-billings are a contract liability (you've collected more than you've earned), and under-billings are a contract asset (you've earned more than you've collected). Shops chronically over-bill on early-stage work and find themselves needing to deliver that earned-but-unbilled work without enough cash. Watching this schedule weekly turns surprises into early warnings.

Customer Deposits Are Liabilities, Not Revenue

This is the single most common bookkeeping error in custom cabinet shops, and it usually compounds quietly until tax season. When a homeowner writes a 50 percent deposit check at design approval, that cash hits the bank account but it is not revenue. The shop has not yet earned anything — it owes the customer a kitchen.

The correct accounting:

Dr. Cash                            $12,000
   Cr. Customer Deposit Liability             $12,000

As the job progresses and revenue is recognized under ASC 606, the deposit gets drawn down:

Dr. Customer Deposit Liability      $4,500
   Cr. Contract Revenue                       $4,500

Shops that treat deposits as revenue end up paying income tax on money they haven't earned, overstate their profitability to their banker, and have no early warning when their unfinished obligations exceed their cash. Worse, if the customer cancels, that liability turns into either a refund or — in most states — a non-refundable portion that has to be recognized as revenue at the cancellation moment, not when collected.

A clean chart of accounts for a millwork shop typically separates:

  • Design deposits (often non-refundable, recognized when design phase is complete)
  • Production deposits (collected before material order, drawn down over WIP)
  • Progress payments (collected at fabrication milestones)
  • Final payments (collected at install completion)
  • Retention/holdback (common on commercial work, recognized when released)

Hardwood and Sheet Good Inventory Tracking

A serious millwork shop carries inventory in three buckets: rough lumber by species and grade, sheet goods by core type and thickness, and hardware/finish consumables. Each bucket needs its own accounting treatment.

Rough Lumber

Hardwood lumber is sold and tracked in board feet, with grade defined by the National Hardwood Lumber Association. The NHLA grading system tells you not just what the boards look like but how much usable material you can cut from them. Select grade yields about 83 percent clear face cuttings, Number 1 Common yields about 67 percent, and Number 2 Common yields about 50 percent. A shop that buys Number 1 Common because it's cheaper but estimates jobs as if every board yielded 100 percent is silently losing 33 cents on every lumber dollar.

For bookkeeping, rough lumber inventory should be carried at landed cost — the invoice price plus inbound freight — and counted at least annually. Shops that build jobs in expensive species like walnut, white oak, or rift-and-quartered material should consider monthly cycle counts because the dollar concentration is high and shrinkage is easy to miss.

Sheet Goods

Plywood, MDF, melamine, and particleboard come in standard 4×8 and increasingly 5×10 sheets, with cost varying by core, face species, and grade. A shop running a nested-based CNC operation can track sheet yield directly through the CNC software — most modern nesting programs report material utilization per program — and that number should flow back into the job cost.

A practical convention: charge each job for the sheets it consumed plus an allocation of drop and offcut, and run a periodic reconciliation between physical sheet inventory and the cumulative draw across open jobs. Any unexplained gap is either theft, mis-cuts, or sheets being used for shop fixtures and samples.

Yield Loss Reserves

For architectural millwork in particular, waste of 30-50 percent is normal once you account for ripping to width, end-cut defect removal, tally rounding by the lumber supplier, and color-matching cull on stain-grade work. Estimates that do not include a realistic waste factor will be chronically underpriced. Some shops bake the waste into the per-board-foot cost; others carry a separate "lumber yield variance" account that captures the difference between theoretical and actual consumption and gets analyzed quarterly.

Job Costing and Machine-Hour Burden

Every job in a millwork shop consumes machine time on specific pieces of equipment — and those machines have radically different cost structures. A CNC router with a $180,000 sticker price, a fume hood, a vacuum table, and a tool changer costs vastly more per hour to operate than a sliding table saw.

Calculating a Burden Rate

A defensible machine-hour rate for a piece of equipment includes:

  • Depreciation (purchase price minus salvage, divided by expected productive hours over useful life)
  • Maintenance (typically 2-10 percent of purchase price per year, depending on equipment)
  • Tooling consumables (router bits, saw blades, sanding belts) divided by hours
  • Power and compressed air
  • Floor space allocation (rent and utilities × percent of floor occupied)

For shops that have never calculated this, the eye-opening exercise is to compute the burden rate for the CNC router and compare it to what the shop is charging per hour of CNC time on a quote. It is common to find that the implicit rate on quotes is 30-50 percent below the real burden.

Loading Burden Onto Jobs

Once a per-hour burden is set for each machine, the bookkeeping question is how to capture the hours. The cleanest approach is to have the operator clock onto each job at the machine, either through a time-tracking system that integrates with the ERP or through manual time tickets that get keyed in daily. The cost flows through as:

Dr. WIP — Job 247                    $315
   Cr. Manufacturing Overhead Applied         $315

At month-end, applied overhead is compared to actual overhead, and the variance is closed out — either to cost of goods sold or pro-rated across WIP, finished goods, and COGS depending on materiality.

Bench Labor Versus Finishing Versus Installation

The three labor pools in a millwork shop have very different effective rates because the productive-hour ratio varies. A bench worker is usually productive about 75-80 percent of the clock; a finisher might be 60-70 percent because of dry times and gun cleanup; and an installer might be 50-60 percent because of drive time and customer interruptions.

Burden the labor accordingly. A $32-per-hour finisher who is actually productive 65 percent of the time costs the job about $49 per productive hour, before any overhead allocation. Estimates that use a flat $32 will lose money on every finishing-heavy job.

Capitalizing Equipment Under Section 179 and Bonus Depreciation

A working cabinet shop owns a lot of capital equipment: CNC routers, beam saws, edgebanders, wide-belt sanders, dust collection systems, spray booths, drying racks, compressors, and forklifts. For 2026, the Section 179 deduction limit is $2,560,000, with phase-out beginning at $4,090,000 of total qualifying purchases. That means almost any shop in the country can fully expense the equipment it buys, rather than depreciating it over five or seven years.

A few practical considerations:

  • Dust collection systems qualify as tangible business equipment when they are installed and operational. The treatment is the same as the saw or sander that produces the dust they collect.
  • Spray booths and finishing rooms generally qualify, though built-in structural components like booth enclosures may need to be analyzed for whether they are personal property or real property. A cost segregation study at construction can break those out.
  • Vehicles for delivery and installation often qualify under separate rules for over-6,000-pound GVWR work trucks.
  • The equipment has to be placed in service during the tax year, not just ordered. Many shop machines have 8-16 week lead times, so a December purchase decision usually means a current-year deduction is impossible. Plan capex by Q3 if the timing matters.
  • Bonus depreciation at 100 percent (currently) can cover anything above the Section 179 limit or in years where the business has a loss, since Section 179 cannot create a net operating loss but bonus depreciation can.

For a comprehensive walkthrough of how Section 179 and bonus depreciation interact, see the Section 179 deduction guide on Beancount.io.

Callback and Warranty Reserves

Every cabinet shop gets callbacks. A finish issue surfaces three months in. A drawer slide fails. A panel develops a crack from seasonal humidity. Most shops eat these costs informally — the installer drives back out with a touch-up kit, the owner doesn't think about it again.

A more disciplined approach is to estimate the historical callback rate as a percentage of revenue (often 0.5-2 percent for cabinet work, higher for commercial millwork with public-use environments) and accrue a warranty reserve as jobs are completed:

Dr. Warranty Expense                $850
   Cr. Warranty Reserve Liability             $850

When the callback happens, the cost hits the liability, not current-period expense. The result is that callback costs get matched against the revenue that generated them, jobs from prior periods don't quietly hurt this year's P&L, and the owner has a quantified number to negotiate against when an acquirer or lender asks about hidden liabilities.

Reading the KPIs That Lenders and Acquirers Care About

When a millwork shop applies for a working-capital line, refinances equipment, or talks to a private equity acquirer, the buyer or banker will ask for specific operational metrics that go beyond gross margin.

Throughput per linear foot installed. For cabinet work, dividing total contract revenue by linear feet of cabinetry produced is a quick benchmark. Premium custom kitchens often run $1,000-$2,000 per linear foot; high-end commercial work can exceed $2,500. A shop whose number is drifting down quarter over quarter is either pricing wrong or losing premium customers.

Labor recovery. The ratio of billed labor hours to clocked labor hours, expressed as a percentage. A healthy shop runs 80-95 percent labor recovery. Anything below 70 percent means the shop is absorbing significant unbilled rework, training, or non-productive time.

WIP turns. Average WIP balance divided by quarterly cost of goods sold. Shops that turn WIP four to six times per year are running efficiently; shops at one to two turns have jobs sitting too long in fabrication or finishing.

Backlog months. Signed contract value not yet built, divided by monthly revenue. Two to four months of backlog is healthy; six-plus months means quote-to-cash is too slow and customers may walk; under one month means the next payroll is uncertain.

Gross margin by job type. Residential remodel, new construction, commercial millwork, and reception/conference room work often have wildly different margin profiles. Tracking them separately reveals which channel is actually paying the bills.

Keep Your Shop's Books in Plain Text

The bookkeeping practices in this guide — separating customer deposits as liabilities, tracking WIP by job, allocating machine-hour burden, reserving for warranty — depend on a chart of accounts that is rich enough to capture the detail and a journal that you can actually trust. Beancount.io provides plain-text accounting that gives custom cabinet and millwork shop owners complete transparency over their books, with every transaction stored in a version-controlled file you can audit, query, and hand to your CPA without surprises. Get started for free and see why builders and finance professionals are switching to plain-text accounting.