Sample output from the Revenue Mix by Customer Segment — Stacked Monthly Brief prompt in the Sonar AI Prompt Library, run against a NetSuite test account. Every name and number here is test data. Back to the post · The library
SuiteStep, LLC  ·  Finance AnalyticsRevenue Mix · FY2026 Interim
Analysis Brief

Revenue Mix by Customer Segment

Thirteen months of GL revenue, August 2025 through August 2026, decomposed by the customer's segment. The base business is steady and growing; the volatility in the top line is almost entirely project-style revenue from a small number of IT and Consulting customers.

Period Aug 2025 – Aug 2026 (13 posting periods) Scope Subsidiaries 1–3, consolidated Source NetSuite GL (TD3016323) Prepared 2026-09-18 by Sonar AI
01 — Executive summary

$1.93M of revenue, two very different businesses inside it

$1.93M
Revenue, 13 months
Ties to Income Statement
35.8%
Largest segment
Manufacturing, 9 customers
64.8%
Base-business share
Mfg + Retail + B2C, present every month
+61%
Last 6 mo vs first 6 mo
$704K → $1,134K
  1. Three segments form a dependable base; the rest arrives in lumps.

    Manufacturing, Retail and B2C posted revenue in all 13 months and together average $96K/month (coefficient of variation 0.22). Information Technology and Consulting appear in only 5 and 4 months respectively, but supplied $607K — 31.5% of the total — and every one of the five peak months.

  2. Growth is real and broad, not just a single spike.

    Comparing Aug 2025–Jan 2026 with Mar 2026–Aug 2026, Manufacturing grew +42%, Retail +28%, B2C +23%, IT +41% and Consulting +297%. The three most recent months average $206K against $101K for the first three.

  3. B2B revenue is concentrated in a handful of accounts.

    In every B2B segment the top three customers account for 65–78% of segment revenue. Jones Manufacturing alone is $192K — 10% of company revenue. B2C is the mirror image: 60 customers, none above 4% of the segment.

  4. August 2026 introduced two segments and one billing pattern that warrants a check.

    "Others" jumped from ≤$4K to $50.7K on three invoices to Macgruber Incorporated for an identical $16,884 each (INV762, INV763, INV764). Construction became material for the first time ($12.8K). See §6.

02 — Revenue mix by month

Stacked revenue by customer segment

Each bar is one posting period. Base segments sit at the bottom in a navy scale so the project-style layers are visually separated above them. Select a segment in the legend to highlight it in red; switch to the share view to see mix independent of scale.

Revenue by segment, Aug 2025 – Aug 2026
USD, GL Income accounts, subsidiaries 1–3, demo journals excluded
    Click a legend item to move the red highlight. Hover a bar segment for detail.

    Peak months — Dec 2025 ($246K), Jul 2026 ($234K), Mar 2026 ($208K), Jun 2026 ($203K), May 2026 ($188K) — each coincide with an IT or Consulting posting. Remove those two segments and the monthly range narrows from $75K–$246K to $75K–$154K.

    Monthly detail

    03 — Segment profiles

    Size, stability and concentration

    Three lenses per segment: how big it is, how steady it is month to month (coefficient of variation — standard deviation divided by mean; below 0.3 is steady, above 1.0 is episodic), and how dependent it is on its largest customers.

    Active customers = customers with at least one Income posting in the window. Top-1 / Top-3 share = that customer group's portion of the segment's 13-month revenue. Segment-level Herfindahl index across the eight segments is 2,351 — moderately concentrated; a single-segment monopoly would be 10,000, eight equal segments 1,250.

    Manufacturing is the only segment that is simultaneously large, steady and diversified enough to plan around. Retail is large but half its 13-month total came from two customers; IT and Consulting are large only in aggregate.

    Top customers by segment

    04 — Base business vs project revenue

    What the run-rate actually is

    Grouping the three every-month segments as Base (Manufacturing, Retail, B2C) and the remainder as Project (IT, Consulting, Others, Construction, Services) separates the recurring engine from the episodic layer.

    Base vs project revenue by month
    Base in navy · project layer in red
    $96K
    Base, monthly mean
    Range $75K – $154K
    0.22
    Base volatility (CV)
    vs 0.41 for total revenue
    $678K
    Project revenue, 13 mo
    35.2% of total, 9 of 13 months
    $115K
    Base, Aug 2026
    +28% vs Aug 2025 ($89K)

    Base revenue has grown in each successive quarter of the window when normalised per month: Q3 2025 $89K, Q4 2025 $80K, Q1 2026 $84K, Q2 2026 $117K, Q3 2026 (2 months) $114K. The Q2 2026 step is driven by Retail ($85K in June — Design Excellence Ltd. and Davis Supplies) and Manufacturing.

    05 — Momentum

    First six months vs last six months

    Aug 2025–Jan 2026 compared with Mar 2026–Aug 2026. February 2026 sits between the two windows and is excluded from both so the halves are equal length.

    All three base segments grew by double digits, which rules out a mix-only explanation for the top-line increase. Consulting's growth is one account: Red Rivers Consulting posted $94K, 46% of the segment, in the second half.

    06 — August 2026 spotlight

    New segments appear; one pattern needs a second look

    August 2026 was the first month with six segments active. Two of them — Others and Construction — had been immaterial or absent, and together they contributed $63.5K, a third of the month.

    SegmentCustomerDocumentTypeRevenue
    OthersMacgruber IncorporatedINV762Invoice$16,884.00
    OthersMacgruber IncorporatedINV763Invoice$16,884.00
    OthersMacgruber IncorporatedINV764Invoice$16,884.00
    ConstructionMcCarthy SuppliesINV766Invoice$8,972.00
    ConstructionGramz LLPINV768Invoice$3,870.00
    Information TechnologySchubert SoftwareINV770Invoice$2,982.00
    Information TechnologyFinch ComputingINV765Invoice$2,145.00
    Verify before relying on August

    Three consecutive invoices to the same customer for an identical $16,884.00 in one posting period is consistent with legitimate milestone or recurring billing — and equally consistent with duplicate entry. $33,768 (two of the three) is 18% of August revenue. Confirm against the underlying sales order(s) before this month is used in a forecast or a commission calculation.

    Separately, Macgruber's segment assignment of "Others" — a residual category — means a $50.7K account is invisible to any segment-based reporting. Recategorising it (or creating the appropriate category) would improve every downstream view.

    07 — Revenue channels

    How each segment is billed

    Every B2B segment is invoiced. B2C is the only segment with a meaningful cash-sale channel — the store point-of-sale pattern — and it is also the highest-volume, lowest-ticket segment by a wide margin.

    SegmentTransaction typeTransactionsRevenueAvg / transaction
    ManufacturingInvoice75$690,659.45$9,209
    RetailInvoice71$409,912.78$5,773
    RetailCredit memo1($145.47)—
    RetailItem receipt GL anomaly2$149.95—
    Information TechnologyInvoice12$399,917.00$33,326
    ConsultingInvoice6$207,147.00$34,525
    B2CCash sale575$84,182.19$146
    B2CInvoice267$64,304.82$241
    OthersInvoice4$54,771.00$13,693
    ConstructionInvoice3$15,419.00$5,140
    ServicesInvoice1$718.00$718

    IT and Consulting average $33–35K per invoice on 18 invoices combined — 31% of revenue on 1.8% of transactions. B2C's 842 transactions average under $200. Two item receipts posting $149.95 to an Income account is unusual (receipts normally hit inventory and accrued purchases); the same $149.95 appears on the Income Statement under 4320 Sales Returns & Allowances and 6690 Bad Debt Expense, suggesting a returns/write-off entry routed through a receipt. Immaterial, but worth a look by whoever owns the returns process.

    08 — Risks, assumptions & data quality

    Read before acting on these numbers

    Assumptions made in this analysis
    • "Customer segment" = the standard NetSuite Customer Category field (customer.category). It is the only populated segmentation in the account. The custom segment cseg_client_tag is set on every customer but is not resolvable to a label via SuiteQL in this account, so it was not used.
    • "Revenue" = GL postings to accounts of type Income (the 4000 Sales family: 4210 Products, 4310 Services, 4320 Returns & Allowances, 4450 Freight). OthIncome (7000 series) is excluded — it is –$75 in the window and not customer revenue.
    • Revenue is attributed to the transaction's header entity (transaction.entity) and that customer's current category. If a customer's category was changed during the window, all of their history moves with it.
    • Posting period, not transaction date, defines the month. This matches the Income Statement.
    • Subsidiary 4 (xElim) excluded as an elimination entity; subsidiaries 1–3 are consolidated. Single currency (USD), so no FX translation applies.
    • Synthetic "Beg Balance" journals excluded. This account carries demo-data journals (memo Beg Balance…, 1st of each month) that post ~$0.75–0.93M/month of Income with no customer. They are 83% of GL Income in August 2026 ($923K of $1,106K). Including them would swamp every segment view under an "Uncategorized" bar; the filter t.memo NOT LIKE 'Beg Balance%' removes them and only them.
    • Base / Project split is an analytical grouping chosen from observed behaviour (present all 13 months vs episodic), not an account attribute.
    • Month-over-month comparisons treat Aug 2025 and Aug 2026 as complete periods. Both are closed to further routine posting at the time of writing, but Aug 2026 is not formally locked.
    Data-quality observations
    • 18 of 273 customers have no category. None generated Income postings in this window, so there is no "Uncategorized" slice today — but the gap will surface the first time one of them is invoiced.
    • "Others" is doing real work. Macgruber Incorporated ($50.7K) is now the sixth-largest customer in the company, sitting in a residual bucket. Recommend assigning a substantive category.
    • Three identical invoices to one customer in one period (INV762–764, $16,884.00 each) — see §6. Confirm against source sales orders.
    • Item receipts posting to Income (2 receipts, $149.95) — see §7. Immaterial; process question rather than a financial one.
    • Category taxonomy is mixed: seven of eight categories describe industry (Manufacturing, Retail, IT…) while B2C describes a channel. A customer can legitimately be both. A two-axis scheme (industry × channel) would prevent the ambiguity from growing as the book grows.
    Key risk

    Roughly a third of revenue depends on IT and Consulting engagements that post in 4–5 months of the year from a dozen accounts. A planning model built on the $1.93M total without separating the $678K project layer will overstate the reliable run-rate by about 50%.

    09 — Methodology & reconciliation

    How the numbers were built and proven

    Revenue was read directly from the general ledger (transactionaccountingline) rather than from transaction headers, so the figures reflect what posted, including credits and returns. Each GL line is joined to its transaction line to obtain the posting subsidiary, to the account to filter on type, to the posting period for the month, and to the customer for the segment.

    Tie-out to the NetSuite Income Statement

    The standard Income Statement (report −200, Parent Company consolidated, period Aug 2026) was run and compared with the query for the same period.

    LineIncome StatementSuiteQLDifference
    Total Income, Aug 2026, all postings$1,106,339.23$1,106,339.23$0.00
      of which "Beg Balance" demo journals—$923,083.34—
    Total Income excluding demo journals (= Aug 2026 bar)—$183,255.89—

    The query and the report agree to the cent on the unfiltered total, which validates the join path, the posting filters and the sign convention. The demo-journal exclusion is then a deliberate, documented departure from the report, not a discrepancy. The report's Net Income for the month was $182,096.23.

    Calculation notes

    Appendix — Queries & source documents

    Everything needed to reproduce this brief

    All queries are SuiteQL, run 2026-09-18 against account TD3016323 as Administrator. They follow the account's house style and are safe to paste into the SuiteQL Query Tool.

    Q1 — Segmentation census (which customer dimension is populated)
    Returned 9 rows. Established that customer.category is populated on 255 of 273 customers.
    SELECT
        BUILTIN.DF(c.category) AS category,
        COUNT(*)               AS customers,
        SUM(CASE WHEN c.cseg_client_tag IS NOT NULL THEN 1 ELSE 0 END) AS with_client_tag
    FROM customer c
    GROUP BY BUILTIN.DF(c.category)
    ORDER BY COUNT(*) DESC
    Q2 — Revenue by posting period and customer segment (primary dataset)
    Returned 53 rows (month × segment). Feeds §2, §3, §4, §5.
    SELECT
        ap.periodname                                     AS period,
        TO_CHAR(ap.startdate, 'YYYY-MM')                  AS ym,
        COALESCE(BUILTIN.DF(c.category), 'Uncategorized') AS segment,
        ROUND(-SUM(tal.amount), 2)                        AS revenue
    FROM transactionaccountingline tal
    JOIN transaction t        ON t.id = tal.transaction
    JOIN transactionline tl   ON tl.transaction = tal.transaction AND tl.id = tal.transactionline
    JOIN account a            ON a.id = tal.account
    JOIN accountingperiod ap  ON ap.id = t.postingperiod
    LEFT JOIN customer c      ON c.id = t.entity
    WHERE t.posting = 'T'
      AND tal.posting = 'T'
      AND a.accttype = 'Income'
      AND tl.subsidiary IN (1, 2, 3)
      AND (t.memo IS NULL OR t.memo NOT LIKE 'Beg Balance%')
      AND ap.startdate >= TO_DATE('2025-08-01', 'YYYY-MM-DD')
      AND ap.startdate <  TO_DATE('2026-09-01', 'YYYY-MM-DD')
    GROUP BY ap.periodname, TO_CHAR(ap.startdate, 'YYYY-MM'),
             COALESCE(BUILTIN.DF(c.category), 'Uncategorized')
    ORDER BY TO_CHAR(ap.startdate, 'YYYY-MM'), ROUND(-SUM(tal.amount), 2) DESC
    Q3 — Customer concentration: top 3 customers per segment
    Returned 21 rows. Feeds §3 concentration columns and the top-customer table.
    SELECT segment, customer, revenue, active_customers, seg_total
    FROM (
      SELECT
          x.segment, x.customer, x.revenue,
          COUNT(*)      OVER (PARTITION BY x.segment) AS active_customers,
          SUM(x.revenue) OVER (PARTITION BY x.segment) AS seg_total,
          ROW_NUMBER()  OVER (PARTITION BY x.segment ORDER BY x.revenue DESC) AS rn
      FROM (
        SELECT
            COALESCE(BUILTIN.DF(c.category), 'Uncategorized') AS segment,
            c.entityid                                        AS customer,
            ROUND(-SUM(tal.amount), 2)                        AS revenue
        FROM transactionaccountingline tal
        JOIN transaction t        ON t.id = tal.transaction
        JOIN transactionline tl   ON tl.transaction = tal.transaction AND tl.id = tal.transactionline
        JOIN account a            ON a.id = tal.account
        JOIN accountingperiod ap  ON ap.id = t.postingperiod
        LEFT JOIN customer c      ON c.id = t.entity
        WHERE t.posting = 'T' AND tal.posting = 'T'
          AND a.accttype = 'Income'
          AND tl.subsidiary IN (1, 2, 3)
          AND (t.memo IS NULL OR t.memo NOT LIKE 'Beg Balance%')
          AND ap.startdate >= TO_DATE('2025-08-01', 'YYYY-MM-DD')
          AND ap.startdate <  TO_DATE('2026-09-01', 'YYYY-MM-DD')
        GROUP BY COALESCE(BUILTIN.DF(c.category), 'Uncategorized'), c.entityid
      ) x
    ) y
    WHERE rn <= 3
    ORDER BY seg_total DESC, revenue DESC
    Q4 — Revenue by segment and transaction type
    Returned 11 rows. Feeds §7.
    SELECT
        COALESCE(BUILTIN.DF(c.category), 'Uncategorized') AS segment,
        t.type                                            AS tran_type,
        COUNT(DISTINCT t.id)                              AS transactions,
        ROUND(-SUM(tal.amount), 2)                        AS revenue
    FROM transactionaccountingline tal
    JOIN transaction t        ON t.id = tal.transaction
    JOIN transactionline tl   ON tl.transaction = tal.transaction AND tl.id = tal.transactionline
    JOIN account a            ON a.id = tal.account
    JOIN accountingperiod ap  ON ap.id = t.postingperiod
    LEFT JOIN customer c      ON c.id = t.entity
    WHERE t.posting = 'T' AND tal.posting = 'T'
      AND a.accttype = 'Income'
      AND tl.subsidiary IN (1, 2, 3)
      AND (t.memo IS NULL OR t.memo NOT LIKE 'Beg Balance%')
      AND ap.startdate >= TO_DATE('2025-08-01', 'YYYY-MM-DD')
      AND ap.startdate <  TO_DATE('2026-09-01', 'YYYY-MM-DD')
    GROUP BY COALESCE(BUILTIN.DF(c.category), 'Uncategorized'), t.type
    ORDER BY ROUND(-SUM(tal.amount), 2) DESC
    Q5 — August 2026 drill-down: Others, Construction, IT by document
    Returned 7 rows. Feeds §6. Period id 182 = Aug 2026.
    SELECT
        COALESCE(BUILTIN.DF(c.category), 'Uncategorized') AS segment,
        c.entityid                                        AS customer,
        t.type                                            AS tran_type,
        t.tranid                                          AS document,
        ROUND(-SUM(tal.amount), 2)                        AS revenue
    FROM transactionaccountingline tal
    JOIN transaction t        ON t.id = tal.transaction
    JOIN transactionline tl   ON tl.transaction = tal.transaction AND tl.id = tal.transactionline
    JOIN account a            ON a.id = tal.account
    LEFT JOIN customer c      ON c.id = t.entity
    WHERE t.posting = 'T' AND tal.posting = 'T'
      AND a.accttype = 'Income'
      AND tl.subsidiary IN (1, 2, 3)
      AND (t.memo IS NULL OR t.memo NOT LIKE 'Beg Balance%')
      AND t.postingperiod = 182
      AND BUILTIN.DF(c.category) IN ('Others', 'Construction', 'Information Technology')
    GROUP BY COALESCE(BUILTIN.DF(c.category), 'Uncategorized'), c.entityid, t.type, t.tranid
    ORDER BY ROUND(-SUM(tal.amount), 2) DESC
    Q6 — Reconciliation: Aug 2026 Income with and without demo journals
    Returned 1 row: 1,106,339.23 / 183,255.89 / 923,083.34. Compared with report −200.
    SELECT
        ROUND(-SUM(tal.amount), 2) AS income_all,
        ROUND(-SUM(CASE WHEN t.memo IS NULL OR t.memo NOT LIKE 'Beg Balance%'
                        THEN tal.amount ELSE 0 END), 2) AS income_excl_begbal,
        ROUND(-SUM(CASE WHEN t.memo LIKE 'Beg Balance%'
                        THEN tal.amount ELSE 0 END), 2) AS income_begbal_only
    FROM transactionaccountingline tal
    JOIN transaction t        ON t.id = tal.transaction
    JOIN transactionline tl   ON tl.transaction = tal.transaction AND tl.id = tal.transactionline
    JOIN account a            ON a.id = tal.account
    WHERE t.posting = 'T' AND tal.posting = 'T'
      AND a.accttype = 'Income'
      AND tl.subsidiary IN (1, 2, 3)
      AND t.postingperiod = 182

    Source documents

    SourceDetailUsed for
    NetSuite Income StatementStandard report −200 · Parent Company (Consolidated) · Aug 2026 (period id 182) · run 2026-09-18Tie-out (§9); account names in §7/§8
    GL tablestransactionaccountingline, transaction, transactionline, account, accountingperiod, customerQ2–Q6
    Customer mastercustomer.category (standard Customer Category list); 273 customers, 255 categorisedSegment dimension
    Branding guidelines"Boardroom Red" — palette, typography and chart rules applied throughoutDocument design
    Account field notesKnown demo-ledger caveat (Beg Balance journals), elimination subsidiary, exposed-column quirksAssumptions (§8)

    Glossary

    Base segmentsManufacturing, Retail, B2C — the three segments with Income postings in every one of the 13 months.
    Project segmentsInformation Technology, Consulting, Others, Construction, Services — episodic, invoice-driven revenue.
    CVCoefficient of variation; standard deviation ÷ mean of the 13 monthly values. Lower is steadier.
    HHIHerfindahl–Hirschman index; sum of squared percentage shares. 10,000 = one segment; 1,250 = eight equal segments.
    Posting periodThe accounting period a transaction posts to; may differ from its transaction date.