Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
cc58574
feat: add vector sizing calculator files for docs-builder
Feb 18, 2026
f3a750d
feat(site): add vector sizing web component under assets
Feb 18, 2026
9b0ca4c
feat(markdown): wire vector-sizing-calculator directive in Elastic.Ma…
itsalexcm Apr 13, 2026
54bb5a7
docs: add vector sizing calculator preview page for local serve
itsalexcm Apr 13, 2026
b14d1c8
Merge remote-tracking branch 'origin/main' into feat/vector-sizing-ca…
itsalexcm Apr 21, 2026
7a15c13
feat(site): refine vector sizing calculator UX and assets
itsalexcm Apr 21, 2026
957222e
fix(site): remove vector sizing CTA and fix Parcel stale bundles
itsalexcm Apr 21, 2026
6ec67b7
fix(ci): satisfy formatter checks and assertion namespace
itsalexcm Apr 22, 2026
5434c9c
fix(ci): address TS and dotnet format failures
itsalexcm Apr 22, 2026
1c00492
Merge remote-tracking branch 'origin/main' into feat/vector-sizing-ca…
itsalexcm Apr 22, 2026
c1a9224
Enable handbook preview deployments and PR comments
itsalexcm May 12, 2026
c9e4d4c
Merge origin/main into feat/vector-sizing-calculator
itsalexcm May 12, 2026
d3a2d4c
feat(vector-sizing-calculator): add shared display and formulas compo…
itsalexcm May 25, 2026
f7a8a99
feat(vector-sizing-calculator): polish configuration, results, and fo…
itsalexcm May 25, 2026
127bce4
chore(vector-sizing-calculator): sync standalone web-component helpers
itsalexcm May 25, 2026
c23e0ea
Merge origin/main into feat/vector-sizing-calculator
itsalexcm May 26, 2026
12c4fa4
fix(vector-sizing-calculator): remove unused EuiSpacer import
itsalexcm May 26, 2026
4a7f3f7
style(vector-sizing-calculator): run prettier on calculator sources
itsalexcm May 26, 2026
ba915a5
feat(vector-sizing-calculator): improve DiskBBQ and HNSW advanced UX
itsalexcm May 26, 2026
b43a364
feat(vector-sizing-calculator): DiskBBQ RAM range and clearer replica UX
itsalexcm May 26, 2026
d22158e
feat(vector-sizing-calculator): put quantization and replica shards o…
itsalexcm May 26, 2026
ca96358
Merge branch 'main' into feat/vector-sizing-calculator
pmpailis Jun 18, 2026
981f8a3
Merge branch 'main' into feat/vector-sizing-calculator
itsalexcm Jul 6, 2026
f3e066d
Initial plan - resolving merge conflicts
Copilot Jul 28, 2026
7c10150
Resolve merge conflicts with main branch
Copilot Jul 28, 2026
989aef9
updating sizing computations
pmpailis Jul 28, 2026
be50d53
updating computations and have GiB instead of GB
pmpailis Jul 28, 2026
099e57b
remodelling ui
pmpailis Jul 28, 2026
10afa9a
updating ui and content
pmpailis Jul 28, 2026
2ee72d1
updating explainer and styling
pmpailis Jul 29, 2026
6f96ec1
updating label
pmpailis Jul 29, 2026
116714d
addressing review comments
pmpailis Jul 29, 2026
67935dc
removing note
pmpailis Jul 29, 2026
1e867da
updating
pmpailis Jul 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 80 additions & 7 deletions .github/workflows/docs-preview-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: read
deployments: none
deployments: write
id-token: write
pull-requests: none
outputs:
Expand All @@ -217,10 +217,8 @@ jobs:
persist-credentials: false

- name: Create Deployment
# disabled: deployments are not enabled on this branch
if: >
false
&& env.MATCH == 'true'
env.MATCH == 'true'
&& needs.check.outputs.any_modified != 'false'
&& (
github.event_name == 'push'
Expand Down Expand Up @@ -364,10 +362,8 @@ jobs:

- name: Update deployment status
uses: actions/github-script@v8
# disabled: deployments are not enabled on this branch
if: >
false
&& env.MATCH == 'true'
env.MATCH == 'true'
&& always()
&& steps.deployment.outputs.result
env:
Expand All @@ -383,3 +379,80 @@ jobs:
environment_url: `https://docs-v3-preview.elastic.dev${process.env.LANDING_PAGE_PATH}`,
log_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
})

comment:
if: >
github.event_name == 'pull_request'
&& needs.check.outputs.any_modified == 'true'
&& needs.build.outputs.path_prefix != ''
&& needs.build.result == 'success'
runs-on: ubuntu-latest
needs:
- check
- build
permissions:
contents: none
deployments: none
id-token: none
pull-requests: write
steps:
- name: Comment handbook preview links on PR
uses: actions/github-script@v8
env:
PATH_PREFIX: ${{ needs.build.outputs.path_prefix }}
ALL_CHANGED_FILES: ${{ needs.check.outputs.all_changed_files }}
with:
script: |
const title = '## Docs preview (local build)'
const base = `https://docs-v3-preview.elastic.dev${process.env.PATH_PREFIX}`
const changedMdFiles = process.env.ALL_CHANGED_FILES
.split(/\s+/)
.filter(Boolean)
.filter((i) => i.endsWith('.md'))
.filter((i) => !i.includes('/_snippets/'))

const lines = [title, '', `**Handbook preview:** ${base}/`, '']

if (changedMdFiles.length > 0) {
lines.push('Sample changed pages:')
for (const file of changedMdFiles.slice(0, 15)) {
const path = file
.replace(/^docs\//, '')
.replace(/\/index\.md$/, '')
.replace(/\.md$/, '')
lines.push(`- [${file}](${base}/${path})`)
}
if (changedMdFiles.length > 15) {
lines.push(`- …and ${changedMdFiles.length - 15} more`)
}
}

const body = lines.join('\n')
const owner = context.repo.owner
const repo = context.repo.repo
const issue_number = context.payload.pull_request.number

const { data: comments } = await github.rest.issues.listComments({
owner,
repo,
issue_number,
})
const existing = comments.find(
(c) =>
c.user.type === 'Bot' && c.body.startsWith(title)
)
if (existing) {
await github.rest.issues.updateComment({
owner,
repo,
comment_id: existing.id,
body,
})
} else {
await github.rest.issues.createComment({
owner,
repo,
issue_number,
body,
})
}
1 change: 1 addition & 0 deletions docs/_docset.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
project: 'doc-builder'

Check notice on line 1 in docs/_docset.yml

View workflow job for this annotation

GitHub Actions / build

Irregular space detected. Run 'docs-builder format --write' to automatically fix all instances.
max_toc_depth: 2
dev_docs: true
Expand Down Expand Up @@ -102,6 +102,7 @@
- file: videos.md
- file: kbd.md
- file: math.md
- file: vector-sizing-calculator.md
- file: diagrams.md
- file: lists.md
- file: task-lists.md
Expand Down
1 change: 1 addition & 0 deletions docs/syntax/directives.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,4 @@ The following directives are available:
- [Tabs](tabs.md) - Tabbed content organization
- [Tables](tables.md) - Data tables
- [Version blocks](version-variables.md) - API version information
- [Vector sizing calculator](vector-sizing-calculator.md) - Interactive dense_vector sizing estimates
21 changes: 21 additions & 0 deletions docs/syntax/vector-sizing-calculator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Vector sizing calculator

The `{vector-sizing-calculator}` directive embeds an interactive calculator for estimating disk and off-heap memory for `dense_vector` fields. The docs site loads the React/EUI web component that registers the `<vector-sizing-calculator>` custom element.

## Usage

```markdown
:::{vector-sizing-calculator}
:::
```

No body content or options are required. Configuration happens in the widget UI.

## Live preview

:::{vector-sizing-calculator}
:::

## Requirements

This directive only produces useful output where the assembled documentation site includes the vector sizing bundle (see `src/Elastic.Documentation.Site/Assets/web-components/VectorSizingCalculator/`).
1 change: 1 addition & 0 deletions src/Elastic.Documentation.Site/Assets/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
@import './markdown/contributors.css';
@import './markdown/storybook.css';
@import './api-docs.css';
@import './web-components/VectorSizingCalculator/vector-sizing-calculator.css';
@import 'tippy.js/dist/tippy.css';

html {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { calculate, validate, getAvailableQuantizations } from './calculations'
import { ComponentBreakdownTable } from './components/ComponentBreakdownTable'
import { ConfigurationPanel } from './components/ConfigurationPanel'
import { ExplainersPanel } from './components/ExplainersPanel'
import { ResultsPanel } from './components/ResultsPanel'
import { parseVectorCount } from './parseVectorCount'
import type {
ElementType,
IndexType,
Quantization,
CalculatorInputs,
} from './types'
import { useState, useMemo, useEffect } from 'react'

function getAvailableIndexTypes(elementType: ElementType) {
const options = [
{ value: 'hnsw', text: 'HNSW' },
{ value: 'flat', text: 'Flat (brute-force)' },
]
if (elementType === 'float' || elementType === 'bfloat16') {
options.push({ value: 'disk_bbq', text: 'DiskBBQ' })
}
return options
}

export function Calculator() {
const [vectorsText, setVectorsText] = useState('1,000,000')
const [numDimensions, setNumDimensions] = useState<number | string>(768)
const [elementType, setElementType] = useState<ElementType>('float')
const [indexType, setIndexType] = useState<IndexType>('hnsw')
const [quantization, setQuantization] = useState<Quantization>('bbq')
const [replicas, setReplicas] = useState(0)
const [hnswM, setHnswM] = useState(16)
const efConstruction = 100
const [vectorsPerCluster, setVectorsPerCluster] = useState(384)
const [offHeapRamPercent, setOffHeapRamPercent] = useState(10)

const indexTypeOptions = useMemo(
() => getAvailableIndexTypes(elementType),
[elementType]
)
const quantOptions = useMemo(
() => getAvailableQuantizations(elementType, indexType),
[elementType, indexType]
)

useEffect(() => {
const available = indexTypeOptions.map((o) => o.value)
if (!available.includes(indexType)) {
setIndexType(available[0] as IndexType)
}
}, [indexTypeOptions, indexType])

useEffect(() => {
const available = quantOptions.map((o) => o.value)
if (!available.includes(quantization)) {
setQuantization(available[0] as Quantization)
}
}, [quantOptions, quantization])

const inputs: CalculatorInputs = useMemo(
() => ({
numVectors: parseVectorCount(vectorsText),
numDimensions:
typeof numDimensions === 'number' ? numDimensions : NaN,
elementType,
indexType,
quantization,
replicas,
hnswM,
efConstruction,
vectorsPerCluster,
offHeapRamPercent,
}),
[
vectorsText,
numDimensions,
elementType,
indexType,
quantization,
replicas,
hnswM,
efConstruction,
vectorsPerCluster,
offHeapRamPercent,
]
)

const validation = useMemo(() => validate(inputs), [inputs])
const result = useMemo(
() => (validation.valid ? calculate(inputs) : null),
[inputs, validation]
)

const quantizationLabel = useMemo(
() => quantOptions.find((o) => o.value === quantization)?.label ?? '',
[quantOptions, quantization]
)

const inputsValid = Boolean(validation.valid && result !== null)

return (
<div className="vectorSizingCalc">
<div className="vectorSizingCalc__grid">
<ConfigurationPanel
vectorsText={vectorsText}
onVectorsChange={setVectorsText}
numDimensions={numDimensions}
onDimensionsChange={setNumDimensions}
elementType={elementType}
onElementTypeChange={setElementType}
indexType={indexType}
onIndexTypeChange={setIndexType}
indexTypeOptions={indexTypeOptions}
quantization={quantization}
onQuantizationChange={setQuantization}
quantOptions={quantOptions}
replicas={replicas}
onReplicasChange={setReplicas}
hnswM={hnswM}
onHnswMChange={setHnswM}
vectorsPerCluster={vectorsPerCluster}
onVectorsPerClusterChange={setVectorsPerCluster}
offHeapRamPercent={offHeapRamPercent}
onOffHeapRamPercentChange={setOffHeapRamPercent}
validation={validation}
/>

<ResultsPanel
result={result}
inputsValid={inputsValid}
quantizationLabel={quantizationLabel}
replicas={replicas}
validation={validation}
/>
</div>

<ComponentBreakdownTable
result={result}
inputsValid={inputsValid}
/>

<ExplainersPanel />
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import '../../eui-icons-cache'
import { Calculator } from './Calculator'
import { EuiProvider } from '@elastic/eui'
import r2wc from '@r2wc/react-to-web-component'
import * as React from 'react'
import { StrictMode } from 'react'

const VectorSizingCalculatorWrapper = () => {
return (
<StrictMode>
<EuiProvider
colorMode="light"
globalStyles={false}
utilityClasses={false}
>
<Calculator />
</EuiProvider>
</StrictMode>
)
}

if (!customElements.get('vector-sizing-calculator')) {
customElements.define(
'vector-sizing-calculator',
r2wc(VectorSizingCalculatorWrapper)
)
}
Loading
Loading