{#if yamlMode}

Use this YAML to manage instance settings as code. Learn more

handleShowSensitiveToggle(e.detail)} options={{ right: 'Show sensitive values' }} size="xs" />
{#await import('$lib/components/SimpleEditor.svelte')} {:then Module} {/await}
{#if yamlError}
{yamlError}
{/if} {:else if hideTabs} {@render categoryContent(tab)} {:else} {#each settingsKeys as category} {/each} {#snippet content()}
{#each Object.keys(settings) as category} {@render categoryContent(category)} {/each} {/snippet}
{/if} {#snippet categoryContent(category: string)} {#if category == 'Core'} {:else if category == 'SMTP'} {:else if category == 'Registries'} {#if !$enterpriseLicense} {/if} {:else if category == 'Alerts'} {:else if category == 'OTEL/Prom'} {:else if category == 'Indexer'} {#if !$enterpriseLicense} {/if} {:else if category == 'Telemetry'} {#if $enterpriseLicense}
Telemetry is required on Enterprise Edition for license compliance. When minimal telemetry is enabled, only the following data is sent:
  • Instance version and base URL
  • Login types, user and seat counts
  • Worker count, vCPUs and memory
  • Superadmin email addresses
  • Development instance status

When minimal telemetry is disabled, the following is also collected:
  • Job counts and durations per language
  • Git sync repository counts
  • Feature usage and adoption counts, including AI model and public Hub names
  • Counts of workspaces, scripts, flows and apps
  • Database, runtime and object storage details

For air-gapped instances, you can download the telemetry data and send it manually.
{:else}
Anonymous usage data is collected to help improve Windmill.
The following information is collected:
  • Instance version and base URL
  • Job counts and durations per language
  • Login types, user and seat counts
  • Worker count, vCPUs and memory
  • Development instance status
  • Feature usage and adoption counts, including AI model and public Hub names
  • Counts of workspaces, scripts, flows and apps
{/if} {:else if category == 'Jobs'} {:else if category == 'Workspace roles'} {:else if category == 'Service logs'} {#if !$values['object_store_cache_config']}
Instance object storage is not configured, so every server and worker keeps its log files on its own disk. This page lists what each host wrote, but can only open the files belonging to the replica serving the request — another host's are listed and not readable — and a host's files go with it when it is replaced. Retention below still governs the entries in the database and the files on disk.
{:else if !$enterpriseLicense}
Log files are uploaded to instance object storage, and the indexer that would ingest them into the columnar store and delete each one afterwards is an enterprise feature. Retention below expires the database entries and the local files; the uploaded copies are only removed when Delete logs from s3 periodically is on under Object Storage.
{/if} {:else if category == 'Object Storage'} {:else if category == 'Private Hub'} {:else if category == 'Secret Storage'} {:else if category == 'GitHub App'} {:else if category == 'DB Health'} {:else if category == 'OIDC signing'} {#if $enterpriseLicense} {/if} {:else if category == 'Agent workers'} {:else if category == 'Auth/OAuth/SAML'} {#snippet scim()}
{#each scimSamlSetting as setting} closeDrawer?.()} {loading} {setting} {values} {markSettingSaved} {version} {oauths} /> {/each}
{/snippet}
{/if}
{#each settings[category] as setting} {#if setting.fieldType != 'slack_connect' && !(quickSetup && setting.hideInQuickSetup) && !(quickSetup && category === 'Core' && setting.key === 'license_key')} closeDrawer?.()} {loading} {setting} {values} {markSettingSaved} {version} {oauths} warning={setting.key === 'base_url' && baseUrlIsFallback ? 'Auto-detected from browser — not yet saved' : setting.key === 'nuget_config' && $values['nuget_config'] && !//.test($values['nuget_config']) ? 'Missing in . Without it, default sources (like nuget.org) are merged with your custom sources, which is likely not what you want.' : undefined} /> {/if} {#if quickSetup && category === 'Core' && setting.key === 'base_url'} {@const licenseKeySetting = settings['Core'].find((s) => s.key === 'license_key')} {#if licenseKeySetting} closeDrawer?.()} {loading} setting={licenseKeySetting} {values} {version} {oauths} /> {/if} {/if} {/each} {#if quickSetup && category === 'Core'} {@const extraSettings = [ ...settings['Jobs'].filter((s) => s.key === 'job_isolation'), ...settings['Jobs'].filter((s) => s.key === 'retention_period_secs'), ...(settings['Object Storage']?.filter((s) => s.key === 'object_store_cache_config') ?? []) ]} {#each extraSettings as setting} closeDrawer?.()} {loading} {setting} {values} {markSettingSaved} {version} {oauths} /> {/each} {/if}
{#if category === 'Registries'} {/if} {#if !loading && !quickSetup && !hideTabs} saveCategorySettings(category)} onDiscard={() => discardCategory(category)} saveLabel={`Save ${category.toLowerCase()} settings`} class="bg-surface" /> {/if} {/snippet}