Skip to main content

What are you looking for?

Explore our services and discover how we can help you achieve your goals

Print pricing is a function, not a price list

Print pricing is a function of size, quantity, substrate, finishing, turnaround and waste, not a static price list. A spreadsheet matrix tries to pre-compute every combination and breaks as variables multiply. The fix is to model pricing as a tested function with named inputs, checked against known-good quotes before it ships.

Start a project brief Explore services

Reviewed by CEO, Netbase JSC · Updated 3 Oct 2026 · 11 min read

star

Why is a print price a function, not a list?

A print price is the output of a calculation, not an entry in a table. Size sets the base cost from sheet yield and imposition. Substrate changes that base cost and sometimes the press. Finishing adds its own cost or moves the job to a different route entirely. Quantity changes the unit price in steps, not smoothly. Turnaround adds a surcharge path. Waste, the offcut and spoilage a run produces, changes what the job actually costs to run at a given size and substrate. Six variables, each changing the others' effect, is a function: price equals some calculation over size, quantity, substrate, finishing, turnaround and waste. It is not a fact to be looked up.

Most web-to-print storefronts that struggle with pricing did not choose a function. They chose a matrix: a spreadsheet or option grid with a cell for every combination a product might need. This article sets out why that choice breaks as the product grows, and how to model and test the calculation as a function instead.

What variables does a print pricing function take?

  • Size

    What it changes
    Sheet yield, imposition, press or device choice
    Why it cannot be a flat column
    Yield rarely scales in a straight line with dimensions
  • Quantity

    What it changes
    Unit price, usually in bands rather than a smooth curve
    Why it cannot be a flat column
    Setup cost is close to fixed, so it dominates small runs and fades on large ones
  • Substrate

    What it changes
    Material cost, sheet yield, sometimes the press itself
    Why it cannot be a flat column
    Some substrates only run on certain equipment at certain sizes
  • Finishing

    What it changes
    An added cost, an added production step, or a different route
    Why it cannot be a flat column
    A finishing combination can be invalid on one substrate and routine on another
  • Turnaround

    What it changes
    A surcharge or a different production slot
    Why it cannot be a flat column
    The surcharge often depends on current capacity, not a fixed percentage
  • Waste

    What it changes
    What the run actually costs once offcut and spoilage are counted
    Why it cannot be a flat column
    Waste is a function of size and substrate together, not a constant

Each row depends on at least one other row. That is the property a flat price list cannot express: a size change alters the waste calculation, a substrate change alters which finishing options exist, and a quantity change alters which cost dominates the unit price.

Why does a spreadsheet matrix break under these variables?

A matrix tries to list an answer for every combination in advance. With five sizes, six quantity bands, four substrates and three finishing options, that is already three hundred and sixty cells, before turnaround or waste are considered. Add one more size and the matrix grows by seventy-two cells; add one more finishing option and every size, substrate and quantity combination needs a new column. The matrix does not fail gracefully. A missing cell returns no price at all, or the nearest cell's price by mistake, and nobody notices until a customer disputes an order.

This is a known shape of problem outside pricing, too: testing every combination of inputs to a system grows combinatorially, which is why software testing practice measures and bounds combination counts rather than attempting to enumerate them all. A pricing matrix is the same problem wearing a spreadsheet: the business is trying to enumerate a space that should instead be calculated on demand, for the one combination an order actually needs.

The matrix also goes stale in a specific way a function does not. When a substrate cost changes, every cell that uses that substrate needs updating by hand, across every size, finishing and quantity column it appears in. A function changes the substrate cost once, in one place, and every price that depends on it is correct the next time it runs.

How does a pricing function resolve an order?

A pricing function does not look up a price; it resolves one, variable by variable, in a fixed order, carrying a trace forward at each step. Size is read first and sets the base cost from sheet yield and imposition. Substrate is read next and adjusts that base cost for material and, where it applies, routes the job to the press the substrate requires. Finishing is applied last among the production variables, adding its own line item or, where a combination is invalid, returning a review state instead of a guess. The quantity band and any turnaround surcharge are then applied to the finished unit cost, and the function returns a price together with the trace of every value it used.

Nothing here is instant lookup. Each step depends on the step before it, which is exactly the property a flat table cannot hold: a substrate decision changes what finishing options are even valid, and a size decision changes what the substrate decision costs.

Diagram of a decision tree resolving a print price through size, substrate and finishing to a traced price (opens the full-size diagram in a new tab)
Diagram of a decision tree resolving a print price through size, substrate and finishing to a traced price

How do you test a pricing function before it ships?

A function is not trustworthy because it looks reasonable; it is trustworthy because it reproduces prices the business already trusts. The standard technique is a regression suite: a fixed set of known inputs and their agreed, correct outputs, re-run every time a rule changes, with any unexpected difference treated as a signal to investigate before release. Applied to a pricing function, that means keeping ten or twenty real quotes the business already stands behind, including at least one boundary case per variable, and re-running every one of them whenever a size table, a substrate cost or a finishing rule changes.

Print pricing engine is the engagement that builds this kind of function and accepts it against exactly this regression suite. Where the quantity axis specifically is concerned, quantity break and run-length pricing rules sets out how the bands amortise setup cost and round consistently; this article is about the variables around quantity, not a restatement of that mechanism.

Worked example: pricing a laminated postcard

The numbers below are illustrative only, in symbolic units, to show how the variables combine. They are not a published price for any product.

A storefront sells a laminated postcard. The function resolves an order for 250 units, A6, 350gsm card, gloss lamination, standard turnaround:

  1. Size: A6

    Base cost 1.20u per unit from sheet yield at this size

    Running total
    1.20u
  2. Substrate: 350gsm card

    Adds 0.30u per unit; no press change needed at this weight

    Running total
    1.50u
  3. Finishing: gloss lamination

    Adds 0.25u per unit; valid on this substrate and size

    Running total
    1.75u
  4. Quantity: 250 units

    Applies the 100-249 band factor from the quantity-break rule set

    Running total
    1.55u per unit
  5. Turnaround: standard

    No surcharge at standard turnaround

    Running total
    1.55u per unit

Change one input and only the steps after it recalculate: choosing a heavier 400gsm card at step 2 changes the base cost and the waste behind it, but the lamination rule at step 3 and the quantity band at step 4 are unaffected. A price list would need a new cell for every such change; the function needs only the one changed input.

Function versus matrix, side by side

  • Grows with each new variable

    Price matrix
    By multiplying every existing cell
    Pricing function
    By adding one calculation step
  • Behaviour on a missing combination

    Price matrix
    Returns nothing, or the wrong cell
    Pricing function
    Returns a review state naming the missing input
  • Cost of a rate change

    Price matrix
    Manual edit of every affected cell
    Pricing function
    One change, applied everywhere it is used
  • Testable line by line

    Price matrix
    Only by sampling cells
    Pricing function
    Yes, against a regression suite of known quotes
  • Keeps a trace per quote

    Price matrix
    Rarely
    Pricing function
    Yes, by design

Does a function ever need a table at all?

Yes, inside a step. A quantity band is itself a small table the function consults at step four, and a size-to-yield lookup can be a table the base-cost step reads. The difference is scope: a table confined to one variable, consulted by a function that resolves the others, stays small and reviewable. A table trying to hold the combination of all six variables at once is the one that breaks.

Decision checklist: does your pricing need to become a function?

  • Can you name, today, every variable your price depends on, and which ones change which others?
  • When a single cost changes, do you edit one place, or do you search a spreadsheet for every cell that mentions it?
  • Can you produce, for a disputed price, the exact values that calculated it?
  • Do you have ten or more quotes the business already trusts that a new pricing rule could be tested against?
  • Has a customer ever been quoted a price that matched no valid combination of what they ordered?

Two or more "no" answers to the first four questions, or a "yes" to the last one, usually means the price list has already outgrown what a table can hold safely.

How we reached this

Web2Print Solutions is the web-to-print engineering service of Netbase JSC. Delivery records cited on this site belong to Netbase JSC; where no delivered example of a capability is published, the page says so rather than implying a record. Netbase JSC, which operates Web2Print Solutions, has delivered 50+ web-to-print platforms; that group engineering experience, formalising estimating rules into callable engines, is the background to the pattern described here. No accuracy figure or delivered example under this property's own name is claimed.

Turn this into a scoped brief

If your current price list has a cell for every combination your products might need, send a project brief describing the variables it holds, one combination it gets wrong today, and two or three quotes your team already trusts. That is enough to show whether the fix is a new column or a different kind of calculation entirely.

Discuss your web-to-print project

Frequently asked questions

Usually less, once more than two or three variables are involved. A spreadsheet's apparent simplicity is the number of cells it hides, not the number of rules it took to fill them in.

Yes, for a single variable at a time, such as a quantity band or a size-to-yield table. The function calls that table as one step; it does not try to make the table hold every variable at once.

No. Quantity break and run-length pricing rules covers how the quantity axis specifically should amortise setup cost and round consistently; this article is about the variables around it, size, substrate, finishing, turnaround and waste, and why they cannot share one flat table with quantity either.

A function can accept a continuous size input and calculate yield directly; a table cannot hold every size without an impractical number of rows. Why you cannot price a custom size online covers that case specifically.

Tell us what you need to build, migrate or connect.

Start a project brief