Clear Cutover Get a quote

Epicor Kinetic · Performance

How to fix Epicor Kinetic BAQ and report timeouts: PartTran, TranGLC and heavy subqueries

Applies to: Epicor Kinetic and related Epicor ERP reporting environments. Validate table definitions, indexes, BAQ Designer capabilities, and configuration options against your installed release and deployment.

Short answer

Most Epicor Kinetic BAQ and SSRS report timeouts should be investigated as a performance problem before changing timeout settings. Common causes include reading too many rows, joining tables at the wrong level of detail, implicit data-type conversions, repeated lookups, and expensive report datasets or subreports.

Check these areas first:

  • PartTran: Confirm that filters and joins align with indexes available in your environment. A date-only filter can be expensive when the relevant index has earlier key columns.
  • TranGLC: Use the correct RelatedToFile discriminator and complete transaction-key mapping. Check data types and the execution plan rather than assuming a particular join is universal.
  • Calculated fields and subqueries: Look for correlated lookups that repeat work for many output rows. A set-based alternative may help, but measure it.
  • SSRS datasets and subreports: Check for repeated child-dataset execution, unused large fields, and joins that multiply rows.

Do not increase a timeout as the first response. Identify which layer is timing out, inspect row counts and query diagnostics, and tune the slow operation. A longer limit may be justified for a tuned query that genuinely needs more time, but it does not repair an inefficient query.

Scope note: Index definitions, BAQ Designer features, SQL access, and timeout behavior vary by Epicor release and deployment. Treat SQL examples in this guide as patterns to validate—not as universal configuration instructions.

How the pieces fit together

Component Role Potential Bottleneck
Erp.PartTran Inventory transactions and adjustments Large scans when predicates do not align with available indexes or are not selective
Erp.TranGLC General-ledger transaction links Broad joins across transaction types, incomplete keys, implicit conversions, or row multiplication
BAQ calculated fields Derive values for returned records Correlated subqueries can repeat work across many rows
BAQ execution settings Configure query behavior where supported Raising a time limit can hide an inefficient query rather than fix it
SSRS datasets and subreports Retrieve and render report data Repeated child queries, unnecessary fields, and row multiplication
Dynamic Query business object Executes BAQs through Epicor services Queries may exceed application or client time limits

A timeout can occur in SQL Server, the Epicor application layer, an API gateway, or the report-rendering path. A timeout message alone does not prove that SQL Server ran out of memory or that a particular index was ignored. Use timings and diagnostics to identify the actual bottleneck.

Step 1: Isolate the expensive table or join

Work in a pilot or test environment first:

  1. Run the BAQ with representative parameters. Record elapsed time and the number of returned rows.
  2. In BAQ Designer, inspect table criteria, subqueries, calculated fields, and table relationships.
  3. Temporarily remove one suspected join at a time—such as PartTran or TranGLC—and compare timings and row counts.
  4. Reintroduce the join with the required company and transaction keys, then test again.
  5. If you have supported SQL Server access, inspect the generated SQL and actual execution plan. Look for large scans, implicit-conversion warnings, expensive sorts, spills, and unexpectedly high row counts.
  6. Test both narrow and broad parameter ranges. A query that is fast for one part may still be inefficient for a company-wide extract.

A faster test after removing a table indicates that the table or its join may contribute to the cost. It does not, by itself, prove that an index is missing.

Step 2: Check PartTran filters and index alignment

PartTran can become very large in active manufacturing environments. Query cost depends on table size, available indexes, predicate selectivity, statistics, and the execution plan.

The Date-Filter Trap

Suppose a BAQ requests transactions in a date range and filters only on Company and TranDate. If an available index begins with Company, followed by PartNum and then TranDate, SQL Server may not be able to seek efficiently by date when PartNum is unconstrained. It may choose another access path or scan many rows instead.

Do not assume a particular index name or key order. The example explains why index key order matters; it is not a guaranteed definition for every Epicor environment.

Practical Fixes

  • When the report concerns specific parts: Filter on PartNum where the business requirement permits it, and join using the complete relationship keys.
  • When the report covers all parts in a date range: Inspect the indexes actually available and the execution plan. Do not substitute SysDate for TranDate unless the business question concerns the date the transaction was entered into the system rather than the transaction date.
  • Reduce rows early: Apply valid, selective criteria such as company, plant, transaction type, warehouse, or date range where relevant.
  • Aggregate at the right level: If the report needs totals by part or month, determine whether aggregation can reduce the rows passed to later joins.
  • Avoid speculative CTE fixes: A CTE or BAQ subquery does not automatically force SQL Server to filter first or materialize a smaller dataset. Verify the execution plan rather than relying on query shape alone.

On-premises DBAs may be able to consider additional indexes after reviewing workload and write overhead. Customers using Epicor Cloud generally cannot create arbitrary indexes on the managed application database; use supported reporting options and consult Epicor Support for environment-specific guidance.

Step 3: Make TranGLC joins selective and type-safe

TranGLC can contain records for many transaction types. Joining it without the correct transaction discriminator or key fields can create unnecessary work and incorrect matches.

Include RelatedToFile When It Matches the Source Record

When joining a source table to TranGLC, filter or join on the correct RelatedToFile value for that source. For example, InvcDtl may use a different relationship from PartTran. Confirm the actual values and key mapping in your environment; do not copy a value from another transaction type.

Avoid Implicit Conversions on Join Keys

In common Epicor schemas, TranGLC.Key1 through Key6 are character fields (nvarchar) because they can represent different kinds of transaction identifiers. Comparing a numeric source column directly to a character key can cause an implicit conversion. SQL Server data-type precedence can result in conversion of the character column, which may make an index seek less likely and can cause conversion errors if candidate rows contain non-numeric text.

Where the verified relationship requires it, converting the numeric source value to the matching string representation can avoid converting the character key column. However, the correct conversion, formatting, and key mapping must be verified for the target source and release. Conversion alone does not guarantee a faster plan or correct matches.

Illustrative Invoice-Detail Pattern

The following SQL is conceptual only. Verify the source-to-GL key mapping, string format, and actual relationship in representative posted records before using it:

-- Illustrative pattern only; verify the mapping first.
ON gl.Company = d.Company
AND gl.RelatedToFile = 'InvcDtl'
AND gl.Key1 = CONVERT(nvarchar(50), d.InvoiceNum)
AND gl.Key2 = CONVERT(nvarchar(50), d.InvoiceLine)

This is not a universal TranGLC join. The correct Key1–Key6 mapping depends on RelatedToFile and the source table. Verify it using the Data Dictionary, representative records, and release-appropriate Epicor documentation. If the plan still scans, inspect conversion warnings and available indexes.

Verify PartTran Mapping Rather Than Assuming It

In some Epicor environments, TranGLC records associated with PartTran use RelatedToFile = 'PartTran' and store SysDate, SysTime, and TranNum in Key1–Key3. Treat this as a candidate mapping to verify, not a universal guarantee. Check representative posted records and confirm the exact string representation—especially for date and time values—before building the join.

Where appropriate, reduce the GL dataset with valid criteria such as company, book, fiscal period, or account before joining. These filters must preserve the report’s intended accounting scope.

Step 4: Replace repeated scalar lookups where appropriate

A correlated scalar subquery in a calculated field can be expensive when it is evaluated for many outer rows. For example, retrieving the latest transaction for every part may involve repeated lookups, although SQL Server can sometimes optimize the query effectively.

Illustrative Scalar Lookup

SELECT TOP (1) pt.TranDate
FROM Erp.PartTran AS pt
WHERE pt.Company = p.Company
  AND pt.PartNum = p.PartNum
ORDER BY pt.TranDate DESC, pt.TranNum DESC;

For a large result set, consider a set-based design, such as a derived table or subquery that ranks candidate transactions and joins the selected row to the part list.

Example SQL Shape

WITH RankedPartTran AS
(
    SELECT
        pt.Company,
        pt.PartNum,
        pt.TranDate,
        pt.TranNum,
        ROW_NUMBER() OVER
        (
            PARTITION BY pt.Company, pt.PartNum
            ORDER BY pt.TranDate DESC, pt.TranNum DESC
        ) AS RowIdent
    FROM Erp.PartTran AS pt
    WHERE pt.Company = 'EPIC01'
)
SELECT
    p.PartNum,
    rpt.TranDate AS LatestTranDate
FROM Erp.Part AS p
LEFT JOIN RankedPartTran AS rpt
    ON rpt.Company = p.Company
   AND rpt.PartNum = p.PartNum
   AND rpt.RowIdent = 1
WHERE p.Company = 'EPIC01';

This is a SQL example, not a guarantee that the same syntax can be entered directly into a BAQ calculated field. Whether and how a window expression is supported depends on BAQ Designer capabilities and the Epicor release.

Ranking all transactions for a company can itself be expensive. Filter the candidate transaction set as tightly as the report’s business requirements allow, and inspect the execution plan. Keep the filters and definition of "latest" consistent with the original report. Use a LEFT JOIN if parts with no transactions must remain in the output; an inner join would exclude them.

Step 5: Join on Company and the complete relationship key

Include Company in applicable joins and apply the correct company scope to the root dataset. Omitting a required key can cause cross-company matches, duplicate rows, or poor cardinality estimates. Adding Company alone does not guarantee an index seek; index definitions, statistics, predicate selectivity, and the plan still matter.

For every join, ask:

  • Are both sides restricted to the same company?
  • Are all columns in the relationship included?
  • Does the join preserve the intended level of detail—one row per part, transaction, invoice line, or GL distribution?
  • Do row counts increase unexpectedly after the join?

In BAQs, use the company context and supported company criteria appropriate to your environment. Do not assume a constant or expression is valid in every SQL, BAQ, or report context.

Step 6: Tune SSRS datasets and subreports

If a BAQ runs quickly in the designer but the report times out, investigate the entire report execution path. If a report remains in ACTIVE in System Monitor, see the related guide How to Fix an Epicor Kinetic Report Stuck in ACTIVE.

  • Remove unused fields: Eliminate columns the RDL does not use, particularly large comment or long-text fields. These can increase data transfer and rendering work, but are not automatically the cause of a timeout.
  • Inspect subreports and nested datasets: Determine whether a child query runs once per report instance or once per detail row. Repeated execution can multiply the cost.
  • Check row multiplication: Ensure joins do not duplicate detail rows and inflate the dataset.
  • Measure dataset time separately from rendering: A slow SQL dataset and a slow SSRS layout require different fixes.
  • Review standard report customizations carefully: If a subreport appears to run repeatedly, test in a non-production environment before disabling or changing it. Preserve required business logic and compare output against the standard report.
  • Avoid unsupported generalizations: Do not claim a named subreport is universally defective unless you have a reproducible case and a matching support reference for the relevant release.

The QueryTimeout = 0 question: Verify the exact setting

Timeout settings can exist at several layers, including BAQ execution, application-server configuration, database commands, report execution, clients, and API gateways. A value of 0 does not have one universal meaning across all these layers.

Some older Epicor ICE documentation describes 0 in the BAQ Query Timeout setting as indicating no limit. That behavior should not be generalized to every timeout setting, release, or component. Confirm the exact setting and its release-specific documentation—or ask Epicor Support—before changing it.

Before raising a timeout:

  1. Identify the component returning the timeout.
  2. Tune joins, filters, row counts, and repeated work.
  3. Confirm the workload is expected and safe to run.
  4. If a longer limit is justified, use the supported setting for that component and test under realistic load.

Increasing a timeout to many minutes can tie up application or database resources if the query is inefficient. A client or API gateway may also time out before the server-side operation completes.

Troubleshooting: Symptom, likely cause, and next step

Symptom Possible Cause What to Check
BAQ repeatedly times out after a similar interval Application, SQL command, report, or gateway timeout Identify the layer returning the error and confirm its configured limit
Query is fast for one part but slow for all parts Broad PartTran scan or low-selectivity date filter Inspect actual index keys, predicates, and execution plan
Query slows after adding TranGLC Missing transaction discriminator, incomplete key mapping, implicit conversion, or row multiplication Add the correct RelatedToFile relationship and verify all keys and data types
BAQ is fast with a small sample but slow on a dashboard Larger parameter scope, repeated scalar lookups, sorting, or client-side processing Test realistic row counts and inspect calculated fields and dashboard behavior
SSRS report times out on orders with many lines Repeated subreport queries, large datasets, or row multiplication Measure each dataset, inspect subreport execution, and remove unused fields
Setting timeout to zero did not help Zero may have a setting-specific meaning, or another layer may be timing out Verify the exact setting and error source in documentation or with Epicor Support

Environment differences to Check

  • Kinetic Cloud and OData: Requests through REST/OData may be subject to client, application, and gateway limits. Large exports should use supported filters and sensible batches. A 504 response does not by itself prove that the database query stopped immediately.
  • Cloud versus on-premises indexing: Database administration options differ. Do not recommend creating indexes on a managed cloud application database unless Epicor explicitly supports the action.
  • Version differences: BAQ Designer capabilities, SQL generation, and configuration options can change across releases. Verify suggested functions, menu paths, and timeout behavior on the target version.

FAQ

How do I troubleshoot an Epicor BAQ timeout?

First identify which component reports the timeout. Reproduce the BAQ with representative parameters, record elapsed time and row counts, then inspect joins, filters, calculated fields, and the actual execution plan where access is available. Tune the demonstrated bottleneck before increasing a timeout.

Why might PartTran be fast when filtered by part number but slow when filtered only by date?

One possible cause is that an available index has PartNum ahead of TranDate, making a date-only predicate less efficient for that index. SQL Server may choose another access path or scan more rows. Inspect the indexes actually available, the query predicates, and the execution plan before choosing a fix.

How should I join TranGLC to a transaction table?

Use Company, the appropriate RelatedToFile value, and the complete key mapping for the source table. The Key1–Key6 mapping differs by transaction type, and some keys are stored as character values. Verify the mapping and data representation against your installed schema and representative posted records; do not copy a join from another transaction type without validation.

How can I get the latest transaction per part?

A set-based approach using ROW_NUMBER() can rank candidate transactions by Company and PartNum, ordered by the fields that define "latest," and then retain row 1. Filter the candidate transaction set where the business requirement allows it, and compare the execution plan with the existing query. Support for this SQL shape within BAQ Designer depends on your release and design approach.

Should I increase the timeout to 600 seconds?

Not as the first step. Identify which component is timing out and tune the query first. A longer timeout may be appropriate for a tuned query that genuinely needs more time, but it does not fix a bad join, excessive row count, or repeated subquery. Test any change under realistic load.

Does QueryTimeout = 0 mean unlimited execution?

Not universally. Its meaning depends on the exact setting and release. Some older Epicor ICE documentation describes 0 in the BAQ Query Timeout setting as no limit, but that should not be generalized to other layers. Verify the specific setting before changing it.

References

Validate procedures against official Epicor documentation and database diagnostic tools:

  • Epicor Kinetic Help: Business Activity Query (BAQ) Designer & Query Execution Settings
  • Epicor Kinetic Help: Report Data Definition (RDD) and SSRS Report Execution
  • Microsoft SQL Server Documentation: Execution Plans, Index Architecture, and Data Type Precedence
  • Epicor Kinetic Documentation: Dynamic Query Engine & REST API OData Execution Limits

Systems I work on