diff --git a/frontend/src/metabase/static-viz/components/XYChart/Values/Values.tsx b/frontend/src/metabase/static-viz/components/XYChart/Values/Values.tsx
index 0aaf2abfbe321f4950441a7d5cafd8c0ba2c914d..86ff531ce434e90fa4600f25ed0a73c9ded64a3d 100644
--- a/frontend/src/metabase/static-viz/components/XYChart/Values/Values.tsx
+++ b/frontend/src/metabase/static-viz/components/XYChart/Values/Values.tsx
@@ -68,8 +68,8 @@ export default function Values({
   if (containBars && xScale.bandwidth) {
     const innerBarScaleDomain = multipleSeries
       .filter(series => series.type === "bar")
-      .map((barSerie, index) => {
-        barSeriesIndexMap.set(barSerie, index);
+      .map((barSeries, index) => {
+        barSeriesIndexMap.set(barSeries, index);
         return index;
       });
     innerBarScale = scaleBand({
@@ -79,8 +79,15 @@ export default function Values({
   }
 
   const multiSeriesValues: MultiSeriesValue[][] = multipleSeries.map(series => {
-    const singleSerieValues = getValues(series, areStacked);
-    return singleSerieValues.map(value => {
+    const singleSeriesValues =
+      series.type === "bar"
+        ? fixSmallBarChartValues(
+            getValues(series, areStacked),
+            innerBarScale?.domain().length ?? 0,
+          )
+        : getValues(series, areStacked);
+
+    return singleSeriesValues.map(value => {
       return {
         ...value,
         series,
@@ -92,6 +99,21 @@ export default function Values({
     });
   });
 
+  function fixSmallBarChartValues(
+    singleSeriesValues: Value[],
+    numberOfBarSeries: number,
+  ) {
+    const barWidth = innerBarScale?.bandwidth() ?? Infinity;
+    const MIN_BAR_WIDTH = 20;
+    // Use the same logic as in https://github.com/metabase/metabase/blob/cb51e574de31c7d4485a9dfbef3261f67c0b7495/frontend/src/metabase/visualizations/lib/chart_values.js#L138
+    if (numberOfBarSeries > 1 && barWidth < MIN_BAR_WIDTH) {
+      singleSeriesValues.forEach(value => {
+        value.hidden = true;
+      });
+    }
+    return singleSeriesValues;
+  }
+
   function getBarXOffset(series: HydratedSeries) {
     if (containBars && innerBarScale) {
       // Use the same logic when rendering <BarSeries />, as bar charts can display values in groups.
@@ -112,13 +134,15 @@ export default function Values({
 
   return (
     <>
-      {verticalOverlappingFreeValues.map((singleSerieValues, seriesIndex) => {
-        const compact = getCompact(singleSerieValues.map(value => value.datum));
+      {verticalOverlappingFreeValues.map((singleSeriesValues, seriesIndex) => {
+        const compact = getCompact(
+          singleSeriesValues.map(value => value.datum),
+        );
 
         return fixHorizontalOverlappingValues(
           seriesIndex,
           compact,
-          singleSerieValues,
+          singleSeriesValues,
         ).map((value, index) => {
           if (value.hidden) {
             return null;
@@ -180,7 +204,7 @@ export default function Values({
   function fixHorizontalOverlappingValues(
     seriesIndex: number,
     compact: boolean,
-    singleSerieValues: MultiSeriesValue[],
+    singleSeriesValues: MultiSeriesValue[],
   ) {
     const valueStep = getValueStep(
       multipleSeries,
@@ -190,7 +214,7 @@ export default function Values({
       innerWidth,
     );
 
-    return singleSerieValues.filter((_, index) => index % valueStep === 0);
+    return singleSeriesValues.filter((_, index) => index % valueStep === 0);
   }
 }
 
diff --git a/frontend/src/metabase/static-viz/lib/numbers.ts b/frontend/src/metabase/static-viz/lib/numbers.ts
index 9d8e864b855def46449c3279d76a4ed72d38ab7b..fad75199b4ca7d3bbdd24288137ba5ff6dccb1c5 100644
--- a/frontend/src/metabase/static-viz/lib/numbers.ts
+++ b/frontend/src/metabase/static-viz/lib/numbers.ts
@@ -1,3 +1,5 @@
+import { merge } from "icepick";
+
 export type NumberFormatOptions = {
   number_style?: "currency" | "decimal" | "scientific" | "percentage";
   currency?: string;
@@ -32,7 +34,7 @@ export const formatNumber = (number: number, options?: NumberFormatOptions) => {
     prefix,
     suffix,
     compact,
-  } = { ...DEFAULT_OPTIONS, ...options };
+  } = handleSmallNumberFormat(number, { ...DEFAULT_OPTIONS, ...options });
 
   function createFormat(compact?: boolean) {
     if (compact) {
@@ -43,6 +45,7 @@ export const formatNumber = (number: number, options?: NumberFormatOptions) => {
         currency: currency,
         currencyDisplay: currency_style,
         useGrouping: true,
+        maximumFractionDigits: decimals != null ? decimals : 2,
       });
     }
 
@@ -67,5 +70,26 @@ export const formatNumber = (number: number, options?: NumberFormatOptions) => {
   return `${prefix}${formattedNumber}${suffix}`;
 };
 
+// Simple hack to handle small decimal numbers (0-1)
+function handleSmallNumberFormat<T>(value: number, options: T): T {
+  const hasAtLeastThreeDecimalPoints = Math.abs(value) < 0.01;
+  if (hasAtLeastThreeDecimalPoints && Math.abs(value) > 0) {
+    options = maybeMerge(options, {
+      compact: true,
+      decimals: 4,
+    });
+  }
+
+  return options;
+}
+
+const maybeMerge = <T, S1>(collection: T, object: S1) => {
+  if (collection == null) {
+    return collection;
+  }
+
+  return merge(collection, object);
+};
+
 export const formatPercent = (percent: number) =>
   `${(100 * percent).toFixed(2)} %`;
diff --git a/frontend/src/metabase/static-viz/lib/numbers.unit.spec.js b/frontend/src/metabase/static-viz/lib/numbers.unit.spec.js
index 14723e0b845d0763edc311442c90b76008557282..1b23ab78a9fcadd3c931add54bcec848f15f98be 100644
--- a/frontend/src/metabase/static-viz/lib/numbers.unit.spec.js
+++ b/frontend/src/metabase/static-viz/lib/numbers.unit.spec.js
@@ -99,6 +99,13 @@ describe("formatNumber", () => {
 
     expect(text).toEqual("10000.11");
   });
+
+  it("should format small number", () => {
+    expect(formatNumber(0.00196)).toEqual("0.002");
+    expect(formatNumber(0.00201)).toEqual("0.002");
+    expect(formatNumber(-0.00119)).toEqual("-0.0012");
+    expect(formatNumber(-0.00191)).toEqual("-0.0019");
+  });
 });
 
 describe("formatPercent", () => {