What does dataLoaderConfig.maxThreadsCount control in the Data Loader, and what value should I use?

Question


What does dataLoaderConfig.maxThreadsCount in the tenant physical configuration control, what is its default, and when should it be changed?

Answer

 

What it controls

  • maxThreadsCount is an optional parameter in the dataLoaderConfig section of the tenant physical configuration.
  • It sets the maximum number of loader threads the Universal Data Loader can use for the tenant, across all running jobs. It is not a per-job setting.
  • Each job requests threads from that tenant pool. If other jobs already hold all of the tenant’s threads, a new job may wait until threads free up.
  • Each loader thread sends create/update requests to the platform in parallel, so this value sets how much concurrent load the Data Loader puts on the tenant.

Which Jobs Actually Consume Threads?

A UDL data loading request is split internally into several sub-jobs

  • MAIN, PREPROCESSOR, and ERRORS_PROCESSOR jobs: Do not consume threads from the tenant's maxThreadsCount pool

  • LOADER jobs: These are the only sub-jobs that reserve and run threads from the tenant pool (executing the actual POST entity/relation requests into the Reltio core platform)

Default value

In the Reltio Universal Data Loader (UDL) architecture and physical tenant configuration:

  • dataloaderConfig.maxThreadsCount sets the maximum number of loading threads allowed per tenant across all active jobs 

Tenant: NDorshimerTest

"dataloaderConfig": {
  "useUDL": true,
  "maxThreadsCount": 200,
  "batchSize": 10
}

Active job groups:
JobGroup 1 - threads_count = 100 
  Loader Job 1 - 100 threads
  Loader Job 2 - 0 threads (waiting for available threads)
JobGroup 2 - threads_count = 100
  Loader job 1 - 100 threads
  Loader job 2 - 0 threads (waiting for available threads)
Job Group 3 - threads_count = 100
  Loader job 1 - 0 threads (waiting for available threads)
  ... 
  • By default, a regular job requests up to 100 threads.udl_job_group_static_info.threads_count = 100). If multiple jobs run concurrently, the available pool is shared among active jobs

  • Configuration Path: Configured in the tenant's physical/optional parameters under:

    "dataloaderConfig": { "maxThreadsCount": 100 }

    Boosted / Premium Mode Default:

    • For jobs loading 10 million or more records (or tenants with Premium Mode enabled), the thread limit defaults to 200 threads (and can be configured higher, e.g., 400–500)

    • The number of threads that job gets is equal to dataloaderConfig.premiumSettings.maxThreadsCount . This bypasses the regulardataloaderConfig.maxThreadsCount and udl_job_group_static_info.threads_count

    Tenant: NDorshimerTest
    
    "dataloaderConfig": {
      "useUDL": true,
      "maxThreadsCount": 200,
      "batchSize": 10,
      "premiumSettings": {
        "maxThreadsCount": 500
      }
    }
    
    Active job groups in order of creation
    JobGroup 1 - threads_count = 100
      Loader Job 1 - 0 threads
      Loader Job 2 - 0 threads 
    JobGroup 2 - premium enabled
      Loader job 1 - 500 threads
      Loader job 2 - 0 threads 
    Job Group 3 - threads_count = 100
      Loader job 1 - 0 threads
      ...

Thread allocation is determined by two main controls:

  1. Tenant Ceiling (dataloaderConfig.maxThreadsCount):

    • Sets the absolute maximum number of loader threads that can run concurrently across all active jobs on that tenant.

  2. Job Group Request (threads_count):

    • Stored in udl_job_group_static_info.threads_count (or dynamic info, which takes precedence).

    • Defines how many threads an individual job group requests to perform ingestion (default is 100) .

When to change it


More threads do not always mean faster loads. Throughput is limited by the slowest shared resource in the create path. For example, if an attribute is auto-generated from a sequential generator, every create takes one cluster-wide lock to get its ID. At high thread counts, threads queue on that lock, time out after 60 seconds (SEQUENTIAL_GENERATOR_LOCK_ERROR, “Cannot obtain HZ lock in 60 seconds”), and are retried, which adds load.

Signs the value is too high for the load:

  • Lock timeout errors on a generator
  • A CRUD queue growing into the millions
  • Slow throughput while the Data Loader workers show low CPU

In one production tenant loading about 4M-record files with a sequential ID generator:

  • At 300 threads, the load hit lock timeouts and a multi-million-record CRUD queue.
  • At 100, the queue dropped to about 2,000.
  • At 200, the errors returned after about 40 minutes.
  • At 150, the load ran without further generator errors.

Results are workload-specific, so treat these as a starting point.

How to change it


Make a targeted update to the dataLoaderConfig section of the physical configuration:

 
"dataLoaderConfig": { "udlCloud": "AWS", "maxThreadsCount": 150 }

Change one step at a time and watch the job for 10–20 minutes before changing it again.

Check Configuration (GET)
GET https://<environment>.reltio.com/reltio/tenants/<tenantId>/dataLoaderConfig 
Update Configuration (PUT)
PUT https://<environment>.reltio.com/reltio/tenants/<tenantId>/dataLoaderConfig 
Authorization: Bearer <access_token> 
Content-Type: application/json 
{ "maxThreadsCount": 100, "premiumSettings": 
{ "enabled": true, "maxThreadsCount": 200 } }


Recommendations

  • Lower the value for loads that call a shared ID generator, such as initial loads that create entities with auto-generated IDs.
  • Loads that use pre-populated IDs don't call the generator and can tolerate higher concurrency.
  • Do not update the same entity from parallel threads in one load, and size batches and threads appropriately.
  • Monitor job throughput and failed counts on the Data Loader job page. Contact Support if you see lock timeout errors.

References

Was this article helpful?
0 out of 0 found this helpful

Comments

0 comments

Please sign in to leave a comment.