SONAR analysis extremely slow with version 2025.3.1

After upgrade from Sonar developer edition 9.9 to 2025.3.1 the Sonar analysis has become extreme slow with an average of 8 minutes while I expect it to be under 1 minute.

This is what we use:

  • SonarQube Server developer edition 2025.3.1 (109879)
  • OS: Microsoft Windows Server 2019 Standard
  • Database: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production Version 19.23.0.0.0
  • OJDBC Driver: 23.9.0.25.07

Memory usage and CPU usage on de SonarQube server are low. Extending memory setting for Sonar does not change that so it seems Sonar is not busy. The Database server is also not busy.

What we see is that this query takes an awfull lot of time:

executions time cost last_active_time SQL_fulltext
36 17051958493 9112 2025-08-14 23:54:10.000

select
    rdi.rule_uuid as "rdi_ruleUuid",
    rdi.software_quality as "rdi_softwareQuality",
    rdi.severity as "rdi_severity",
    CASE WHEN rt.is_system_tag = 1 THEN rt.value ELSE NULL END as rt_systemTags,
    CASE WHEN rt.is_system_tag = 0 THEN rt.value ELSE NULL END as rt_tags,
    rt.is_system_tag as "rt_isSystemTag",
    rt.value as "rt_value",
    rds.content as "rds_content",
    rds.uuid as "rds_uuid",
    rds.kee as "rds_kee",
    rds.context_key as "rds_contextKey",
    rds.context_display_name as "rds_contextDisplayName",
    r.uuid as "r_uuid",
    r.plugin_rule_key as "ruleKey",
    r.plugin_name as "repositoryKey",
    r.description_format as "descriptionFormat",
    r.status,
    r.name,
    r.plugin_config_key as "configKey",
    r.priority as "severity",
    r.is_template as "isTemplate",
    r.is_external as "isExternal",
    r.is_ad_hoc as "isAdHoc",
    r.language as "language",
    r.template_uuid as "templateUuid",
    r.def_remediation_function as "defRemediationFunction",
    r.def_remediation_gap_mult as "defRemediationGapMultiplier",
    r.def_remediation_base_effort as "defRemediationBaseEffort",
    r.gap_description as "gapDescription",
    r.security_standards as "securityStandardsField",
    r.rule_type as "type",
    r.plugin_key as "pluginKey",
    r.scope,
    r.created_at as "createdAt",
    r.updated_at as "updatedAt",
    r.note_data as "noteData",
    r.note_user_uuid as "noteUserUuid",
    r.note_created_at as "noteCreatedAt",
    r.note_updated_at as "noteUpdatedAt",
    r.remediation_function as "remediationFunction",
    r.remediation_gap_mult as "remediationGapMultiplier",
    r.remediation_base_effort as "remediationBaseEffort",
    r.ad_hoc_name as "adHocName",
    r.ad_hoc_description as "adHocDescription",
    r.ad_hoc_severity as "adHocSeverity",
    r.ad_hoc_type as "adHocType",
    r.education_principles as "educationPrinciplesField",
    r.clean_code_attribute as "cleanCodeAttribute"
    from
      rules r
    left outer join rule_desc_sections rds on
      rds.rule_uuid = r.uuid
    left outer join rules_default_impacts rdi on
      rdi.rule_uuid = r.uuid
    left outer join rule_tags rt on
      rt.rule_uuid = r.uuid
    order by r.uuid

What can we do to solve the problem so that analyses gets at least under 1 minute?

Have you updated your database indexes and dropped unused data since the upgrade?

Every analysis Sonarqube is stuck on the specific step ‘Load quality profiles’ (Sonarqube_ce.log):

2025.08.20 15:07:15 INFO ce[65a3f46b-3402-4cce-86d3-48780d95b7e9][o.s.c.t.s.ComputationStepExecutor] Load quality profiles | status=SUCCESS | time=456015ms

Even with the logs level trace, there’s no useful or extra logging during the part where the process seems stuck. During this step this query is being executed in our Oracle Database. Executing this query on the machine, we’ve noticed a duration of 6 seconds.

SELECT
   rdi.rule_uuid as “rdi_ruleUuid”,
   rdi.software_quality as “rdi_softwareQuality”,
   rdi.severity as “rdi_severity”,
   CASE WHEN rt.is_system_tag = 1 THEN rt.value ELSE NULL END as rt_systemTags,
   CASE WHEN rt.is_system_tag = 0 THEN rt.value ELSE NULL END as rt_tags,
   rt.is_system_tag as “rt_isSystemTag”,
   rt.value as “rt_value”,
   rds.content as “rds_content”,
   rds.uuid as “rds_uuid”,
   rds.kee as “rds_kee”,
   rds.context_key as “rds_contextKey”,
   rds.context_display_name as “rds_contextDisplayName”,
   r.uuid as “r_uuid”,
   r.plugin_rule_key as “ruleKey”,
   r.plugin_name as “repositoryKey”,
   r.description_format as “descriptionFormat”,
   r.status,r.name,r.plugin_config_key as “configKey”,
   r.priority as “severity”,
   r.is_template as “isTemplate”,
   r.is_external as “isExternal”,
   r.is_ad_hoc as “isAdHoc”,
   r.language as “language”,
   r.template_uuid as “templateUuid”,
   r.def_remediation_function as “defRemediationFunction”,
   r.def_remediation_gap_mult as “defRemediationGapMultiplier”,
   r.def_remediation_base_effort as “defRemediationBaseEffort”,
   r.gap_description as “gapDescription”,
   r.security_standards as “securityStandardsField”,
   r.rule_type as “type”,
   r.plugin_key as “pluginKey”,
   r.scope,r.created_at as “createdAt”,
   r.updated_at as “updatedAt”,
   r.note_data as “noteData”,
   r.note_user_uuid as “noteUserUuid”,
   r.note_created_at as “noteCreatedAt”,
   r.note_updated_at as “noteUpdatedAt”,
   r.remediation_function as “remediationFunction”,
   r.remediation_gap_mult as “remediationGapMultiplier”,
   r.remediation_base_effort as “remediationBaseEffort”,
   r.ad_hoc_name as “adHocName”,
   r.ad_hoc_description as “adHocDescription”,
   r.ad_hoc_severity as “adHocSeverity”,
   r.ad_hoc_type as “adHocType”,
   r.education_principles as “educationPrinciplesField”,
   r.clean_code_attribute as “cleanCodeAttribute”
   from
      rules r
   left outer join rule_desc_sections rds on
      rds.rule_uuid = r.uuid
   left outer join rules_default_impacts rdi on
      rdi.rule_uuid = r.uuid
   left outer join rule_tags rt on
      rt.rule_uuid = r.uuid
   order by r.uuid;

With the SQL_ID of this query we can tell that Sonar is holding onto the data for the time it’s processing the load quality profiles step:

SELECT sql_exec_id,
   COUNT(*) samples,
   MIN(sample_time) min_t,
   MAX(sample_time) max_t
FROM v$active_session_history
WHERE sql_id = ‘6ag2x7ps29ztf’
GROUP BY sql_exec_id
ORDER BY min_t DESC;
SQL_EXEC_ID SAMPLES MIN_T MAX_T
16,777,372 458 2025-08-21 12:55:26.690 2025-08-21 13:03:06.223
16,777,371 451 2025-08-21 12:46:58.152 2025-08-21 12:54:32.612
16,777,370 454 2025-08-21 12:39:02.438 2025-08-21 12:46:39.119

If we check the roundtrip, we can see that the database isn’t the bottleneck during this proces.

SELECT name, round(value/100,2) as ms
FROM   v$sysstat
WHERE  name LIKE ‘%SQL*Net roundtrip%’;
NAME MS
SQL*Net roundtrips to/from client 42688.23
SQL*Net roundtrips to/from dblink 0

The tables have been analysed recently as well.

SELECT table_name, last_analyzed, num_rows, blocks, sample_size
FROM dba_tab_statistics
WHERE owner = ‘SONAR’
   AND table_name IN (
      ‘RULES’,
      ‘RULE_DESC_SECTIONS’,
      ‘RULE_TAGS’,
      ‘RULES_DEFAULT_IMPACTS’,
      ‘COMPONENTS’
)
ORDER BY last_analyzed DESC;
TABLE_NAME LAST_ANALYZED NUM_ROWS BLOCKS SAMPLE_SIZE
COMPONENTS 2025-08-19 06:00:15.000 113412 11260 113412
RULE_DESC_SECTIONS 2025-08-14 06:08:56.000 30440 4956 30440
RULE_TAGS 2025-08-14 06:08:55.000 11566 65 11566
RULES 2025-08-14 06:08:55.000 21557 764 21557
RULES_DEFAULT_IMPACTS 2025-07-17 06:19:13.000 21152 244 21152

And the database columns all have indexes.

SELECT index_name, column_name
FROM dba_ind_columns
WHERE table_name IN (‘RULES’,‘RULE_DESC_SECTIONS’,‘RULE_TAGS’,‘RULES_DEFAULT_IMPACTS’,‘COMPONENTS’)
AND table_owner = ‘SONAR’
ORDER BY table_name, index_name, column_position;
INDEX_NAME COLUMN_NAME
COMPONENTS_BRANCH_UUID BRANCH_UUID
COMPONENTS_KEE_BRANCH_UUID KEE
COMPONENTS_KEE_BRANCH_UUID BRANCH_UUID
COMPONENTS_UUID UUID
PROJECTS_QUALIFIER QUALIFIER
PK_RULES UUID
RULES_REPO_KEY PLUGIN_NAME
RULES_REPO_KEY PLUGIN_RULE_KEY
UNIQ_RUL_UUID_SOF_QUAL RULE_UUID
UNIQ_RUL_UUID_SOF_QUAL SOFTWARE_QUALITY
PK_RULE_DESC_SECTIONS UUID
UNIQ_RULE_DESC_SECTIONS RULE_UUID
UNIQ_RULE_DESC_SECTIONS KEE
UNIQ_RULE_DESC_SECTIONS CONTEXT_KEY
PK_RULE_TAGS VALUE
PK_RULE_TAGS RULE_UUID
RULE_TAGS_RULE_UUID RULE_UUID
RULE_TAGS_RULE_UUID VALUE
RULE_TAGS_RULE_UUID IS_SYSTEM_TAG

More information about the content of our profiles and rules:

The table content sizes

Table Rows
components 112318
rules 21557
issues 376892
snapshots 5822
rule_desc_sections 30440
rules_default_impacts 21152
rule_tags 11566

Yes, done that. That did not improve the situation. The analyses still takes up to 8 minutes.

Hey @wma

My understanding is that we had a performance regression on this step (SONAR-24006) that was fixed in SonarQube 2025.1.

If you’re correct that the database here isn’t the bottleneck (it was in SONAR-24006, and we needed to add an index), I’d turn your attention to the SonarQube server itself. What kind of resources are available, and have you tuned your Java options? Specifically. sonar.ce.javaOpts would be relevant here.

How many rows are returned?

sonar.ce.javaOpts=-Xms2g -Xmx3g -XX:+HeapDumpOnOutOfMemoryError

The slow query returned 41159 rows.

Refined:

Thanks @wma

Quoting Wim Machiels:

  • Database: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 – Production Version 19.23.0.0.0
  • OJDBC Driver: 23.9.0.25.07

As a suggestion, could you try using the ojdbc10.jar version available under Oracle Database 19c (19.28.0.0) JDBC Driver & UCP Downloads - Long Term Release? This version aligns more closely with your current DB version and could help identify or rule out compatibility issues.

Switching to ojdbc10.jar was a bad idea. On average the jobs are 2 minutes slower than before

Alright, good to know. Sorry about that!

Back to this query:

SELECT
   rdi.rule_uuid as “rdi_ruleUuid”,
   rdi.software_quality as “rdi_softwareQuality”,
   rdi.severity as “rdi_severity”,
   CASE WHEN rt.is_system_tag = 1 THEN rt.value ELSE NULL END as rt_systemTags,
   CASE WHEN rt.is_system_tag = 0 THEN rt.value ELSE NULL END as rt_tags,
   rt.is_system_tag as “rt_isSystemTag”,
   rt.value as “rt_value”,
   rds.content as “rds_content”,
   rds.uuid as “rds_uuid”,
   rds.kee as “rds_kee”,
   rds.context_key as “rds_contextKey”,
   rds.context_display_name as “rds_contextDisplayName”,
   r.uuid as “r_uuid”,
   r.plugin_rule_key as “ruleKey”,
   r.plugin_name as “repositoryKey”,
   r.description_format as “descriptionFormat”,
   r.status,r.name,r.plugin_config_key as “configKey”,
   r.priority as “severity”,
   r.is_template as “isTemplate”,
   r.is_external as “isExternal”,
   r.is_ad_hoc as “isAdHoc”,
   r.language as “language”,
   r.template_uuid as “templateUuid”,
   r.def_remediation_function as “defRemediationFunction”,
   r.def_remediation_gap_mult as “defRemediationGapMultiplier”,
   r.def_remediation_base_effort as “defRemediationBaseEffort”,
   r.gap_description as “gapDescription”,
   r.security_standards as “securityStandardsField”,
   r.rule_type as “type”,
   r.plugin_key as “pluginKey”,
   r.scope,r.created_at as “createdAt”,
   r.updated_at as “updatedAt”,
   r.note_data as “noteData”,
   r.note_user_uuid as “noteUserUuid”,
   r.note_created_at as “noteCreatedAt”,
   r.note_updated_at as “noteUpdatedAt”,
   r.remediation_function as “remediationFunction”,
   r.remediation_gap_mult as “remediationGapMultiplier”,
   r.remediation_base_effort as “remediationBaseEffort”,
   r.ad_hoc_name as “adHocName”,
   r.ad_hoc_description as “adHocDescription”,
   r.ad_hoc_severity as “adHocSeverity”,
   r.ad_hoc_type as “adHocType”,
   r.education_principles as “educationPrinciplesField”,
   r.clean_code_attribute as “cleanCodeAttribute”
   from
      rules r
   left outer join rule_desc_sections rds on
      rds.rule_uuid = r.uuid
   left outer join rules_default_impacts rdi on
      rdi.rule_uuid = r.uuid
   left outer join rule_tags rt on
      rt.rule_uuid = r.uuid
   order by r.uuid;

It would be great to analyze the results. I’ll send you a PM since that will probably be easier for you to send over the results.

Finally this looks very similar to SonarQube Upgrade Issue: Background Task Failure (Compute Engine)

Hopefully a second data point here will help us track down the root issue

I think this is the same as this issue: Jira