diff --git a/gui/src/components/entry/properties/SampleHistoryCard.js b/gui/src/components/entry/properties/SampleHistoryCard.js
index 5b2e7db2e19728198d50c79e8ef1b3b9eeeb8366..b2da5ba428912cc56c3f8f2816a43cfea4b54179 100644
--- a/gui/src/components/entry/properties/SampleHistoryCard.js
+++ b/gui/src/components/entry/properties/SampleHistoryCard.js
@@ -21,7 +21,7 @@ import React, { memo, useMemo } from 'react'
 import PropTypes from 'prop-types'
 import { PropertyCard } from './PropertyCard'
 import { SearchContext, useSearchContext } from "../../search/SearchContext"
-import SearchResults from "../../search/SearchResults"
+import { SearchResultsWithContext } from "../../search/SearchResults"
 import { cloneDeep } from "lodash"
 import { ui } from "../../../config"
 
@@ -55,7 +55,7 @@ const HistoryCard = memo(() => {
 
   return (
     <PropertyCard title='History'>
-      <SearchResults
+      <SearchResultsWithContext
         title='activity'
         multiSelect={false}
         PaperProps={{elevation: 0}}
diff --git a/gui/src/components/search/SearchContext.js b/gui/src/components/search/SearchContext.js
index a7ee7fa8762a9355f7a766a043d39bbab0b28ce4..b6c87d255f16b72071fb4e5a604b5d8c36bce7d4 100644
--- a/gui/src/components/search/SearchContext.js
+++ b/gui/src/components/search/SearchContext.js
@@ -57,7 +57,8 @@ import {
   parseQuantityName,
   rsplit,
   parseOperator,
-  getSuggestions
+  getSuggestions,
+  DType
 } from '../../utils'
 import { Quantity } from '../units/Quantity'
 import { Unit } from '../units/Unit'
@@ -246,13 +247,18 @@ export const SearchContextRaw = React.memo(({
     // Add unit information if one is defined. This unit is currently fixed and
     // not affected by global unit system.
     const config = cloneDeep(initialColumns)
-    let options = config?.options ? Object.values(config.options) : []
+    let options = config?.options
+      ? Object.entries(config.options).map(([key, value]) => ({key, ...value}))
+      : []
     options.forEach(option => {
-      const unit = option.unit
+      const storageUnit = initialFilterData[option.quantity || option.key]?.unit
+      const displayUnit = option.unit
       option.label = option.label || initialFilterData[option.quantity || option.key]?.label
-      if (unit) {
-        option.unit = new Unit(unit)
-        option.label = `${option.label} (${option.unit.label()})`
+      if (storageUnit || displayUnit) {
+        const finalUnit = displayUnit
+          ? new Unit(displayUnit)
+          : new Unit(storageUnit).toSystem(units)
+        option.label = `${option.label} (${finalUnit.label()})`
       }
     })
 
@@ -264,7 +270,6 @@ export const SearchContextRaw = React.memo(({
 
         const transform = (value) => {
           const key = option.key
-          const unit = option.unit
           const format = option.format
           const dtype = initialFilterData[key]?.dtype
 
@@ -272,11 +277,15 @@ export const SearchContextRaw = React.memo(({
             return formatTimestamp(value, format?.mode)
           }
 
-          if (unit) {
-            const originalUnit = initialFilterData[key]?.unit
-            value = new Quantity(value, originalUnit).to(unit).value()
+          const storageUnit = initialFilterData[option.quantity || option.key]?.unit
+          const displayUnit = option.unit
+          if (storageUnit || displayUnit) {
+            const finalUnit = displayUnit
+              ? new Unit(displayUnit)
+              : new Unit(storageUnit).toSystem(units)
+            value = new Quantity(value, storageUnit).to(finalUnit).value()
           }
-          if (format) {
+          if (dtype === DType.Int || dtype === DType.Float) {
             value = formatNumber(value, dtype, format?.mode, format?.decimals)
           }
           return value
@@ -359,7 +368,7 @@ export const SearchContextRaw = React.memo(({
     }))
 
     return config
-  }, [initialFilterData, initialColumns, user])
+  }, [initialFilterData, initialColumns, user, units])
 
   // The final row configuration
   const rows = useMemo(() => {
diff --git a/gui/src/components/search/SearchContext.spec.js b/gui/src/components/search/SearchContext.spec.js
index 34a776cfdcd9d637d01c48a71436db832c8424f5..6d8aa5d15e8c96f5c7db247a8b10e17f6c71028d 100644
--- a/gui/src/components/search/SearchContext.spec.js
+++ b/gui/src/components/search/SearchContext.spec.js
@@ -15,14 +15,30 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+import React from 'react'
 import { renderHook, act } from '@testing-library/react-hooks'
 import { WrapperSearch } from './conftest.spec'
-import { useSearchContext } from './SearchContext'
+import { useSearchContext, SearchContextRaw } from './SearchContext'
 import { Quantity } from '../units/Quantity'
 import { isEqualWith } from 'lodash'
+import { Filter } from '../search/Filter'
 import { SearchSuggestion, SuggestionType } from './SearchSuggestion'
 import { WrapperDefault } from '../conftest.spec'
 
+/**
+ * Can be used to wrap the test in a specific search context.
+ */
+const Wrapper = (props) => {
+  return <WrapperDefault>
+    <SearchContextRaw
+      resource="entries"
+      id='entries'
+      {...props}
+    ></SearchContextRaw>
+  </WrapperDefault>
+}
+
 describe('parseQuery', function() {
   test.each([
     ['unit not specified', 'results.material.topology.cell.a', '1', new Quantity(1, 'angstrom'), undefined],
@@ -108,3 +124,21 @@ describe('reading query from URL', function() {
     expect(query).toMatchObject(expected_query)
   })
 })
+
+describe('test that final column information is generated correctly', function() {
+  test.each([
+    ['default unit, default label', {}, new Filter({name: 'test_filter'}, {group: 'test', unit: 'joule'}), 'Test filter (eV)'],
+    ['custom label, default unit', {label: 'Testing'}, new Filter(undefined, {group: 'test', unit: 'joule'}), 'Testing (eV)'],
+    ['default label, custom unit', {}, new Filter({name: 'test_filter'}, {group: 'test', unit: 'joule'}), 'Test filter (eV)'],
+    ['custom label, custom unit', {label: 'Testing', unit: 'Ha'}, new Filter(undefined, {group: 'test', unit: 'joule'}), 'Testing (Ha)']
+  ])('%s', async (name, column, filter, label) => {
+    const key = 'test_filter'
+    const { result: resultUseSearchContext } = renderHook(() => useSearchContext(), { wrapper: (props) => <Wrapper
+      initialFilterData={{[key]: filter}}
+      initialColumns={{options: {[key]: column}}} {...props}
+    />})
+    const columns = resultUseSearchContext.current.columns
+    expect(columns.options[key].label).toBe(label)
+    }
+  )
+})
diff --git a/gui/src/components/search/SearchPage.js b/gui/src/components/search/SearchPage.js
index fcab3b702325455c3899441a0b2c10a1b3c8244c..4845cb1cf41ec2968da080bd79bca6a7674e13f4 100644
--- a/gui/src/components/search/SearchPage.js
+++ b/gui/src/components/search/SearchPage.js
@@ -23,7 +23,7 @@ import { makeStyles } from '@material-ui/core/styles'
 import FilterMainMenu from './menus/FilterMainMenu'
 import { collapsedMenuWidth } from './menus/FilterMenu'
 import SearchBar from './SearchBar'
-import SearchResults from './SearchResults'
+import { SearchResultsWithContext } from './SearchResults'
 import Dashboard from './widgets/Dashboard'
 import { useSearchContext } from './SearchContext'
 
@@ -114,7 +114,7 @@ const SearchPage = React.memo(({
           <Dashboard/>
         </Box>
         <Box position="relative" zIndex={1}>
-          <SearchResults/>
+          <SearchResultsWithContext/>
         </Box>
         <div className={clsx(styles.shadow, isMenuOpen && styles.shadowVisible)}></div>
       </Box>
diff --git a/gui/src/components/search/SearchPage.spec.js b/gui/src/components/search/SearchPage.spec.js
index a426eb3fa89b31765b35979a084cac5907dc508c..bf0936a71182b7ed176b297d3653c8eb062e9eea 100644
--- a/gui/src/components/search/SearchPage.spec.js
+++ b/gui/src/components/search/SearchPage.spec.js
@@ -30,9 +30,8 @@ describe('', () => {
   })
   afterAll(() => closeAPI())
 
-  test.each(
-    Object.entries(ui.apps.options)
-  )('renders search page correctly, context: %s', async (key, context) => {
+  test('renders search page correctly', async () => {
+    const context = ui.apps.options.entries
     render(
       <SearchContext
           resource={context.resource}
diff --git a/gui/src/components/search/SearchResults.js b/gui/src/components/search/SearchResults.js
index d474dd8d2e72461c277dd68a9b4734fb275b2ca4..42602fcaa71ddb2283862a13c1c1e9f804f11367 100644
--- a/gui/src/components/search/SearchResults.js
+++ b/gui/src/components/search/SearchResults.js
@@ -48,18 +48,27 @@ export const ActionURL = React.memo(({action, data}) => {
   </Tooltip>
 })
 ActionURL.propTypes = {
-  // Action configuration from app config
-  action: PropTypes.object.isRequired,
-  // ES index data
-  data: PropTypes.object.isRequired
+  action: PropTypes.object.isRequired, // Action configuration from app config
+  data: PropTypes.object.isRequired // ES index data
 }
 
 /**
  * Displays the list of search results.
  */
-const SearchResults = React.memo((props) => {
-  const {noAction, onSelectedChanged, defaultUncollapsedEntryID, title, 'data-testid': testID, PaperProps, ...otherProps} = props
-  const {columns, resource, rows, useResults, useApiQuery} = useSearchContext()
+export const SearchResults = React.memo(({
+  columns,
+  resource,
+  rows,
+  useResults,
+  useApiQuery,
+  noAction,
+  onSelectedChanged,
+  defaultUncollapsedEntryID,
+  title,
+  'data-testid': testID,
+  PaperProps,
+  ...otherProps
+}) => {
   const {data, pagination, setPagination} = useResults()
   const apiQuery = useApiQuery()
   const [selected, setSelected] = useState(new Set())
@@ -148,6 +157,11 @@ const SearchResults = React.memo((props) => {
 })
 
 SearchResults.propTypes = {
+  columns: PropTypes.object,
+  resource: PropTypes.string,
+  rows: PropTypes.object,
+  useResults: PropTypes.func,
+  useApiQuery: PropTypes.func,
   noAction: PropTypes.bool,
   PaperProps: PropTypes.object,
   onSelectedChanged: PropTypes.func,
@@ -160,4 +174,18 @@ SearchResults.defaultProps = {
   'data-testid': 'search-results'
 }
 
-export default SearchResults
+/**
+ * Displays search results from the current search context.
+ */
+export const SearchResultsWithContext = React.memo((props) => {
+  const {columns, resource, rows, useResults, useApiQuery} = useSearchContext()
+
+  return <SearchResults
+    columns={columns}
+    resource={resource}
+    rows={rows}
+    useResults={useResults}
+    useApiQuery={useApiQuery}
+    {...props}
+  />
+})
diff --git a/gui/src/components/search/SearchResults.spec.js b/gui/src/components/search/SearchResults.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..927cd456cc22b151e050f948ccc4184d7259b812
--- /dev/null
+++ b/gui/src/components/search/SearchResults.spec.js
@@ -0,0 +1,38 @@
+/*
+ * Copyright The NOMAD Authors.
+ *
+ * This file is part of NOMAD. See https://nomad-lab.eu for further info.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react'
+import { renderNoAPI, screen } from '../conftest.spec'
+import { SearchResults } from './SearchResults'
+
+describe('test header', () => {
+  test.each([
+    ['default label', {options: {hello: {key: 'default', render: () => ''}}}, 'Default'],
+    ['custom label', {options: {hello: {key: 'hello', label: 'custom', render: () => ''}}}, 'custom']
+  ])('%s', async (name, columns, expected) => {
+    renderNoAPI(<SearchResults
+      columns={columns}
+      useResults={() => ({
+        data: [{}],
+        pagination: {total: 1}
+      })}
+      useApiQuery={() => ({})}
+    />)
+    expect(screen.getByText(expected)).toBeInTheDocument()
+  })
+})
diff --git a/gui/src/components/search/conftest.spec.js b/gui/src/components/search/conftest.spec.js
index 3dba928ee3c5fbc2f4f081ae5eecb07f34e4ef73..2052e282981591deee38acb6a5071cb989dfb13c 100644
--- a/gui/src/components/search/conftest.spec.js
+++ b/gui/src/components/search/conftest.spec.js
@@ -336,7 +336,7 @@ export async function expectSearchResults(context, root = screen) {
     const columnConfig = context.columns
     const columnLabels = columnConfig.selected.map(key => {
       const config = columnConfig.options[key]
-      const unit = config.unit
+      const unit = config.unit || defaultFilterData[key]?.unit
       const label = config.label || defaultFilterData[key]?.label || getDisplayLabel({name: key.split('.').slice(-1)[0]})
       return unit
         ? `${label} (${new Unit(unit).label()})`
diff --git a/gui/src/components/uploads/SectionSelectDialog.js b/gui/src/components/uploads/SectionSelectDialog.js
index 19bfd72f2d70f54624d0e90d132b07416bb7903c..f9c6200b1b604feae2bd9000a36d9eaf6dc5844c 100644
--- a/gui/src/components/uploads/SectionSelectDialog.js
+++ b/gui/src/components/uploads/SectionSelectDialog.js
@@ -31,7 +31,7 @@ import {useUploadPageContext} from './UploadPageContext'
 import {useEntryStore} from '../entry/EntryContext'
 import {traverse, useGlobalMetainfo} from '../archive/metainfo'
 import { defaultFilterGroups, quantityNameSearch } from '../search/FilterRegistry'
-import SearchResults from '../search/SearchResults'
+import { SearchResultsWithContext } from '../search/SearchResults'
 import {useDataStore} from '../DataStore'
 import {pluralize, resolveNomadUrlNoThrow} from "../../utils"
 import {Check} from '@material-ui/icons'
@@ -382,7 +382,7 @@ function SearchBox({open, onCancel, onSelectedChanged, selected}) {
           {definedFilters.length > 0 && <Chip label={`and ${definedFilters.length} more ${pluralize('filter', definedFilters.length, false)}`} color="primary" onDelete={() => handleResetSearch()}/>}
         </Box>
         <div className={classes.resultsTable}>
-          <SearchResults
+          <SearchResultsWithContext
             defaultUncollapsedEntryID={selected?.entry_id}
             multiSelect={false}
             noAction
diff --git a/nomad/config/models/ui.py b/nomad/config/models/ui.py
index 7bcc67aa6da030ea6441a3962e1bdbe5d0752371..388209989e303a85e28e89d3fdc185b210e42fae 100644
--- a/nomad/config/models/ui.py
+++ b/nomad/config/models/ui.py
@@ -224,7 +224,7 @@ class Format(ConfigBaseModel):
     """Value formatting options."""
 
     decimals: int = Field(3, description='Number of decimals to show for numbers.')
-    mode: ModeEnum = Field('standard', description='Display mode for numbers.')
+    mode: ModeEnum = Field(ModeEnum.SCIENTIFIC, description='Display mode for numbers.')
 
 
 class AlignEnum(str, Enum):