diff --git a/app/assets/javascripts/analytics/usage_trends/components/usage_trends_count_chart.vue b/app/assets/javascripts/analytics/usage_trends/components/usage_trends_count_chart.vue
index 247c147609b6c28a03567c0df072766b6d81af6c..cebc48f4ba754ddad16d20e4482416303bf16ab3 100644
--- a/app/assets/javascripts/analytics/usage_trends/components/usage_trends_count_chart.vue
+++ b/app/assets/javascripts/analytics/usage_trends/components/usage_trends_count_chart.vue
@@ -53,6 +53,9 @@ export default {
     return {
       errors: { ...generateDataKeys(this.queries, '') },
       ...generateDataKeys(this.queries, []),
+      loadingStates: {
+        ...generateDataKeys(this.queries, true),
+      },
     };
   },
   computed: {
@@ -60,7 +63,7 @@ export default {
       return Object.values(this.errors);
     },
     isLoading() {
-      return some(this.$apollo.queries, (query) => query?.loading);
+      return Object.values(this.loadingStates).some(Boolean);
     },
     allQueriesFailed() {
       return every(this.errorMessages, (message) => message.length);
@@ -115,8 +118,13 @@ export default {
   },
   created() {
     this.queries.forEach(({ query, identifier, loadError }) => {
+      this.loadingStates[identifier] = true;
+
       this.$apollo.addSmartQuery(identifier, {
         query,
+        context: {
+          batchKey: 'UsageTrendsCountChart',
+        },
         variables() {
           return {
             identifier,
@@ -140,6 +148,8 @@ export default {
               pageInfo,
               identifier,
             });
+          } else {
+            this.loadingStates[identifier] = false;
           }
         },
         error(error) {
@@ -159,7 +169,7 @@ export default {
         : 0;
     },
     handleError({ identifier, error, message }) {
-      this.loadingError = true;
+      this.loadingStates[identifier] = false;
       this.errors = { ...this.errors, [identifier]: message };
       Sentry.captureException(error);
     },
@@ -187,12 +197,24 @@ export default {
 <template>
   <div>
     <h3>{{ chartTitle }}</h3>
-    <gl-alert v-if="hasLoadingErrors" variant="danger" :dismissible="false" class="gl-mt-3">
+    <chart-skeleton-loader v-if="isLoading" />
+    <gl-alert
+      v-else-if="hasLoadingErrors"
+      data-testid="usage-trends-count-error-alert"
+      variant="danger"
+      :dismissible="false"
+      class="gl-mt-3"
+    >
       {{ errorMessage }}
     </gl-alert>
-    <div v-if="!allQueriesFailed">
-      <chart-skeleton-loader v-if="isLoading" />
-      <gl-alert v-else-if="hasEmptyDataSet" variant="info" :dismissible="false" class="gl-mt-3">
+    <div v-else>
+      <gl-alert
+        v-if="hasEmptyDataSet"
+        data-testid="usage-trends-count-info-alert"
+        variant="info"
+        :dismissible="false"
+        class="gl-mt-3"
+      >
         {{ noDataMessage }}
       </gl-alert>
       <gl-line-chart
diff --git a/spec/frontend/analytics/usage_trends/components/__snapshots__/usage_trends_count_chart_spec.js.snap b/spec/frontend/analytics/usage_trends/components/__snapshots__/usage_trends_count_chart_spec.js.snap
index dd3bc5d2a4f7fe4279a44772cef948c54fcc60cc..ca8ac2b54b61d8531cdf87646b9e6963ede3fba4 100644
--- a/spec/frontend/analytics/usage_trends/components/__snapshots__/usage_trends_count_chart_spec.js.snap
+++ b/spec/frontend/analytics/usage_trends/components/__snapshots__/usage_trends_count_chart_spec.js.snap
@@ -1,6 +1,6 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`UsageTrendsCountChart when fetching more data when the fetchMore query returns data passes the data to the line chart 1`] = `
+exports[`UsageTrendsCountChart with data passes the data to the line chart 1`] = `
 [
   {
     "data": [
@@ -12,17 +12,26 @@ exports[`UsageTrendsCountChart when fetching more data when the fetchMore query
         "2020-06-01",
         22,
       ],
+    ],
+    "name": "Mock Query 1",
+  },
+  {
+    "data": [
       [
-        "2020-08-01",
-        5,
+        "2020-07-01",
+        10,
+      ],
+      [
+        "2020-06-01",
+        21,
       ],
     ],
-    "name": "Mock Query",
+    "name": "Mock Query 2",
   },
 ]
 `;
 
-exports[`UsageTrendsCountChart with data passes the data to the line chart 1`] = `
+exports[`UsageTrendsCountChart with multiple pages of data fetched more data passes the data to the line chart 1`] = `
 [
   {
     "data": [
@@ -34,8 +43,29 @@ exports[`UsageTrendsCountChart with data passes the data to the line chart 1`] =
         "2020-06-01",
         22,
       ],
+      [
+        "2020-08-01",
+        5,
+      ],
+    ],
+    "name": "Mock Query 1",
+  },
+  {
+    "data": [
+      [
+        "2020-07-01",
+        10,
+      ],
+      [
+        "2020-06-01",
+        21,
+      ],
+      [
+        "2020-08-01",
+        10,
+      ],
     ],
-    "name": "Mock Query",
+    "name": "Mock Query 2",
   },
 ]
 `;
diff --git a/spec/frontend/analytics/usage_trends/components/usage_trends_count_chart_spec.js b/spec/frontend/analytics/usage_trends/components/usage_trends_count_chart_spec.js
index 322d05e663a30f8e1711108c0b84a708da4a6a79..c8f2df4dc3bbcb30ee95d91066c5c382ddd25d14 100644
--- a/spec/frontend/analytics/usage_trends/components/usage_trends_count_chart_spec.js
+++ b/spec/frontend/analytics/usage_trends/components/usage_trends_count_chart_spec.js
@@ -1,29 +1,38 @@
 import { GlAlert } from '@gitlab/ui';
 import { GlLineChart } from '@gitlab/ui/dist/charts';
-import { shallowMount } from '@vue/test-utils';
-import Vue, { nextTick } from 'vue';
+import Vue from 'vue';
 import VueApollo from 'vue-apollo';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
 import createMockApollo from 'helpers/mock_apollo_helper';
 import waitForPromises from 'helpers/wait_for_promises';
 import UsageTrendsCountChart from '~/analytics/usage_trends/components/usage_trends_count_chart.vue';
 import statsQuery from '~/analytics/usage_trends/graphql/queries/usage_count.query.graphql';
 import ChartSkeletonLoader from '~/vue_shared/components/resizable_chart/skeleton_loader.vue';
 import { mockQueryResponse, mockApolloResponse } from '../apollo_mock_data';
-import { mockCountsData1 } from '../mock_data';
+import { mockCountsData1, mockCountsData2 } from '../mock_data';
 
 Vue.use(VueApollo);
 
 const loadChartErrorMessage = 'My load error message';
 const noDataMessage = 'My no data message';
 
+const mockError = new Error('Something went wrong');
+
 const queryResponseDataKey = 'usageTrendsMeasurements';
-const identifier = 'MOCK_QUERY';
-const mockQueryConfig = {
-  identifier,
-  title: 'Mock Query',
-  query: statsQuery,
-  loadError: 'Failed to load mock query data',
-};
+const mockQueries = [
+  {
+    identifier: 'MOCK_QUERY_1',
+    title: 'Mock Query 1',
+    query: statsQuery,
+    loadError: 'Failed to load mock query 1 data',
+  },
+  {
+    identifier: 'MOCK_QUERY_2',
+    title: 'Mock Query 2',
+    query: statsQuery,
+    loadError: 'Failed to load mock query 2 data',
+  },
+];
 
 const mockChartConfig = {
   loadChartErrorMessage,
@@ -31,83 +40,151 @@ const mockChartConfig = {
   chartTitle: 'Foo',
   yAxisTitle: 'Bar',
   xAxisTitle: 'Baz',
-  queries: [mockQueryConfig],
+  queries: mockQueries,
 };
 
 describe('UsageTrendsCountChart', () => {
   let wrapper;
   let queryHandler;
 
-  const createComponent = ({ responseHandler }) => {
-    return shallowMount(UsageTrendsCountChart, {
+  const createWrapper = async ({ responseHandler }) => {
+    wrapper = shallowMountExtended(UsageTrendsCountChart, {
       apolloProvider: createMockApollo([[statsQuery, responseHandler]]),
       propsData: { ...mockChartConfig },
     });
+
+    await waitForPromises();
   };
 
   const findLoader = () => wrapper.findComponent(ChartSkeletonLoader);
   const findChart = () => wrapper.findComponent(GlLineChart);
-  const findAlert = () => wrapper.findComponent(GlAlert);
+  const findAllAlerts = () => wrapper.findAllComponents(GlAlert);
+  const findErrorsAlert = () => wrapper.findByTestId('usage-trends-count-error-alert');
+  const findInfoAlert = () => wrapper.findByTestId('usage-trends-count-info-alert');
 
   describe('while loading', () => {
     beforeEach(() => {
       queryHandler = mockQueryResponse({ key: queryResponseDataKey, loading: true });
-      wrapper = createComponent({ responseHandler: queryHandler });
+      createWrapper({ responseHandler: queryHandler });
     });
 
     it('requests data', () => {
-      expect(queryHandler).toHaveBeenCalledTimes(1);
+      expect(queryHandler).toHaveBeenCalledTimes(2);
+
+      mockQueries.forEach(({ identifier }, idx) => {
+        expect(queryHandler).toHaveBeenNthCalledWith(idx + 1, {
+          identifier,
+          first: 365,
+          after: null,
+        });
+      });
     });
 
     it('displays the skeleton loader', () => {
       expect(findLoader().exists()).toBe(true);
     });
 
-    it('hides the chart', () => {
+    it('does not display chart', () => {
       expect(findChart().exists()).toBe(false);
     });
 
-    it('does not show an error', () => {
-      expect(findAlert().exists()).toBe(false);
+    it('does not display any alerts', () => {
+      expect(findAllAlerts()).toHaveLength(0);
+    });
+  });
+
+  describe('with errors', () => {
+    describe('all queries failed', () => {
+      beforeEach(() => {
+        return createWrapper({ responseHandler: jest.fn().mockRejectedValue(mockError) });
+      });
+
+      it('displays alert with generic error message', () => {
+        expect(findAllAlerts()).toHaveLength(1);
+        expect(findErrorsAlert().text()).toBe(loadChartErrorMessage);
+      });
+
+      it('does not display the skeleton loader', () => {
+        expect(findLoader().exists()).toBe(false);
+      });
+
+      it('does not display the chart', () => {
+        expect(findChart().exists()).toBe(false);
+      });
+    });
+
+    describe('a single query failed', () => {
+      beforeEach(() => {
+        queryHandler = jest
+          .fn()
+          .mockResolvedValueOnce(
+            mockApolloResponse({
+              key: queryResponseDataKey,
+              data: mockCountsData1,
+            }),
+          )
+          .mockRejectedValueOnce(mockError);
+
+        return createWrapper({
+          responseHandler: queryHandler,
+        });
+      });
+
+      it('displays alert with correct error message', () => {
+        expect(findAllAlerts()).toHaveLength(1);
+        expect(findErrorsAlert().text()).toBe('Failed to load mock query 2 data');
+      });
+
+      it('does not display the skeleton loader', () => {
+        expect(findLoader().exists()).toBe(false);
+      });
+
+      it('does not display the chart', () => {
+        expect(findChart().exists()).toBe(false);
+      });
     });
   });
 
   describe('without data', () => {
-    beforeEach(async () => {
+    beforeEach(() => {
       queryHandler = mockQueryResponse({ key: queryResponseDataKey, data: [] });
-      wrapper = createComponent({ responseHandler: queryHandler });
-      await waitForPromises();
+      return createWrapper({ responseHandler: queryHandler });
     });
 
-    it('renders an no data message', () => {
-      expect(findAlert().text()).toBe(noDataMessage);
+    it('displays info alert with no data message', () => {
+      expect(findAllAlerts()).toHaveLength(1);
+      expect(findInfoAlert().text()).toBe(noDataMessage);
     });
 
-    it('hides the skeleton loader', () => {
+    it('does not display the skeleton loader', () => {
       expect(findLoader().exists()).toBe(false);
     });
 
-    it('renders the chart', () => {
+    it('does not display the chart', () => {
       expect(findChart().exists()).toBe(false);
     });
   });
 
   describe('with data', () => {
-    beforeEach(async () => {
-      queryHandler = mockQueryResponse({ key: queryResponseDataKey, data: mockCountsData1 });
-      wrapper = createComponent({ responseHandler: queryHandler });
-      await waitForPromises();
-    });
-
-    it('requests data', () => {
-      expect(queryHandler).toHaveBeenCalledTimes(1);
-    });
-
-    it('hides the skeleton loader', () => {
-      expect(findLoader().exists()).toBe(false);
+    beforeEach(() => {
+      queryHandler = jest
+        .fn()
+        .mockResolvedValueOnce(
+          mockApolloResponse({
+            key: queryResponseDataKey,
+            data: mockCountsData1,
+          }),
+        )
+        .mockResolvedValueOnce(
+          mockApolloResponse({
+            key: queryResponseDataKey,
+            data: mockCountsData2,
+          }),
+        );
+      return createWrapper({ responseHandler: queryHandler });
     });
 
-    it('renders the chart', () => {
+    it('displays the chart', () => {
       expect(findChart().exists()).toBe(true);
     });
 
@@ -115,59 +192,173 @@ describe('UsageTrendsCountChart', () => {
       expect(findChart().props('data')).toMatchSnapshot();
     });
 
-    it('does not show an error', () => {
-      expect(findAlert().exists()).toBe(false);
+    it('does not display the skeleton loader', () => {
+      expect(findLoader().exists()).toBe(false);
+    });
+
+    it('does not display any alerts', () => {
+      expect(findAllAlerts()).toHaveLength(0);
     });
   });
 
-  describe('when fetching more data', () => {
-    const recordedAt = '2020-08-01';
-    describe('when the fetchMore query returns data', () => {
-      beforeEach(async () => {
-        const newData = [{ __typename: 'UsageTrendsMeasurement', recordedAt, count: 5 }];
-        queryHandler = mockQueryResponse({
-          key: queryResponseDataKey,
-          data: mockCountsData1,
-          additionalData: newData,
-        });
+  describe('with multiple pages of data', () => {
+    describe('while fetching more data', () => {
+      beforeEach(() => {
+        queryHandler = jest
+          .fn()
+          .mockResolvedValueOnce(
+            mockApolloResponse({
+              key: queryResponseDataKey,
+              data: mockCountsData1,
+              hasNextPage: false,
+            }),
+          )
+          .mockResolvedValueOnce(
+            mockApolloResponse({
+              key: queryResponseDataKey,
+              data: mockCountsData2,
+              hasNextPage: true,
+            }),
+          )
+          .mockReturnValue(new Promise(() => {}));
+
+        return createWrapper({ responseHandler: queryHandler });
+      });
+
+      it('displays the skeleton loader', () => {
+        expect(findLoader().exists()).toBe(true);
+      });
+
+      it('does not display the chart', () => {
+        expect(findChart().exists()).toBe(false);
+      });
+
+      it('does not display any alerts', () => {
+        expect(findAllAlerts()).toHaveLength(0);
+      });
+    });
+
+    describe('fetched more data', () => {
+      beforeEach(() => {
+        queryHandler = jest
+          .fn()
+          .mockResolvedValueOnce(
+            mockApolloResponse({
+              key: queryResponseDataKey,
+              data: mockCountsData1,
+              hasNextPage: true,
+            }),
+          )
+          .mockResolvedValueOnce(
+            mockApolloResponse({
+              key: queryResponseDataKey,
+              data: mockCountsData2,
+              hasNextPage: true,
+            }),
+          )
+          .mockResolvedValueOnce(
+            mockApolloResponse({
+              key: queryResponseDataKey,
+              data: [{ __typename: 'UsageTrendsMeasurement', recordedAt: '2020-08-01', count: 5 }],
+              hasNextPage: false,
+            }),
+          )
+          .mockResolvedValueOnce(
+            mockApolloResponse({
+              key: queryResponseDataKey,
+              data: [{ __typename: 'UsageTrendsMeasurement', recordedAt: '2020-08-05', count: 10 }],
+              hasNextPage: false,
+            }),
+          );
 
-        wrapper = createComponent({ responseHandler: queryHandler });
-        await waitForPromises();
+        return createWrapper({ responseHandler: queryHandler });
       });
 
-      it('requests data twice', () => {
-        expect(queryHandler).toHaveBeenCalledTimes(2);
+      it('requests data twice for each query', () => {
+        expect(queryHandler).toHaveBeenCalledTimes(4);
       });
 
       it('passes the data to the line chart', () => {
         expect(findChart().props('data')).toMatchSnapshot();
       });
+
+      it('does not display the skeleton loader', () => {
+        expect(findLoader().exists()).toBe(false);
+      });
+
+      it('does not display any alerts', () => {
+        expect(findAllAlerts()).toHaveLength(0);
+      });
     });
 
-    describe('when the fetchMore query throws an error', () => {
-      beforeEach(async () => {
-        queryHandler = jest.fn().mockResolvedValueOnce(
-          mockApolloResponse({
-            key: queryResponseDataKey,
-            data: mockCountsData1,
-            hasNextPage: true,
-          }),
-        );
+    describe('has errors', () => {
+      describe('fetching more data for all queries fails', () => {
+        beforeEach(() => {
+          queryHandler = jest
+            .fn()
+            .mockResolvedValue(
+              mockApolloResponse({
+                key: queryResponseDataKey,
+                data: mockCountsData1,
+                hasNextPage: true,
+              }),
+            )
+            .mockRejectedValue(mockError);
 
-        wrapper = createComponent({ responseHandler: queryHandler });
-        jest
-          .spyOn(wrapper.vm.$apollo.queries[identifier], 'fetchMore')
-          .mockImplementation(jest.fn().mockRejectedValue());
+          return createWrapper({ responseHandler: queryHandler });
+        });
 
-        await nextTick();
-      });
+        it('displays alert with generic error message', () => {
+          expect(findAllAlerts()).toHaveLength(1);
+          expect(findErrorsAlert().text()).toBe(loadChartErrorMessage);
+        });
+
+        it('does not display the skeleton loader', () => {
+          expect(findLoader().exists()).toBe(false);
+        });
 
-      it('calls fetchMore', () => {
-        expect(wrapper.vm.$apollo.queries[identifier].fetchMore).toHaveBeenCalledTimes(1);
+        it('does not display the chart', () => {
+          expect(findChart().exists()).toBe(false);
+        });
       });
 
-      it('show an error message', () => {
-        expect(findAlert().text()).toBe(loadChartErrorMessage);
+      describe('fetching more data for a single query fails', () => {
+        beforeEach(() => {
+          queryHandler = jest
+            .fn()
+            .mockResolvedValue(
+              mockApolloResponse({
+                key: queryResponseDataKey,
+                data: mockCountsData1,
+                hasNextPage: true,
+              }),
+            )
+            .mockResolvedValueOnce(
+              mockApolloResponse({
+                key: queryResponseDataKey,
+                data: [
+                  { __typename: 'UsageTrendsMeasurement', recordedAt: '2020-08-01', count: 5 },
+                ],
+                hasNextPage: false,
+              }),
+            )
+            .mockRejectedValueOnce(mockError);
+
+          return createWrapper({ responseHandler: queryHandler });
+        });
+
+        it('displays alert with correct error message', () => {
+          expect(findAllAlerts()).toHaveLength(1);
+          expect(findErrorsAlert().text()).toBe('Failed to load mock query 2 data');
+        });
+
+        it('does not display the skeleton loader', () => {
+          expect(findLoader().exists()).toBe(false);
+        });
+
+        it('does not display the chart', () => {
+          expect(findChart().exists()).toBe(false);
+        });
       });
     });
   });