---
# === IDENTITY ===
id: business/erp-integration/epicor-dmt-bulk-import/2026
canonical_question: "What are the Epicor DMT data migration tool bulk import constraints and limits?"
aliases:
  - "Epicor DMT CSV import limits and file size constraints"
  - "How to speed up Epicor DMT bulk data uploads"
  - "Epicor Data Management Tool batch import best practices and performance"
  - "Epicor Kinetic DMT playlist and playbook automation constraints"
entity_type: erp_integration
domain: business > erp-integration > epicor-dmt-bulk-import
region: global
jurisdiction: global
temporal_scope: 2024-2026

# === SYSTEM PROFILE ===
systems:
  - name: "Epicor Kinetic (ERP)"
    vendor: "Epicor"
    version: "Kinetic 2024.1+"
    edition: "All editions (Standard, Enterprise, Cloud)"
    deployment: "hybrid"
    api_surface: "REST (OData) + DMT CLI"

# === VERIFICATION ===
last_verified: 2026-03-02
confidence: 0.82
version: 1.0
first_published: 2026-03-02

# === TEMPORAL VALIDITY ===
temporal_validity:
  status: evolving
  last_breaking_change: "2024.1 - Server Processing flag introduced for select tables"
  next_review: 2026-08-29
  change_sensitivity: medium

# === CONSTRAINTS ===
constraints:
  - "DMT processes records one-at-a-time through Epicor business objects (BO) - not direct SQL. Every record triggers full validation and BPM rules."
  - "Server Processing flag (batch size default: 200 records) is only available on select tables - most common import tables (Customer, Part, PO) do not yet support it."
  - "CSV is the only supported import file format for DMT playlists and command-line automation. Excel files must be saved as CSV first."
  - "Date fields must use MM/DD/YYYY format. Numerical fields must not contain thousand separators (commas). File encoding must be UTF-8."
  - "Data must be loaded in dependency order - parent records before child records (e.g., Parts before BOMs, Customers before Sales Orders)."
  - "No built-in file size limit, but practical limit is ~50,000-100,000 records per file before performance degrades significantly. Split into 10,000-record chunks for parallel processing."
  - "BPMs (Business Process Management rules) execute on every DMT record, which can double import time. Disable non-essential BPMs during bulk loads."
  - "Cloud deployments cannot access server-side processing optimizations available to on-premise installations."

# === SKIP CONDITIONS ===
skip_this_unit_if:
  - condition: "User needs to integrate via Epicor REST API directly (not DMT)"
    use_instead: "business/erp-integration/epicor-kinetic-rest-api/2026"
  - condition: "User needs real-time bidirectional sync, not batch import"
    use_instead: "business/erp-integration/epicor-kinetic-rest-api/2026"
  - condition: "User needs a different ERP system's data migration tool"
    use_instead: "N/A - search for the specific ERP system"

# === AGENT HINTS ===
inputs_needed:
  - key: integration_pattern
    question: "What integration pattern do you need?"
    type: choice
    options:
      - "one-time data migration (go-live cutover)"
      - "recurring batch import (daily/weekly sync)"
      - "bulk update of existing records"
      - "bulk delete of records"
  - key: data_volume
    question: "What's your data volume?"
    type: choice
    options:
      - "< 1,000 records"
      - "1,000-10,000 records"
      - "10,000-100,000 records"
      - "> 100,000 records"
  - key: deployment
    question: "What is your Epicor deployment model?"
    type: choice
    options:
      - "Cloud (Epicor-hosted SaaS)"
      - "On-premise (self-hosted)"
      - "Hybrid"

# === DISTRIBUTION ===
canonical_source: "https://knowledgelib.io/business/erp-integration/epicor-dmt-bulk-import/2026"
suggested_citation: "Source: knowledgelib.io - AI Knowledge Library (verified 2026-03-02)"

# === RELATED UNITS ===
related_kos:
  depends_on: []
  related_to:
    - id: "business/erp-integration/epicor-kinetic-rest-api/2026"
      label: "Epicor Kinetic REST API capabilities and rate limits"
  solves: []
  alternative_to:
    - id: "business/erp-integration/epicor-kinetic-rest-api/2026"
      label: "Epicor REST API for real-time record-level integrations"
  often_confused_with:
    - id: "business/erp-integration/sap-data-migration-cockpit/2026"
      label: "SAP Data Migration Cockpit (different ERP, similar concept)"

# === SOURCES (7 authoritative sources) ===
sources:
  - id: src1
    title: "DMT Documentation"
    author: Epicor
    url: https://epicordmthelp.z20.web.core.windows.net/
    type: official_docs
    published: 2024-06-01
    reliability: authoritative
  - id: src2
    title: "Data Migration Tools - Epicor Kinetic"
    author: Epicor
    url: https://www.epicor.com/en-us/products/enterprise-resource-planning-erp/kinetic/global-business-management/data-migration-tool/
    type: official_docs
    published: 2025-01-15
    reliability: authoritative
  - id: src3
    title: "Is there any way to speed up DMT? - Epicor User Help Forum"
    author: Epicor Community
    url: https://www.epiusers.help/t/is-there-any-way-to-speed-up-dmt/93459
    type: community_resource
    published: 2023-08-15
    reliability: moderate_high
  - id: src4
    title: "New DMT Server Processing flag - Epicor User Help Forum"
    author: Epicor Community
    url: https://www.epiusers.help/t/new-dmt-server-processing-flag/119999
    type: community_resource
    published: 2024-03-20
    reliability: moderate_high
  - id: src5
    title: "How to Upload Data using Epicor DMT"
    author: Datix
    url: https://datixinc.com/blog/how-to-upload-data-using-epicor-dmt/
    type: technical_blog
    published: 2024-01-10
    reliability: moderate_high
  - id: src6
    title: "Common Data Formatting Issues in Epicor DMT and How to Fix Them"
    author: Epicforce Tech
    url: https://epicforcetech.com/common-data-formatting-issues-in-epicor-dmt-and-how-to-fix-them/
    type: technical_blog
    published: 2025-06-15
    reliability: moderate
  - id: src7
    title: "Data Migration Best Practice Feedback - Epicor User Help Forum"
    author: Epicor Community
    url: https://www.epiusers.help/t/data-migration-best-practice-feedback/132873
    type: community_resource
    published: 2025-01-20
    reliability: moderate_high
---

# Epicor DMT (Data Management Tool): Bulk Import Constraints, Limits, and Best Practices

## TL;DR

- **Bottom line**: Epicor DMT processes records through business objects one-at-a-time (not direct SQL), so bulk imports are inherently slow -- expect 30-90 records per minute depending on table complexity and BPMs. Split large files into 10,000-record chunks and run parallel DMT instances to dramatically reduce total import time. [src3]
- **Key limit**: No hard record-count cap per file, but practical throughput is 30-90 records/minute (RPM). A 100,000-record import takes 18-55 hours single-threaded. With 10 parallel instances, this drops to under 5 hours. [src3]
- **Watch out for**: BPMs (Business Process Management rules) fire on every DMT record. Badly designed BPMs can double your import time. Disable or condition them before bulk loads. [src3]
- **Best for**: One-time data migrations (go-live cutover), bulk master data loads (Parts, Customers, Vendors, BOMs), and recurring batch updates via CLI/playlist automation. [src2]
- **Authentication**: DMT uses Epicor user credentials (username/password) passed via CLI arguments or entered in the GUI. No OAuth or API key support for DMT itself. [src1]

## System Profile

This card covers the Epicor Data Management Tool (DMT), a desktop client application bundled with Epicor ERP (version 10.2.500+) and Epicor Kinetic. DMT is the official tool for bulk importing, updating, and deleting records in Epicor ERP using CSV files. It processes data through Epicor's business objects (BOs), which means all standard validation rules, BPMs, and data directives execute on every imported record -- exactly as if a user were entering data manually through the UI. This is both DMT's greatest strength (data integrity) and its biggest constraint (throughput). [src1, src2]

DMT is NOT a direct database import tool. It does not bypass business logic or write directly to SQL Server. This distinction is critical for understanding its performance characteristics. [src5]

| Property | Value |
|---|---|
| **Vendor** | Epicor |
| **System** | Epicor Kinetic (ERP) 2024.1+ |
| **API Surface** | Desktop client (GUI + CLI), processes via Business Objects (REST/SOAP internally) |
| **Current Version** | DMT 4.0.50.1+ (ships with Epicor Kinetic) |
| **Editions Covered** | All editions (Standard, Enterprise, Cloud) |
| **Deployment** | Hybrid (on-premise client connects to on-premise or cloud Epicor server) |
| **API Docs URL** | [Epicor DMT Documentation](https://epicordmthelp.z20.web.core.windows.net/) |
| **Status** | GA |

## API Surfaces & Capabilities

DMT is not a traditional API -- it is a client-side tool that internally calls Epicor's business objects. However, it exposes multiple interaction surfaces for automation. [src1]

| Surface | Interface | Best For | Automation? | Parallel? | Notes |
|---|---|---|---|---|---|
| DMT GUI (interactive) | Windows desktop app | Small imports (<1,000 records), one-time loads | No | Manual parallel tabs | Template builder, validation preview, pause/cancel [src5] |
| DMT CLI (command line) | `DMT.exe` with arguments | Scheduled/automated imports, scripted migrations | Yes (batch/PowerShell) | Yes (multiple processes) | `-User`, `-Pass`, `-Source`, `-NoUI` arguments [src1] |
| DMT Playlists | CSV file listing multiple imports | Multi-table sequential loads with dependency ordering | Yes | Sequential within playlist | PlayList is CSV of CLI arguments with headers [src1] |
| DMT Playbooks | Text file listing playlist files | Full migration orchestration across many tables | Yes | Sequential playlists | PlayBook references multiple PlayList files [src1] |
| BAQ Export | `-Export -BAQ=` CLI arguments | Extracting data from Epicor for analysis or migration | Yes | Yes (multiple processes) | Outputs to CSV only [src1] |
| Server Processing | Server-side batch flag | Faster processing for supported tables | Yes | N/A | Default batch size: 200 records. Limited table support. [src4] |

## Rate Limits & Quotas

### Per-Record Processing Limits

| Limit Type | Value | Applies To | Notes |
|---|---|---|---|
| Processing throughput | 30-90 RPM (records per minute) | All DMT imports | Varies by table complexity, number of BPMs, and server hardware [src3] |
| Throughput with BPMs disabled | 55-90 RPM | Tables with many BPMs | Disabling non-essential BPMs can double speed [src3] |
| Throughput with BPMs active | 30-50 RPM | Tables with complex BPMs | Email-sending BPMs are worst offenders [src3] |
| Server Processing batch size | 200 records (default) | Server Processing-enabled tables only | 4x faster than standard processing reported [src4] |

[src3, src4]

### File & Data Limits

| Limit Type | Value | Applies To | Notes |
|---|---|---|---|
| Max file size | No hard limit | CSV import files | Practical limit: files >100K rows degrade performance. Split recommended. [src3] |
| Recommended chunk size | 10,000 records per file | Parallel processing strategy | Users report best results with 10 files of 10K records vs. one 100K file [src3] |
| File format | CSV (comma-delimited) only | Playlists and CLI automation | Excel files must be saved as CSV first. Tab-delimited not supported. [src1, src5] |
| File encoding | UTF-8 | All CSV files | Required for proper handling of special characters and accented text [src6] |
| Date format | MM/DD/YYYY | All date fields | Non-compliant formats cause import failure [src6] |
| Decimal separator | Period (.) | All numeric fields | Thousand separators (commas) must be removed [src6] |
| Concurrent DMT instances | Limited by client CPU/RAM | Parallel imports | 10-12 instances per client machine is practical maximum (85% CPU typical) [src3] |

[src3, src6]

### Practical Throughput Estimates

| Record Count | Single Instance | 5 Instances | 10 Instances | Notes |
|---|---|---|---|---|
| 1,000 records | 11-33 min | 3-7 min | 2-4 min | Small load, minimal benefit from parallelism |
| 10,000 records | 1.8-5.5 hours | 22-66 min | 11-33 min | Ideal chunk size for parallel processing |
| 50,000 records | 9-28 hours | 2-6 hours | 1-3 hours | Must split files [src3] |
| 100,000 records | 18-55 hours | 4-11 hours | 2-5.5 hours | 10 files of 10K records recommended [src3] |
| 200,000+ records | Multiple days | 8-22 hours | 4-11 hours | Consider phased approach over multiple nights [src7] |

[src3]

## Authentication

DMT authentication is straightforward -- it uses Epicor ERP user credentials. There is no separate API key or OAuth flow for DMT itself. [src1]

| Method | Use When | Credential Type | Notes |
|---|---|---|---|
| GUI login | Interactive use | Username + password | Standard Epicor login dialog [src1] |
| CLI `-User`/`-Pass` | Automated/scripted imports | Username + password in command arguments | Credentials visible in process list and scripts. Secure with file permissions. [src1] |
| Windows auth (SSO) | On-premise with AD integration | Windows domain credentials | Available when Epicor is configured for Windows authentication [src1] |

### Authentication Gotchas

- **CLI credentials are in plaintext**: The `-Pass=` argument is visible in Task Manager and batch file contents. Restrict file permissions on automation scripts. Consider using Windows Task Scheduler with stored credentials instead. [src1]
- **DMT user needs appropriate Epicor security**: The DMT user must have security roles granting access to the specific business objects being imported. A user who can enter Parts manually can DMT Parts, but not Customers if they lack Customer security. [src5]
- **Cloud deployments may require VPN or specific network access**: DMT is a client application that connects to the Epicor application server. Cloud-hosted Epicor instances require network connectivity to the server. [src2]

## Constraints

- **Records processed through business objects, not direct SQL** -- every record triggers full field validation, required field checks, cross-reference lookups, and all active BPMs. This is intentional for data integrity but limits throughput to 30-90 RPM. [src3, src5]
- **BPMs fire on every record** -- email notifications, workflow triggers, and custom logic all execute during DMT imports. A single badly-designed BPM can cut throughput in half. [src3]
- **Dependency order is mandatory** -- you cannot import child records before parent records. Parts must exist before BOMs, Customers before Sales Orders, Vendors before POs. DMT enforces this through business object validation. [src5]
- **Server Processing is limited to select tables** -- the 4x-faster server-side batch processing (introduced in 2024.1) only works on a few tables (e.g., Image Category). Most high-volume tables (Customer, Part, Price List) do not yet support it. [src4]
- **Cloud tenancy restrictions** -- cloud-hosted Epicor instances cannot use certain server-side optimizations available to on-premise deployments. [src3]
- **No incremental/delta import built-in** -- DMT does not natively compare source data to existing Epicor data. You must manage add vs. update logic yourself via the Add/Update/Delete checkboxes. [src5]
- **60+ templates available** -- but not all Epicor tables have DMT templates. Custom UD (User Defined) tables require manual template configuration. [src2]

## Integration Pattern Decision Tree

```
START - Bulk import data into Epicor via DMT
|-- How many records?
|   |-- < 1,000 records
|   |   --> Use DMT GUI: interactive mode, preview validation, single file
|   |-- 1,000 - 10,000 records
|   |   --> Use DMT CLI: single instance, -NoUI flag for unattended
|   |-- 10,000 - 100,000 records
|   |   |-- Split into 10,000-record CSV files
|   |   |-- Launch 5-10 parallel DMT.exe instances
|   |   --> Disable non-essential BPMs first [src3]
|   |-- > 100,000 records
|       |-- Split into 10,000-record chunks
|       |-- Run across multiple client machines if available
|       |-- Consider phased migration (load base data early, delta at go-live) [src7]
|       --> Total runtime: plan for 4-11 hours with 10 parallel instances
|-- What operation?
|   |-- Add new records --> Check "Add" in DMT, ensure parent records exist
|   |-- Update existing --> Check "Update" in DMT, match on primary key fields
|   |-- Delete records --> Check "Delete" in DMT, use caution with cascading deletes
|   |-- Mixed add/update --> Check both "Add" and "Update" checkboxes
|-- One-time or recurring?
|   |-- One-time (go-live migration)
|   |   --> Use Playbooks for full orchestration
|   |   --> Pre-load base data weeks before go-live
|   |   --> Delta load at cutover [src7]
|   |-- Recurring (daily/weekly sync)
|       --> Use CLI with Windows Task Scheduler
|       --> Implement file generation from source system
|       --> Add error monitoring and alerting [src1]
|-- Which tables? (load in this dependency order)
    |-- 1. Company, Sites, Plants (foundational)
    |-- 2. Chart of Accounts, GL Accounts
    |-- 3. Customers, Vendors, Suppliers
    |-- 4. Part Classes, Part Groups
    |-- 5. Parts (Part Master)
    |-- 6. Part Revisions
    |-- 7. Bill of Operations (BOO)
    |-- 8. Bill of Materials (BOM)
    |-- 9. Inventory (initial balances)
    |-- 10. Open Orders, POs, Jobs [src5, src7]
```

## Quick Reference

| DMT CLI Argument | Purpose | Example | Notes |
|---|---|---|---|
| `-User=` | Epicor username | `-User=manager` | Required for CLI mode [src1] |
| `-Pass=` | Epicor password | `-Pass=epicor123` | Plaintext -- secure your scripts [src1] |
| `-Source=` | CSV file path | `-Source="C:\data\parts.csv"` | Full path to import file [src1] |
| `-NoUI` | Suppress GUI | `-NoUI` | Required for unattended automation [src1] |
| `-Add` | Add new records | `-Add` | Cannot be used with -Delete [src1] |
| `-Update` | Update existing records | `-Update` | Can be combined with -Add [src1] |
| `-Delete` | Delete records | `-Delete` | Use with caution [src1] |
| `-Export` | Export mode (BAQ) | `-Export` | Switches DMT to export mode [src1] |
| `-BAQ=` | BAQ query name | `-BAQ="PartExport"` | Used with -Export [src1] |
| `-Target=` | Export output path | `-Target="C:\export\parts.csv"` | CSV output only [src1] |
| `-UseFieldNames` | Include headers | `-UseFieldNames` | Adds column headers to export [src1] |

## Step-by-Step Integration Guide

### 1. Prepare your CSV file using DMT Template Builder

Open DMT, select the target table (e.g., Part), and click "Template Builder." Required fields are pre-checked. Check additional fields you need, then export the empty CSV template. Populate the template with your data, keeping all required columns. [src5]

```bash
# Launch DMT GUI to build template
start C:\Epicor\ERP10\DMT.exe
# In DMT GUI: select table > Template Builder > check fields > Save CSV
# The generated CSV has correct column headers matching Epicor field names
```

**Verify**: Open the generated CSV -- required columns are present, headers match Epicor field names exactly. Click "Validate Columns" in DMT to confirm all required fields are present and no column name errors exist. [src5]

### 2. Clean and format your data

Ensure all data meets Epicor DMT formatting requirements before import. [src6]

```python
# Input:  Raw CSV with data from legacy system
# Output: Cleaned CSV ready for DMT import

import pandas as pd

df = pd.read_csv("raw_data.csv", encoding="utf-8")

# Fix date format to MM/DD/YYYY
for col in df.select_dtypes(include=["datetime64"]).columns:
    df[col] = pd.to_datetime(df[col]).dt.strftime("%m/%d/%Y")

# Remove thousand separators from numeric columns
for col in df.select_dtypes(include=["object"]).columns:
    df[col] = df[col].str.replace(",", "", regex=False)

# Trim whitespace from all string columns
for col in df.select_dtypes(include=["object"]).columns:
    df[col] = df[col].str.strip()

# Save as UTF-8 CSV
df.to_csv("cleaned_for_dmt.csv", index=False, encoding="utf-8")
print(f"Rows: {len(df)}, Columns: {len(df.columns)}")
```

**Verify**: Open the cleaned CSV and confirm dates are MM/DD/YYYY, no commas in numbers, no leading/trailing whitespace. [src6]

### 3. Split large files for parallel processing

For datasets over 10,000 records, split into chunks for parallel DMT execution. [src3]

```python
# Input:  Large CSV file (e.g., 100,000 records)
# Output: Multiple smaller CSV files (10,000 records each)

import pandas as pd
import math

df = pd.read_csv("cleaned_for_dmt.csv", encoding="utf-8")
chunk_size = 10000
num_chunks = math.ceil(len(df) / chunk_size)

for i in range(num_chunks):
    chunk = df[i * chunk_size : (i + 1) * chunk_size]
    chunk.to_csv(f"dmt_chunk_{i+1:03d}.csv", index=False, encoding="utf-8")
    print(f"Chunk {i+1}/{num_chunks}: {len(chunk)} records")
```

**Verify**: Confirm each chunk file has correct headers and expected row counts. Total rows across all chunks equals the original file. [src3]

### 4. Disable non-essential BPMs before bulk load

Identify and disable BPMs that will slow down imports (email notifications, workflow triggers, audit logging). [src3]

```plaintext
In Epicor Kinetic:
1. Navigate to System Setup > Business Process Management
2. Identify BPMs on the target table (e.g., Part)
3. For each non-essential BPM:
   - Option A: Disable the BPM entirely (uncheck Active)
   - Option B: Add a condition: "Client Type <> DMT" or "User ID <> DMTUser"
4. Document which BPMs were disabled for re-enabling after import
```

**Verify**: Run a small test import (10 records) and confirm processing speed is acceptable (target: 55-90 RPM without BPMs). [src3]

### 5. Execute parallel imports via CLI

Launch multiple DMT instances simultaneously, each processing a different chunk. [src3]

```batch
@echo off
REM Input:  Multiple chunk CSV files
REM Output: Parallel DMT imports

REM Launch 10 parallel DMT instances
start "" "C:\Epicor\ERP10\DMT.exe" -User=dmtuser -Pass=password -Source="C:\data\dmt_chunk_001.csv" -Add -NoUI
start "" "C:\Epicor\ERP10\DMT.exe" -User=dmtuser -Pass=password -Source="C:\data\dmt_chunk_002.csv" -Add -NoUI
start "" "C:\Epicor\ERP10\DMT.exe" -User=dmtuser -Pass=password -Source="C:\data\dmt_chunk_003.csv" -Add -NoUI
start "" "C:\Epicor\ERP10\DMT.exe" -User=dmtuser -Pass=password -Source="C:\data\dmt_chunk_004.csv" -Add -NoUI
start "" "C:\Epicor\ERP10\DMT.exe" -User=dmtuser -Pass=password -Source="C:\data\dmt_chunk_005.csv" -Add -NoUI
start "" "C:\Epicor\ERP10\DMT.exe" -User=dmtuser -Pass=password -Source="C:\data\dmt_chunk_006.csv" -Add -NoUI
start "" "C:\Epicor\ERP10\DMT.exe" -User=dmtuser -Pass=password -Source="C:\data\dmt_chunk_007.csv" -Add -NoUI
start "" "C:\Epicor\ERP10\DMT.exe" -User=dmtuser -Pass=password -Source="C:\data\dmt_chunk_008.csv" -Add -NoUI
start "" "C:\Epicor\ERP10\DMT.exe" -User=dmtuser -Pass=password -Source="C:\data\dmt_chunk_009.csv" -Add -NoUI
start "" "C:\Epicor\ERP10\DMT.exe" -User=dmtuser -Pass=password -Source="C:\data\dmt_chunk_010.csv" -Add -NoUI

echo All 10 DMT instances launched. Monitor Task Manager for completion.
```

**Verify**: Monitor Task Manager for DMT.exe processes. Each process will terminate when its chunk is complete. Check DMT log files for errors. [src3]

### 6. Validate imported data and re-enable BPMs

After all imports complete, verify data integrity and restore BPMs. [src5]

```plaintext
Post-import validation:
1. In Epicor, run BAQ queries to count imported records
2. Compare counts against source data
3. Spot-check 10-20 records for field accuracy
4. Re-enable all disabled BPMs
5. Review DMT error logs for any failed records
6. Re-import failed records from error CSV files
```

**Verify**: Record counts in Epicor match source data. Error log shows zero or expected failures. BPMs are re-enabled and active. [src5]

## Code Examples

### Python: Automated DMT execution with error monitoring

```python
# Input:  Directory of chunk CSV files, DMT.exe path, credentials
# Output: Parallel DMT execution with error log collection

import subprocess
import os
import time
import glob

DMT_PATH = r"C:\Epicor\ERP10\DMT.exe"
DATA_DIR = r"C:\data\dmt_chunks"
USER = "dmtuser"
PASS = "password"
MAX_PARALLEL = 10

chunk_files = sorted(glob.glob(os.path.join(DATA_DIR, "dmt_chunk_*.csv")))
processes = []

for i, csv_file in enumerate(chunk_files):
    # Wait if at max parallel limit
    while len([p for p in processes if p.poll() is None]) >= MAX_PARALLEL:
        time.sleep(5)

    cmd = [
        DMT_PATH,
        f"-User={USER}",
        f"-Pass={PASS}",
        f"-Source={csv_file}",
        "-Add",
        "-NoUI"
    ]
    proc = subprocess.Popen(cmd)
    processes.append(proc)
    print(f"Launched DMT for {os.path.basename(csv_file)} (PID: {proc.pid})")

# Wait for all to complete
for proc in processes:
    proc.wait()

print("All DMT imports complete. Check error logs in DMT log directory.")
```

### PowerShell: PlayList-based automated migration

```powershell
# Input:  PlayList CSV file with multiple import definitions
# Output: Sequential DMT imports per playlist entries

# DMT PlayList CSV format (playlist.csv):
# Source,Add,Update,Delete
# C:\data\customers.csv,TRUE,FALSE,FALSE
# C:\data\parts.csv,TRUE,FALSE,FALSE
# C:\data\bom.csv,TRUE,FALSE,FALSE

$dmtPath = "C:\Epicor\ERP10\DMT.exe"
$playlistPath = "C:\data\playlist.csv"

$startTime = Get-Date
Write-Host "Starting DMT Playlist at $startTime"

$proc = Start-Process -FilePath $dmtPath `
    -ArgumentList "-User=dmtuser", "-Pass=password", "-PlayList=$playlistPath", "-NoUI" `
    -Wait -PassThru

$duration = (Get-Date) - $startTime
Write-Host "DMT Playlist completed in $($duration.TotalMinutes) minutes"
Write-Host "Exit code: $($proc.ExitCode)"
```

### Batch: BAQ Export for pre-migration data extraction

```batch
@echo off
REM Input:  BAQ query names defined in Epicor
REM Output: CSV exports of current data for backup/comparison

REM Export customer data
start /wait "" "C:\Epicor\ERP10\DMT.exe" -User=dmtuser -Pass=password ^
    -Export -BAQ="CustomerExport" -Target="C:\backup\customers.csv" -UseFieldNames -NoUI

REM Export part data
start /wait "" "C:\Epicor\ERP10\DMT.exe" -User=dmtuser -Pass=password ^
    -Export -BAQ="PartExport" -Target="C:\backup\parts.csv" -UseFieldNames -NoUI

echo Exports complete. Files saved to C:\backup\
```

## Data Mapping

### DMT CSV Column Requirements

| Data Type | CSV Format | Example | Gotcha |
|---|---|---|---|
| String | Plain text, no quotes needed unless contains commas | `ACME Corp` | Leading/trailing spaces cause lookup failures. TRIM all strings. [src6] |
| Date | MM/DD/YYYY | `01/15/2026` | Other formats (YYYY-MM-DD, DD/MM/YYYY) cause silent failures [src6] |
| Integer | No thousand separators | `12345` | Commas in numbers (12,345) cause type mismatch errors [src6] |
| Decimal | Period as decimal separator | `123.45` | Regional comma-decimal settings cause import failure [src6] |
| Boolean | TRUE/FALSE or 1/0 | `TRUE` | Case-insensitive. Do not use Yes/No. [src6] |
| Lookup/Foreign Key | Exact match to Epicor value | `CUST001` | Case-sensitive. Must match existing record exactly. [src6] |
| Multi-value | Tilde (~) separated | `VAL1~VAL2~VAL3` | Epicor-specific separator for multi-select fields |

### Data Type Gotchas

- **Lookup values must exactly match existing Epicor records** -- if your CSV references Customer ID "CUST001" but Epicor has "Cust001", the import will fail with "Field references invalid value." Case sensitivity depends on the specific field. [src6]
- **Empty numeric fields should use 0, not blank** -- leaving numeric fields blank can cause type conversion errors. Use appropriate defaults (0 for integers, 0.00 for decimals). [src6]
- **UOM codes must exist in Epicor before import** -- Unit of Measure fields reference the UOM master table. Import UOMs first if introducing new units. [src5]
- **Site/Plant codes are required on most transactional records** -- even if single-site, the Site code must be present in the CSV. [src5]

## Error Handling & Failure Points

### Common Error Messages

| Error | Meaning | Cause | Resolution |
|---|---|---|---|
| "Field references invalid value" | Lookup field contains unrecognized value | Foreign key value doesn't exist in Epicor | Verify the referenced record exists (e.g., Customer, UOM, Site) before importing dependent records [src5, src6] |
| "Required field is empty" | Mandatory field missing | CSV column present but cell is blank | Populate all required fields. Use Template Builder to identify which are required. [src5] |
| "Record already exists" | Duplicate primary key | Attempting to Add a record that already exists | Use "Update" instead of "Add", or remove duplicates from source file [src5] |
| "Business object validation failed" | BO rule violation | Data violates Epicor business logic (e.g., invalid date range, negative quantity) | Review the specific validation message and correct the data [src5] |
| "Column not found" | CSV header mismatch | Column name in CSV doesn't match Epicor field name | Use Template Builder to generate correct headers. Copy headers exactly. [src5] |
| "Access denied" / "Security violation" | Insufficient permissions | DMT user lacks security role for this table/operation | Grant appropriate Epicor security roles to the DMT user account [src5] |
| BPM error messages | Custom logic failure | A BPM rule rejected the record | Review BPM conditions. Consider disabling BPM during import. [src3] |

[src5, src6]

### Failure Points in Production

- **BPMs sending emails on every DMT record**: A BPM that sends notification emails fires on every single imported record, generating thousands of emails and severely degrading mail server and DMT performance. Fix: `Add a condition to the BPM: skip when Client Type = DMT, or disable email BPMs during bulk loads.` [src3]
- **Dependency order violation**: Attempting to import BOMs before Parts exist, or Sales Orders before Customers. DMT will fail on every record with "Field references invalid value." Fix: `Always load in dependency order: master data first, then transactional data. Use Playbooks to enforce correct sequence.` [src5]
- **DMT.exe process hangs after completion**: When launching DMT from .NET code with `Process.Start()` and `RedirectStandardOutput = true`, a classic deadlock occurs on large datasets when the IO buffer fills. Fix: `Set RedirectStandardOutput = false (the default) or asynchronously read stdout.` [src3]
- **CSV encoding issues with special characters**: Non-UTF-8 encoded files cause garbled text in name fields, addresses, and descriptions. Fix: `Always save CSV files as UTF-8. In Excel: Save As > CSV UTF-8 (Comma delimited).` [src6]
- **Client machine runs out of memory with 10+ parallel instances**: Each DMT.exe instance consumes significant RAM. Running too many parallel instances crashes the client. Fix: `Monitor RAM usage. Limit parallel instances to 8-10 per machine. Distribute across multiple client machines for very large migrations.` [src3]
- **Timeout on cloud-hosted Epicor instances**: Network latency between the DMT client and cloud-hosted server reduces throughput. Fix: `Run DMT from a VM in the same cloud region as the Epicor server, or use a VPN with low latency.` [src2]

## Anti-Patterns

### Wrong: Loading all 100,000 records in a single DMT instance

```plaintext
// BAD -- single DMT instance for 100K records takes 18-55 hours
DMT.exe -User=admin -Pass=pass -Source="C:\data\all_100k_parts.csv" -Add -NoUI
// Result: 18+ hours, no parallelism, no progress visibility
```

### Correct: Split into chunks and run parallel instances

```batch
// GOOD -- 10 parallel instances, each processing 10K records
// Total time: 2-5 hours instead of 18-55 hours
for /L %%i in (1,1,10) do (
    start "" DMT.exe -User=admin -Pass=pass -Source="C:\data\chunk_%%i.csv" -Add -NoUI
)
```

[src3]

### Wrong: Leaving all BPMs active during bulk import

```plaintext
// BAD -- email BPM fires on every record, sending 100,000 emails
// Processing speed drops from 90 RPM to 30 RPM
// Mail server queue backs up for hours
```

### Correct: Disable or condition BPMs before bulk load

```plaintext
// GOOD -- add condition to BPM: skip when CallContext.ClientType == "DMT"
// Or temporarily disable email/notification BPMs
// Processing speed stays at 55-90 RPM
// Re-enable BPMs immediately after import completes
```

[src3]

### Wrong: Importing child records before parent records

```plaintext
// BAD -- importing BOMs before Parts exist
DMT.exe -Source="bom_materials.csv" -Add -NoUI    // FAILS: Parts don't exist yet
DMT.exe -Source="parts.csv" -Add -NoUI            // Too late
```

### Correct: Use Playbook with correct dependency order

```plaintext
// GOOD -- Playbook enforces correct load sequence
// playbook.txt:
// playlist_1_parts.csv      (Parts first)
// playlist_2_revisions.csv  (Revisions depend on Parts)
// playlist_3_operations.csv (BOO depends on Revisions)
// playlist_4_materials.csv  (BOM depends on Revisions + Operations)

DMT.exe -User=admin -Pass=pass -PlayBook="C:\data\playbook.txt" -NoUI
```

[src5]

## Common Pitfalls

- **Not testing with a small batch first**: Running a full 100,000-record import without testing 100 records first. A formatting error in one column wastes hours of processing time. Fix: `Always test with 50-100 records first. Verify field mapping, validation, and BPM behavior before launching the full import.` [src5]
- **Using Excel format instead of CSV**: Saving the file as .xlsx and expecting DMT to read it. DMT requires .csv format for automation. Fix: `Always save as CSV (Comma delimited) or CSV UTF-8 in Excel. Do not use .xlsx, .xls, or tab-delimited formats.` [src1, src5]
- **Forgetting to validate columns before import**: Skipping the "Validate Columns" step in DMT GUI. Missing or misspelled columns cause batch failures. Fix: `Click the Validate Columns hyperlink after loading the CSV. It checks for required columns and column name errors.` [src5]
- **Not backing up before bulk delete operations**: Using DMT's Delete mode without a backup. There is no undo. Fix: `Export the target table via BAQ Export before any delete operation. Store the backup CSV securely.` [src1]
- **Mixing Add and Update incorrectly**: Checking both Add and Update for a file that contains only new records. DMT will attempt to look up each record first (slower). Fix: `Use Add-only for new records, Update-only for existing records. Only check both when the file contains a mix.` [src5]
- **Running DMT during business hours**: Bulk imports consume server resources and can slow down interactive users. Fix: `Schedule bulk imports during off-hours (nights/weekends). Coordinate with Epicor administrators.` [src7]
- **Version mismatch between DMT and Epicor server**: Using a DMT version that doesn't match the Epicor server version causes field mapping or validation failures. Fix: `Always use the DMT version that shipped with your specific Epicor build. DMT is included in the Epicor installation directory since version 10.2.500.` [src1]

## Diagnostic Commands

```batch
REM Check DMT version
"C:\Epicor\ERP10\DMT.exe" -Version

REM Test connectivity with a small import (1 record)
"C:\Epicor\ERP10\DMT.exe" -User=testuser -Pass=testpass -Source="C:\test\single_record.csv" -Add -NoUI

REM Export data for verification via BAQ
"C:\Epicor\ERP10\DMT.exe" -User=admin -Pass=pass -Export -BAQ="PartCount" -Target="C:\verify\part_count.csv" -UseFieldNames -NoUI

REM Check DMT log files for errors (default location)
dir "C:\Users\%USERNAME%\AppData\Local\Epicor\DMT\Logs\"

REM Monitor running DMT processes
tasklist /fi "imagename eq DMT.exe"

REM Kill hung DMT processes (use with caution)
REM taskkill /f /im DMT.exe
```

## Version History & Compatibility

| Version | Release | Status | Changes | Notes |
|---|---|---|---|---|
| DMT 4.0.50.1+ (Kinetic 2024.1) | 2024-Q1 | Current | Server Processing flag introduced | Default batch size: 200 records. Limited table support. [src4] |
| DMT (ERP 10.2.700) | 2023 | Supported | BAQ Export via CLI | `-Export -BAQ=` arguments added [src1] |
| DMT (ERP 10.2.500) | 2022 | Supported | Bundled with ERP installation | No longer requires separate DMT installer [src1] |
| DMT (ERP 10.2.x) | 2020-2022 | Supported | PlayList and PlayBook support | Automation via CSV-based orchestration files [src1] |
| DMT (ERP 10.1.x) | 2018-2020 | Legacy | Command-line arguments | Basic CLI automation introduced [src1] |
| DMT (ERP 9.x) | Pre-2018 | EOL | GUI-only | No CLI, no automation support |

[src1, src4]

### Deprecation Policy

Epicor does not publish a formal DMT deprecation policy. However, each major Epicor release (Kinetic 2024.1, 2024.2, etc.) may add new DMT capabilities (like Server Processing) or modify template structures. Always use the DMT version matching your Epicor server version. Older DMT clients may fail against newer servers due to business object changes. [src1]

## When to Use / When Not to Use

| Use When | Don't Use When | Use Instead |
|---|---|---|
| One-time data migration at go-live (Parts, Customers, Vendors, BOMs) | Real-time integration requiring <1s latency | Epicor REST API with webhooks |
| Bulk master data loads >1,000 records | Continuous bidirectional sync with external systems | Epicor REST API + integration platform (MuleSoft, Boomi) |
| Recurring batch updates from CSV/Excel exports | Data transformation requiring complex business logic mid-import | ETL tool (SSIS, Informatica) feeding Epicor REST API |
| Initial inventory balance loading | Direct SQL insert bypassing business rules | Never bypass DMT/BO for production data |
| Bulk price list updates | Mobile or web application data entry | Epicor Kinetic UI or REST API |

## Important Caveats

- DMT throughput (30-90 RPM) is a practical measurement from community reports, not an official Epicor specification. Actual rates vary significantly based on server hardware, network latency, table complexity, number of active BPMs, and Epicor edition. Always benchmark with your specific environment. [src3]
- Server Processing (2024.1+) is being rolled out incrementally across tables. As of early 2026, most common high-volume tables do not yet support it. Check Epicor release notes for your specific version. [src4]
- Cloud-hosted Epicor instances may have additional throughput constraints imposed by the hosting infrastructure that are not documented as DMT-specific limits. [src2]
- DMT is a Windows desktop application. There is no Linux, macOS, or web-based version. Automation requires a Windows machine (physical or VM) with DMT installed. [src1]
- The 60+ template count is approximate and varies by Epicor version and installed modules. Not all Epicor tables have pre-built DMT templates. [src2]

## Related Units

- [Epicor Kinetic REST API capabilities and rate limits](/business/erp-integration/epicor-kinetic-rest-api/2026)
- [SAP Data Migration Cockpit (similar concept, different ERP)](/business/erp-integration/sap-data-migration-cockpit/2026)
